From fb4f34e895875c08530ef81c5d3afd4546e6b65b Mon Sep 17 00:00:00 2001 From: ismail Date: Fri, 22 Aug 2025 12:42:53 +0300 Subject: [PATCH] Add and execute unit tests for run limit feature --- test_apps/main/test_app_main.c | 10 ++- test_apps/main/test_relay_chn_core_multi.c | 98 ++++++++++++++++++++- test_apps/main/test_relay_chn_core_single.c | 78 +++++++++++++++- test_apps/main/test_relay_chn_nvs_multi.c | 17 ++++ test_apps/main/test_relay_chn_nvs_single.c | 16 ++++ test_apps/sdkconfig | 22 +++-- 6 files changed, 232 insertions(+), 9 deletions(-) diff --git a/test_apps/main/test_app_main.c b/test_apps/main/test_app_main.c index edabae1..460659c 100644 --- a/test_apps/main/test_app_main.c +++ b/test_apps/main/test_app_main.c @@ -28,6 +28,7 @@ void tearDown() reset_channels_to_idle_state(); } +#if CONFIG_RELAY_CHN_ENABLE_NVS == 1 static void test_nvs_flash_init(void) { esp_err_t ret; @@ -52,9 +53,11 @@ static void test_nvs_flash_init(void) } } #endif - TEST_ESP_OK(ret); +TEST_ESP_OK(ret); } +#endif +#if CONFIG_RELAY_CHN_ENABLE_NVS == 1 static void test_nvs_flash_deinit(void) { esp_err_t ret; @@ -65,11 +68,14 @@ static void test_nvs_flash_deinit(void) #endif TEST_ESP_OK(ret); } +#endif void app_main(void) { +#if CONFIG_RELAY_CHN_ENABLE_NVS == 1 // Init NVS once for all tests test_nvs_flash_init(); +#endif // Create relay_chn once for all tests TEST_ESP_OK(relay_chn_create(gpio_map, gpio_count)); @@ -92,8 +98,10 @@ void app_main(void) // Destroy relay_chn relay_chn_destroy(); +#if CONFIG_RELAY_CHN_ENABLE_NVS == 1 // Deinit NVS test_nvs_flash_deinit(); +#endif ESP_LOGI(TEST_TAG, "All tests complete."); diff --git a/test_apps/main/test_relay_chn_core_multi.c b/test_apps/main/test_relay_chn_core_multi.c index 8b35c5c..b7904dd 100644 --- a/test_apps/main/test_relay_chn_core_multi.c +++ b/test_apps/main/test_relay_chn_core_multi.c @@ -344,4 +344,100 @@ 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)); -} \ No newline at end of file +} + +#if CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT == 1 +#define TEST_RUN_LIMIT_SEC 5 +#define TEST_SHORT_RUN_LIMIT_SEC 2 +// ### Run Limit Tests +TEST_CASE("Test run limit initialization", "[relay_chn][run_limit]") +{ + for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) { + // Should initialize with default value + TEST_ASSERT_EQUAL(CONFIG_RELAY_CHN_RUN_LIMIT_DEFAULT_SEC, relay_chn_get_run_limit(i)); + } +} + +TEST_CASE("Test run limit setting boundaries", "[relay_chn][run_limit]") +{ + for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) { + // Test minimum boundary + relay_chn_set_run_limit(i, CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC - 1); + TEST_ASSERT_EQUAL(CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC, relay_chn_get_run_limit(i)); + + // Test maximum boundary + relay_chn_set_run_limit(i, CONFIG_RELAY_CHN_RUN_LIMIT_MAX_SEC + 1); + TEST_ASSERT_EQUAL(CONFIG_RELAY_CHN_RUN_LIMIT_MAX_SEC, relay_chn_get_run_limit(i)); + + // Test valid value + relay_chn_set_run_limit(i, TEST_RUN_LIMIT_SEC); + TEST_ASSERT_EQUAL(TEST_RUN_LIMIT_SEC, relay_chn_get_run_limit(i)); + } +} + +TEST_CASE("Test run limit stops channel after timeout", "[relay_chn][run_limit]") +{ + for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) { + // Set a short run limit for testing + relay_chn_set_run_limit(i, TEST_SHORT_RUN_LIMIT_SEC); + } + + relay_chn_run_forward(RELAY_CHN_ID_ALL); + + for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) { + // Check running forward + TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state(i)); + } + + // Wait for run limit timeout + vTaskDelay(pdMS_TO_TICKS(TEST_SHORT_RUN_LIMIT_SEC * 1000 + test_delay_margin_ms)); + for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) { + TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state(i)); + } +} + +TEST_CASE("Test run limit reset on direction change and time out finally", "[relay_chn][run_limit]") +{ + for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) { + // Set a short run limit + relay_chn_set_run_limit(i, TEST_SHORT_RUN_LIMIT_SEC); + + // Start running forward + relay_chn_run_forward(i); + } + + vTaskDelay(1000 / portTICK_PERIOD_MS); // Wait 1 second + + // Change direction before timeout + relay_chn_run_reverse(RELAY_CHN_ID_ALL); + + // Wait for the inertia period (after which the reverse command will be dispatched) + vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms)); + + for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) { + TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state(i)); + } + + // Timer should time out and stop the channel after the run limit time + vTaskDelay(pdMS_TO_TICKS(TEST_SHORT_RUN_LIMIT_SEC * 1000 + test_delay_margin_ms)); + + for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) { + TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state(i)); + } +} + +TEST_CASE("Test run limit persistence across stop/start", "[relay_chn][run_limit]") +{ + for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) { + // Set initial run limit + relay_chn_set_run_limit(i, TEST_RUN_LIMIT_SEC); + + // Stop and start channel + relay_chn_stop(i); + relay_chn_run_forward(i); + + // Run limit should persist + TEST_ASSERT_EQUAL(TEST_RUN_LIMIT_SEC, relay_chn_get_run_limit(i)); + } +} +#endif // CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT == 1 \ No newline at end of file diff --git a/test_apps/main/test_relay_chn_core_single.c b/test_apps/main/test_relay_chn_core_single.c index 3c3f4a8..b21823f 100644 --- a/test_apps/main/test_relay_chn_core_single.c +++ b/test_apps/main/test_relay_chn_core_single.c @@ -171,4 +171,80 @@ TEST_CASE("Flipping a running channel stops it and flips direction", "[relay_chn vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms)); TEST_ASSERT_EQUAL(RELAY_CHN_STATE_IDLE, relay_chn_get_state()); TEST_ASSERT_EQUAL(RELAY_CHN_DIRECTION_FLIPPED, relay_chn_get_direction()); -} \ No newline at end of file +} + +#if CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT == 1 +#define TEST_RUN_LIMIT_SEC 5 +#define TEST_SHORT_RUN_LIMIT_SEC 2 +// ### Run Limit Tests +TEST_CASE("Test run limit initialization", "[relay_chn][run_limit]") +{ + // Should initialize with default value + TEST_ASSERT_EQUAL(CONFIG_RELAY_CHN_RUN_LIMIT_DEFAULT_SEC, relay_chn_get_run_limit()); +} + +TEST_CASE("Test run limit setting boundaries", "[relay_chn][run_limit]") +{ + // Test minimum boundary + relay_chn_set_run_limit(CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC - 1); + TEST_ASSERT_EQUAL(CONFIG_RELAY_CHN_RUN_LIMIT_MIN_SEC, relay_chn_get_run_limit()); + + // Test maximum boundary + relay_chn_set_run_limit(CONFIG_RELAY_CHN_RUN_LIMIT_MAX_SEC + 1); + TEST_ASSERT_EQUAL(CONFIG_RELAY_CHN_RUN_LIMIT_MAX_SEC, relay_chn_get_run_limit()); + + // Test valid value + relay_chn_set_run_limit(TEST_RUN_LIMIT_SEC); + TEST_ASSERT_EQUAL(TEST_RUN_LIMIT_SEC, relay_chn_get_run_limit()); +} + +TEST_CASE("Test run limit stops channel after timeout", "[relay_chn][run_limit]") +{ + // Set a short run limit for testing + relay_chn_set_run_limit(TEST_SHORT_RUN_LIMIT_SEC); + + // Start running forward + relay_chn_run_forward(); + TEST_ASSERT_EQUAL(RELAY_CHN_STATE_FORWARD, relay_chn_get_state()); + + // Wait for run limit timeout + vTaskDelay(pdMS_TO_TICKS(TEST_SHORT_RUN_LIMIT_SEC * 1000 + test_delay_margin_ms)); + TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state()); +} + +TEST_CASE("Test run limit reset on direction change and time out finally", "[relay_chn][run_limit]") +{ + // Set a short run limit + relay_chn_set_run_limit(TEST_SHORT_RUN_LIMIT_SEC); + + // Start running forward + relay_chn_run_forward(); + vTaskDelay(1000 / portTICK_PERIOD_MS); // Wait 1 second + + // Change direction before timeout + relay_chn_run_reverse(); + + // Wait for the inertia period (after which the reverse command will be dispatched) + vTaskDelay(pdMS_TO_TICKS(opposite_inertia_ms + test_delay_margin_ms)); + + TEST_ASSERT_EQUAL(RELAY_CHN_STATE_REVERSE, relay_chn_get_state()); + + // Timer should time out and stop the channel after the run limit time + vTaskDelay(pdMS_TO_TICKS(TEST_SHORT_RUN_LIMIT_SEC * 1000 + test_delay_margin_ms)); + + TEST_ASSERT_EQUAL(RELAY_CHN_STATE_STOPPED, relay_chn_get_state()); +} + +TEST_CASE("Test run limit persistence across stop/start", "[relay_chn][run_limit]") +{ + // Set initial run limit + relay_chn_set_run_limit(TEST_RUN_LIMIT_SEC); + + // Stop and start channel + relay_chn_stop(); + relay_chn_run_forward(); + + // Run limit should persist + TEST_ASSERT_EQUAL(TEST_RUN_LIMIT_SEC, relay_chn_get_run_limit()); +} +#endif // CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT == 1 \ No newline at end of file diff --git a/test_apps/main/test_relay_chn_nvs_multi.c b/test_apps/main/test_relay_chn_nvs_multi.c index b21b3d5..d591dbb 100644 --- a/test_apps/main/test_relay_chn_nvs_multi.c +++ b/test_apps/main/test_relay_chn_nvs_multi.c @@ -84,6 +84,23 @@ TEST_CASE("Test relay_chn_nvs_erase_all", "[relay_chn][nvs]") TEST_ESP_OK(relay_chn_nvs_deinit()); } +#ifdef CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT +TEST_CASE("Test run limit setting and getting", "[relay_chn][nvs][run_limit]") +{ + TEST_ESP_OK(relay_chn_nvs_init()); + + const uint16_t run_limit_sec = 32; + for (uint8_t i = 0; i < CONFIG_RELAY_CHN_COUNT; i++) { + TEST_ESP_OK(relay_chn_nvs_set_run_limit(i, run_limit_sec)); + + uint16_t run_limit_read; + TEST_ESP_OK(relay_chn_nvs_get_run_limit(i, &run_limit_read)); + TEST_ASSERT_EQUAL(run_limit_sec, run_limit_read); + } + TEST_ESP_OK(relay_chn_nvs_deinit()); +} +#endif + #ifdef RELAY_CHN_ENABLE_TILTING TEST_CASE("Test sensitivity setting and getting", "[relay_chn][nvs][tilt]") { diff --git a/test_apps/main/test_relay_chn_nvs_single.c b/test_apps/main/test_relay_chn_nvs_single.c index b6fb376..2872d5c 100644 --- a/test_apps/main/test_relay_chn_nvs_single.c +++ b/test_apps/main/test_relay_chn_nvs_single.c @@ -77,6 +77,22 @@ TEST_CASE("Test relay_chn_nvs_erase_all", "[relay_chn][nvs]") TEST_ESP_OK(relay_chn_nvs_deinit()); } +#ifdef CONFIG_RELAY_CHN_ENABLE_RUN_LIMIT +TEST_CASE("Test run limit setting and getting", "[relay_chn][nvs][run_limit]") +{ + TEST_ESP_OK(relay_chn_nvs_init()); + + const uint16_t run_limit_sec = 32; + TEST_ESP_OK(relay_chn_nvs_set_run_limit(0, run_limit_sec)); + + uint16_t run_limit_read; + TEST_ESP_OK(relay_chn_nvs_get_run_limit(0, &run_limit_read)); + TEST_ASSERT_EQUAL(run_limit_sec, run_limit_read); + + TEST_ESP_OK(relay_chn_nvs_deinit()); +} +#endif + #ifdef RELAY_CHN_ENABLE_TILTING TEST_CASE("Test sensitivity setting and getting", "[relay_chn][nvs][tilt]") { diff --git a/test_apps/sdkconfig b/test_apps/sdkconfig index f47128a..7810c58 100644 --- a/test_apps/sdkconfig +++ b/test_apps/sdkconfig @@ -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 @@ -1268,7 +1268,8 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y # Relay Channel Driver Configuration # CONFIG_RELAY_CHN_OPPOSITE_INERTIA_MS=200 -CONFIG_RELAY_CHN_COUNT=2 +CONFIG_RELAY_CHN_COUNT=8 +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 @@ -1277,8 +1278,17 @@ CONFIG_RELAY_CHN_ENABLE_NVS=y # Relay Channel NVS Storage Configuration # CONFIG_RELAY_CHN_NVS_NAMESPACE="relay_chn" -# CONFIG_RELAY_CHN_NVS_CUSTOM_PARTITION is not set +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