2 Commits

Author SHA1 Message Date
a6d38327b7 Add test cases for *all and *all_with functions
Added test cases for the recently implemented `*all` and `*all_with`
functions. Closes #1089.
2025-08-28 09:34:19 +03:00
0cd6b4e263 Refactor and enhance reset_channels_to_idle_state
- Refactor reset_channels_to_idle_state to reset_channels_to_defaults
and enhance functionality with direction reset logic. This is because
some tilt test cases were failing due to modified run limit values in some
of the previous core test cases. See #1089-3.
- A relay channel listener has been added to diagnose channel
states during tests.

Refs #1089
2025-08-28 09:30:43 +03:00
6 changed files with 169 additions and 11 deletions

View File

@@ -25,7 +25,7 @@ void setUp()
void tearDown()
{
reset_channels_to_idle_state();
reset_channels_to_defaults();
}
#if CONFIG_RELAY_CHN_ENABLE_NVS

View File

@@ -32,17 +32,40 @@ const uint8_t gpio_map[] = {4, 5};
const uint8_t gpio_count = sizeof(gpio_map) / sizeof(gpio_map[0]);
void reset_channels_to_idle_state()
void reset_channels_to_defaults()
{
#if CONFIG_RELAY_CHN_COUNT > 1
relay_chn_stop_all();
#if CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT
relay_chn_set_run_limit_all_with(CONFIG_RELAY_CHN_RUN_LIMIT_DEFAULT_SEC);
#endif
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
for (int i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state(i));
// Reset directions
if (relay_chn_get_direction(i) != RELAY_CHN_DIRECTION_DEFAULT) {
relay_chn_flip_direction(i);
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_DEFAULT, relay_chn_get_direction(i));
}
}
#else
relay_chn_stop();
#if CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT
relay_chn_set_run_limit(CONFIG_RELAY_CHN_RUN_LIMIT_DEFAULT_SEC);
#endif
// Reset direction
if (relay_chn_get_direction() != RELAY_CHN_DIRECTION_DEFAULT) {
relay_chn_flip_direction();
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_DEFAULT, relay_chn_get_direction());
}
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state());
#endif
}
void test_state_listener(uint8_t id, relay_chn_state_t old_state, relay_chn_state_t new_state)
{
ESP_LOGI(TEST_TAG, "test_state_listener: id: %d, old_state: %d, new_state: %d", id, old_state, new_state);
}

View File

@@ -18,4 +18,7 @@ extern const uint8_t gpio_count;
#define TEST_DELAY_MARGIN_MS 50
// Reset channels to Idle state
void reset_channels_to_idle_state(void);
void reset_channels_to_defaults(void);
// Relay channel state listener for tests
void test_state_listener(uint8_t id, relay_chn_state_t old_state, relay_chn_state_t new_state);

View File

@@ -355,6 +355,65 @@ TEST_CASE("Direction flip handles invalid channel ID gracefully", "[relay_chn][c
relay_chn_flip_direction(invalid_ch); // Call with an invalid ID
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_DEFAULT, relay_chn_get_direction(invalid_ch));
}
TEST_CASE("get_state_all retrieves all channel states", "[relay_chn][core][batch]")
{
relay_chn_state_t states[CONFIG_RELAY_CHN_COUNT];
// 1. All should be IDLE initially
TEST_ESP_OK(relay_chn_get_state_all(states));
for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, states[i]);
}
// 2. Set some states
if (CONFIG_RELAY_CHN_COUNT >= 2) {
relay_chn_run_forward(0);
relay_chn_run_reverse(1);
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
} else {
relay_chn_run_forward(0);
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
}
// 3. Get all states and verify
TEST_ESP_OK(relay_chn_get_state_all(states));
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, states[0]);
if (CONFIG_RELAY_CHN_COUNT >= 2) {
TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, states[1]);
}
}
TEST_CASE("get_direction_all retrieves all channel directions", "[relay_chn][core][direction][batch]")
{
relay_chn_direction_t directions[CONFIG_RELAY_CHN_COUNT];
// 1. All should be default initially
TEST_ESP_OK(relay_chn_get_direction_all(directions));
for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_DEFAULT, directions[i]);
}
// 2. Flip all
relay_chn_flip_direction_all();
vTaskDelay(pdMS_TO_TICKS(CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS + TEST_DELAY_MARGIN_MS));
// 3. Get all directions and verify
TEST_ESP_OK(relay_chn_get_direction_all(directions));
for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_FLIPPED, directions[i]);
}
}
TEST_CASE("get_all functions handle NULL arguments", "[relay_chn][core][batch]")
{
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_get_state_all(NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_get_direction_all(NULL));
#if CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_get_run_limit_all(NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, relay_chn_set_run_limit_all(NULL));
#endif
}
#if CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT
#define TEST_RUN_LIMIT_SEC 5
@@ -463,6 +522,31 @@ TEST_CASE("Run limit functions handle invalid channel ID", "[relay_chn][run_limi
relay_chn_set_run_limit(invalid_ch, 999);
TEST_ASSERT_EQUAL(original_limit, relay_chn_get_run_limit(0));
}
TEST_CASE("Run limit _all functions work correctly", "[relay_chn][run_limit][batch]")
{
// 1. Test set_run_limit_all_with
relay_chn_set_run_limit_all_with(TEST_RUN_LIMIT_SEC);
for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
TEST_ASSERT_EQUAL(TEST_RUN_LIMIT_SEC, relay_chn_get_run_limit(i));
}
// 2. Test get_run_limit_all
uint16_t limits[CONFIG_RELAY_CHN_COUNT];
TEST_ESP_OK(relay_chn_get_run_limit_all(limits));
for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
TEST_ASSERT_EQUAL(TEST_RUN_LIMIT_SEC, limits[i]);
}
// 3. Test set_run_limit_all
for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
limits[i] = TEST_RUN_LIMIT_SEC + i;
}
TEST_ESP_OK(relay_chn_set_run_limit_all(limits));
for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) {
TEST_ASSERT_EQUAL(TEST_RUN_LIMIT_SEC + i, relay_chn_get_run_limit(i));
}
}
#endif // CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT
TEST_CASE("relay_chn_destroy allows clean-up and re-creation", "[relay_chn][core]")

View File

@@ -399,3 +399,35 @@ TEST_CASE("run command during TILT state transitions correctly", "[relay_chn][ti
// Should transition to REVERSE
check_all_channels_for_state(RELAY_CHN_STATE_REVERSE);
}
// Test run command during active tilt cycle (move/pause)
TEST_CASE("run_all command during active tilt cycle stops tilt", "[relay_chn][tilt][interrupt]")
{
// Set a known sensitivity for predictable timing.
// For sensitivity=50, move_time=30ms, pause_time=270ms.
relay_chn_tilt_set_sensitivity_all_with(50);
const uint32_t move_time_ms = 30;
// --- Test interrupting during MOVE step ---
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward_all();
vTaskDelay(pdMS_TO_TICKS(move_time_ms / 2)); // Wait for half of the move time
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// Interrupt with run_reverse_all while in the MOVE part of the cycle
relay_chn_run_reverse_all();
vTaskDelay(pdMS_TO_TICKS(TEST_DELAY_MARGIN_MS));
// Should stop tilting and go to REVERSE immediately (no inertia from TILT_FORWARD)
check_all_channels_for_state(RELAY_CHN_STATE_REVERSE);
// --- Test interrupting during PAUSE step ---
prepare_all_channels_for_tilt(RELAY_CHN_CMD_FORWARD);
relay_chn_tilt_forward_all();
vTaskDelay(pdMS_TO_TICKS(move_time_ms + TEST_DELAY_MARGIN_MS)); // Wait past MOVE, into PAUSE
check_all_channels_for_state(RELAY_CHN_STATE_TILT_FORWARD);
// Interrupt with run_forward_all while in the PAUSE part of the cycle
relay_chn_run_forward_all();
// Should stop tilting and go to FORWARD_PENDING (inertia from TILT_FORWARD)
check_all_channels_for_state(RELAY_CHN_STATE_FORWARD_PENDING);
}

View File

@@ -395,13 +395,13 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
#
# Partition Table
#
CONFIG_PARTITION_TABLE_SINGLE_APP=y
# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set
# CONFIG_PARTITION_TABLE_CUSTOM is not set
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions/part_nvs.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions/part_nvs.csv"
CONFIG_PARTITION_TABLE_OFFSET=0x8000
CONFIG_PARTITION_TABLE_MD5=y
# end of Partition Table
@@ -1260,11 +1260,27 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
# Relay Channel Driver Configuration
#
CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200
CONFIG_RELAY_CHN_COUNT=8
# CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT is not set
# CONFIG_RELAY_CHN_ENABLE_TILTING is not set
# CONFIG_RELAY_CHN_ENABLE_NVS is not set
CONFIG_RELAY_CHN_COUNT=1
CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT=y
CONFIG_RELAY_CHN_ENABLE_TILTING=y
CONFIG_RELAY_CHN_ENABLE_NVS=y
# end of Relay Channel Driver Configuration
#
# Relay Channel NVS Storage Configuration
#
CONFIG_RELAY_CHN_NVS_NAMESPACE="relay_chn"
CONFIG_RELAY_CHN_NVS_CUSTOM_PARTITION=y
CONFIG_RELAY_CHN_NVS_CUSTOM_PARTITION_NAME="app_data"
# end of Relay Channel NVS Storage Configuration
#
# Relay Channel Run Limit Configuration
#
CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC=1
CONFIG_RELAY_CHN_RUN_LIMIT_MAX_SEC=600
CONFIG_RELAY_CHN_RUN_LIMIT_DEFAULT_SEC=60
# end of Relay Channel Run Limit Configuration
# end of Component config
# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set