Fix GPIO tests to use meaningful assertions instead of tautologies

Co-authored-by: pmarchini <49943249+pmarchini@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-24 22:43:35 +00:00
parent 1786c41b15
commit 77a70fc0da
2 changed files with 63 additions and 64 deletions

View File

@@ -35,11 +35,11 @@ The tests are organized using the ESP-IDF Unity testing framework and cover the
- `test_multiple_dimmers_independent`: Verifies multiple dimmers operate independently - `test_multiple_dimmers_independent`: Verifies multiple dimmers operate independently
7. **GPIO and Timer ISR Tests** 7. **GPIO and Timer ISR Tests**
- `test_gpio_output_timing_high`: Verifies GPIO output pin timing after zero-crossing - `test_gpio_output_timing_high`: Verifies GPIO output pin goes HIGH after zero-crossing trigger (tests with power=99 for immediate response)
- `test_gpio_output_pulse_width`: Tests the pulse width timing on GPIO output - `test_gpio_output_pulse_width`: Tests the pulse completes and pin returns to LOW after full cycle
- `test_gpio_output_zero_crossing_response`: Validates dimmer response to zero-crossing interrupts - `test_gpio_output_zero_crossing_response`: Validates dimmer triggers output HIGH in response to zero-crossing events
- `test_multiple_dimmers_gpio_independence`: Tests that multiple dimmers control GPIO pins independently - `test_multiple_dimmers_gpio_independence`: Tests that ON dimmer triggers output while OFF dimmer remains LOW
- `test_timer_isr_respects_state_changes`: Verifies timer ISR respects dimmer state changes (ON/OFF) - `test_timer_isr_respects_state_changes`: Verifies timer ISR keeps pin LOW when OFF and triggers HIGH when ON
## Running the Tests ## Running the Tests

View File

@@ -269,29 +269,26 @@ void test_gpio_output_timing_high(void)
begin(dimmer, NORMAL_MODE, ON, 50); begin(dimmer, NORMAL_MODE, ON, 50);
// Set power to 50 (mid-range) // Set power to 99 (maximum power, earliest trigger, dimPulseBegin=1)
setPower(dimmer, 50); setPower(dimmer, 99);
vTaskDelay(pdMS_TO_TICKS(10)); vTaskDelay(pdMS_TO_TICKS(10));
// Trigger zero-crossing by toggling the ZC pin // Initial pin state should be LOW before zero-crossing
// This simulates the external zero-crossing detector int initial_state = gpio_get_level(TEST_TRIAC_GPIO);
TEST_ASSERT_EQUAL(0, initial_state);
// Trigger zero-crossing by creating a falling edge on ZC pin
gpio_set_level(TEST_ZC_GPIO, 1);
vTaskDelay(pdMS_TO_TICKS(1));
gpio_set_level(TEST_ZC_GPIO, 0); gpio_set_level(TEST_ZC_GPIO, 0);
// Wait briefly for the first timer tick
// With power=99, dimPulseBegin=1, pin should go HIGH almost immediately
vTaskDelay(pdMS_TO_TICKS(1)); vTaskDelay(pdMS_TO_TICKS(1));
// Wait for timer ISR to fire and set the output high // At this point, the pin should be HIGH (during the pulse)
// The timer runs at intervals based on AC frequency (50Hz = 10ms half-period) int pin_during_pulse = gpio_get_level(TEST_TRIAC_GPIO);
// Each timer tick is 1/100th of the half-period (~100us for 50Hz) TEST_ASSERT_EQUAL(1, pin_during_pulse);
// With power=50, dimPulseBegin=50, so pin should go high after ~5ms
vTaskDelay(pdMS_TO_TICKS(6));
// The pin should have been set HIGH at some point during the cycle
// Note: Due to the pulsed nature, we might catch it HIGH or LOW
// This test verifies the mechanism is working
int pin_level = gpio_get_level(TEST_TRIAC_GPIO);
// The pin should be either HIGH (during pulse) or LOW (after pulse)
// Both are valid depending on timing, but the system should be responsive
TEST_ASSERT_TRUE(pin_level == 0 || pin_level == 1);
} }
// Test: GPIO output pulse timing - verify pulse width // Test: GPIO output pulse timing - verify pulse width
@@ -302,24 +299,21 @@ void test_gpio_output_pulse_width(void)
begin(dimmer, NORMAL_MODE, ON, 50); begin(dimmer, NORMAL_MODE, ON, 50);
// Set power to 10 (low power, early in cycle) // Set power to 99 for fastest response
setPower(dimmer, 10); setPower(dimmer, 99);
vTaskDelay(pdMS_TO_TICKS(10)); vTaskDelay(pdMS_TO_TICKS(10));
// Trigger zero-crossing // Trigger zero-crossing
gpio_set_level(TEST_ZC_GPIO, 0); gpio_set_level(TEST_ZC_GPIO, 1);
vTaskDelay(pdMS_TO_TICKS(1)); vTaskDelay(pdMS_TO_TICKS(1));
gpio_set_level(TEST_ZC_GPIO, 0);
// Wait for pulse to happen // Wait for a full AC half-cycle to complete (~10ms for 50Hz)
// With power=10, dimPulseBegin should be high (~90 from powerBuf) vTaskDelay(pdMS_TO_TICKS(12));
// So pin should go high late in the cycle
vTaskDelay(pdMS_TO_TICKS(11));
// After the full cycle, pin should be LOW (pulse complete) // After the full cycle, pin should be back to LOW (pulse complete)
int pin_level = gpio_get_level(TEST_TRIAC_GPIO); int pin_level = gpio_get_level(TEST_TRIAC_GPIO);
TEST_ASSERT_EQUAL(0, pin_level);
// Verify the pin state is valid (0 or 1)
TEST_ASSERT_TRUE(pin_level == 0 || pin_level == 1);
} }
// Test: GPIO output with zero-crossing interrupt // Test: GPIO output with zero-crossing interrupt
@@ -336,6 +330,7 @@ void test_gpio_output_zero_crossing_response(void)
// Initial pin state should be LOW // Initial pin state should be LOW
int initial_state = gpio_get_level(TEST_TRIAC_GPIO); int initial_state = gpio_get_level(TEST_TRIAC_GPIO);
TEST_ASSERT_EQUAL(0, initial_state);
// Trigger zero-crossing by creating a falling edge on ZC pin // Trigger zero-crossing by creating a falling edge on ZC pin
gpio_set_level(TEST_ZC_GPIO, 1); gpio_set_level(TEST_ZC_GPIO, 1);
@@ -344,12 +339,11 @@ void test_gpio_output_zero_crossing_response(void)
// Wait for timer ISR cycles to process // Wait for timer ISR cycles to process
// With power=99, dimPulseBegin=1, so pin should go high very quickly // With power=99, dimPulseBegin=1, so pin should go high very quickly
vTaskDelay(pdMS_TO_TICKS(2)); vTaskDelay(pdMS_TO_TICKS(1));
// The dimmer should have responded to the zero-crossing // Pin should be HIGH during the pulse
// Verify system is operational by checking pin is still valid int state_during_pulse = gpio_get_level(TEST_TRIAC_GPIO);
int final_state = gpio_get_level(TEST_TRIAC_GPIO); TEST_ASSERT_EQUAL(1, state_during_pulse);
TEST_ASSERT_TRUE(final_state == 0 || final_state == 1);
} }
// Test: Multiple dimmers GPIO independence // Test: Multiple dimmers GPIO independence
@@ -362,30 +356,33 @@ void test_multiple_dimmers_gpio_independence(void)
TEST_ASSERT_NOT_NULL(dimmer2); TEST_ASSERT_NOT_NULL(dimmer2);
begin(dimmer1, NORMAL_MODE, ON, 50); begin(dimmer1, NORMAL_MODE, ON, 50);
begin(dimmer2, NORMAL_MODE, ON, 50); begin(dimmer2, NORMAL_MODE, OFF, 50); // dimmer2 is OFF
// Set different power levels // Set power for dimmer1
setPower(dimmer1, 25); setPower(dimmer1, 99);
setPower(dimmer2, 75);
vTaskDelay(pdMS_TO_TICKS(10)); vTaskDelay(pdMS_TO_TICKS(10));
// Initial states
int pin1_initial = gpio_get_level(TEST_TRIAC_GPIO);
int pin2_initial = gpio_get_level(TEST_TRIAC_GPIO_2);
TEST_ASSERT_EQUAL(0, pin1_initial);
TEST_ASSERT_EQUAL(0, pin2_initial);
// Trigger zero-crossing // Trigger zero-crossing
gpio_set_level(TEST_ZC_GPIO, 1);
vTaskDelay(pdMS_TO_TICKS(1));
gpio_set_level(TEST_ZC_GPIO, 0); gpio_set_level(TEST_ZC_GPIO, 0);
// Wait for dimmer1 to trigger
vTaskDelay(pdMS_TO_TICKS(1)); vTaskDelay(pdMS_TO_TICKS(1));
// Wait for timer cycles // Dimmer1 should be HIGH (ON and triggered)
vTaskDelay(pdMS_TO_TICKS(8)); // Dimmer2 should remain LOW (OFF state)
// Both GPIO pins should be independently controlled
int pin1_level = gpio_get_level(TEST_TRIAC_GPIO); int pin1_level = gpio_get_level(TEST_TRIAC_GPIO);
int pin2_level = gpio_get_level(TEST_TRIAC_GPIO_2); int pin2_level = gpio_get_level(TEST_TRIAC_GPIO_2);
// Verify both pins have valid states TEST_ASSERT_EQUAL(1, pin1_level); // dimmer1 is ON
TEST_ASSERT_TRUE(pin1_level == 0 || pin1_level == 1); TEST_ASSERT_EQUAL(0, pin2_level); // dimmer2 is OFF
TEST_ASSERT_TRUE(pin2_level == 0 || pin2_level == 1);
// Note: Pins might be in different states due to different power settings
// Both should be operational and independent
} }
// Test: Timer ISR execution with state changes // Test: Timer ISR execution with state changes
@@ -395,37 +392,39 @@ void test_timer_isr_respects_state_changes(void)
TEST_ASSERT_NOT_NULL(dimmer); TEST_ASSERT_NOT_NULL(dimmer);
begin(dimmer, NORMAL_MODE, ON, 50); begin(dimmer, NORMAL_MODE, ON, 50);
setPower(dimmer, 50); setPower(dimmer, 99);
vTaskDelay(pdMS_TO_TICKS(10)); vTaskDelay(pdMS_TO_TICKS(10));
// Turn dimmer OFF // Turn dimmer OFF
setState(dimmer, OFF); setState(dimmer, OFF);
// Trigger zero-crossing // Trigger zero-crossing
gpio_set_level(TEST_ZC_GPIO, 0); gpio_set_level(TEST_ZC_GPIO, 1);
vTaskDelay(pdMS_TO_TICKS(1)); vTaskDelay(pdMS_TO_TICKS(1));
gpio_set_level(TEST_ZC_GPIO, 0);
// Wait for timer cycles // Wait for timer cycles
vTaskDelay(pdMS_TO_TICKS(12)); vTaskDelay(pdMS_TO_TICKS(5));
// Pin should remain LOW when dimmer is OFF // Pin should remain LOW when dimmer is OFF
int pin_level = gpio_get_level(TEST_TRIAC_GPIO); int pin_level_off = gpio_get_level(TEST_TRIAC_GPIO);
TEST_ASSERT_EQUAL(0, pin_level_off);
// When OFF, the timer should not trigger the output
// However, due to race conditions, we just verify valid state
TEST_ASSERT_TRUE(pin_level == 0 || pin_level == 1);
// Turn back ON and verify it responds // Turn back ON and verify it responds
setState(dimmer, ON); setState(dimmer, ON);
vTaskDelay(pdMS_TO_TICKS(2)); vTaskDelay(pdMS_TO_TICKS(2));
// Trigger another zero-crossing // Trigger another zero-crossing
gpio_set_level(TEST_ZC_GPIO, 1);
vTaskDelay(pdMS_TO_TICKS(1));
gpio_set_level(TEST_ZC_GPIO, 0); gpio_set_level(TEST_ZC_GPIO, 0);
vTaskDelay(pdMS_TO_TICKS(8));
// Now the dimmer should be active // Wait briefly for pulse
vTaskDelay(pdMS_TO_TICKS(1));
// Now the dimmer should be active and pin HIGH
int pin_level_on = gpio_get_level(TEST_TRIAC_GPIO); int pin_level_on = gpio_get_level(TEST_TRIAC_GPIO);
TEST_ASSERT_TRUE(pin_level_on == 0 || pin_level_on == 1); TEST_ASSERT_EQUAL(1, pin_level_on);
} }
// Main test runner // Main test runner