From 113d69f1882e24da40573f364d6f4342bf768046 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Thu, 23 Oct 2025 14:15:56 +0800 Subject: [PATCH] test(core): add WDT protection to detect stuck tests --- .../test_apps/main/test_event_main.c | 19 +++++++++- .../test_apps/newlib/main/test_app_main.c | 19 +++++++++- .../esp_timer/test_apps/main/test_app_main.c | 36 ++++++++++++++++++- .../esp_timer/test_apps/main/test_esp_timer.c | 4 +-- .../freertos/main/test_freertos_main.c | 20 ++++++++++- 5 files changed, 92 insertions(+), 6 deletions(-) diff --git a/components/esp_event/test_apps/main/test_event_main.c b/components/esp_event/test_apps/main/test_event_main.c index 293a363123..37515aa46f 100644 --- a/components/esp_event/test_apps/main/test_event_main.c +++ b/components/esp_event/test_apps/main/test_event_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include "unity_test_runner.h" #include "unity_test_utils_memory.h" #include "esp_log.h" +#include "esp_task_wdt.h" #ifdef CONFIG_HEAP_TRACING #include "memory_checks.h" #include "esp_heap_trace.h" @@ -25,6 +26,10 @@ void setUp(void) unity_utils_set_leak_level(0); unity_utils_record_free_mem(); + + esp_task_wdt_add(NULL); + esp_task_wdt_reset(); + } void tearDown(void) @@ -35,10 +40,22 @@ void tearDown(void) #endif unity_utils_evaluate_leaks(); + + esp_task_wdt_reset(); + esp_task_wdt_delete(NULL); } void app_main(void) { + // Configure the task watchdog timer to catch any tests that hang + esp_task_wdt_config_t config = { + .timeout_ms = 25 * 1000, // 25 seconds, smaller than the default pytest timeout + .idle_core_mask = 0, + .trigger_panic = true, + }; + + esp_task_wdt_init(&config); + ESP_LOGI(TAG, "Running esp-event test app"); // rand() seems to do a one-time allocation. Call it here so that the memory it allocates // is not counted as a leak. diff --git a/components/esp_libc/test_apps/newlib/main/test_app_main.c b/components/esp_libc/test_apps/newlib/main/test_app_main.c index a1a484df85..03494de3aa 100644 --- a/components/esp_libc/test_apps/newlib/main/test_app_main.c +++ b/components/esp_libc/test_apps/newlib/main/test_app_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -10,6 +10,7 @@ #include "unity_test_runner.h" #include "esp_heap_caps.h" #include "test_utils.h" +#include "esp_task_wdt.h" #define TEST_MEMORY_LEAK_THRESHOLD (-350) @@ -27,6 +28,10 @@ void setUp(void) { before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + + esp_task_wdt_add(NULL); + esp_task_wdt_reset(); + } void tearDown(void) @@ -37,10 +42,22 @@ void tearDown(void) size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); check_leak(before_free_8bit, after_free_8bit, "8BIT"); check_leak(before_free_32bit, after_free_32bit, "32BIT"); + + esp_task_wdt_reset(); + esp_task_wdt_delete(NULL); } void app_main(void) { + // Configure the task watchdog timer to catch any tests that hang + esp_task_wdt_config_t config = { + .timeout_ms = 25 * 1000, // 25 seconds, smaller than the default pytest timeout + .idle_core_mask = 0, + .trigger_panic = true, + }; + + esp_task_wdt_init(&config); + // Raise priority to main task as some tests depend on the test task being at priority UNITY_FREERTOS_PRIORITY vTaskPrioritySet(NULL, UNITY_FREERTOS_PRIORITY); unity_run_menu(); diff --git a/components/esp_timer/test_apps/main/test_app_main.c b/components/esp_timer/test_apps/main/test_app_main.c index a4c1c22289..a2be45ba15 100644 --- a/components/esp_timer/test_apps/main/test_app_main.c +++ b/components/esp_timer/test_apps/main/test_app_main.c @@ -1,14 +1,48 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ #include "unity.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "esp_task_wdt.h" + +// On C2 due to only have a single HW WDT we use the timer +// so some tests will interfere with the WDT +#if !CONFIG_IDF_TARGET_ESP32C2 +#define WDT_MONITOR_UNITY_TASK +#endif + +void setUp(void) +{ +#ifdef WDT_MONITOR_UNITY_TASK + esp_task_wdt_add(NULL); + esp_task_wdt_reset(); +#endif +} + +void tearDown(void) +{ +#ifdef WDT_MONITOR_UNITY_TASK + esp_task_wdt_reset(); + esp_task_wdt_delete(NULL); +#endif +} void app_main(void) { + // Configure the task watchdog timer to catch any tests that hang +#ifdef WDT_MONITOR_UNITY_TASK + esp_task_wdt_config_t config = { + .timeout_ms = 25 * 1000, // 25 seconds, smaller than the default pytest timeout + .idle_core_mask = 0, + .trigger_panic = true, + }; + + esp_task_wdt_init(&config); +#endif + vTaskPrioritySet(NULL, CONFIG_UNITY_FREERTOS_PRIORITY); unity_run_menu(); } diff --git a/components/esp_timer/test_apps/main/test_esp_timer.c b/components/esp_timer/test_apps/main/test_esp_timer.c index 899096240b..88eb874ab3 100644 --- a/components/esp_timer/test_apps/main/test_esp_timer.c +++ b/components/esp_timer/test_apps/main/test_esp_timer.c @@ -773,7 +773,7 @@ TEST_CASE("esp_timer_impl_set_alarm does not set an alarm below the current time esp_timer_create(&periodic_timer_args, &periodic_timer[1]); esp_timer_start_periodic(periodic_timer[1], 9000); - vTaskDelay(60 * 1000 / portTICK_PERIOD_MS); + vTaskDelay(15 * 1000 / portTICK_PERIOD_MS); task_stop = true; esp_timer_stop(periodic_timer[0]); @@ -822,7 +822,7 @@ TEST_CASE("esp_timer_impl_set_alarm and using start_once do not lead that the Sy esp_timer_start_once(oneshot_timer, 9990); printf("timers created\n"); - vTaskDelay(60 * 1000 / portTICK_PERIOD_MS); + vTaskDelay(20 * 1000 / portTICK_PERIOD_MS); task_stop = true; esp_timer_stop(oneshot_timer); diff --git a/components/freertos/test_apps/freertos/main/test_freertos_main.c b/components/freertos/test_apps/freertos/main/test_freertos_main.c index 2293213827..6832952d93 100644 --- a/components/freertos/test_apps/freertos/main/test_freertos_main.c +++ b/components/freertos/test_apps/freertos/main/test_freertos_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,7 @@ #include "unity_test_runner.h" #include "esp_heap_caps.h" #include "test_utils.h" +#include "esp_task_wdt.h" #define TEST_MEMORY_LEAK_THRESHOLD (-512) @@ -27,6 +28,10 @@ void setUp(void) { before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + + esp_task_wdt_add(NULL); + esp_task_wdt_reset(); + } void tearDown(void) @@ -37,10 +42,23 @@ void tearDown(void) size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); check_leak(before_free_8bit, after_free_8bit, "8BIT"); check_leak(before_free_32bit, after_free_32bit, "32BIT"); + + esp_task_wdt_reset(); + esp_task_wdt_delete(NULL); } void app_main(void) { + + // Configure the task watchdog timer to catch any tests that hang + esp_task_wdt_config_t config = { + .timeout_ms = 25 * 1000, // 25 seconds, smaller than the default pytest timeout + .idle_core_mask = 0, + .trigger_panic = true, + }; + + esp_task_wdt_init(&config); + /* Some FreeRTOS tests are reliant on the main task being at priority UNITY_FREERTOS_PRIORITY to test scheduling behavior. Thus, we raise the main task's priority before any tasks are run. See IDF-6088