Merge branch 'ci/add_test_wdt_helper' into 'master'

test(core): add WDT protection to detect stuck tests

See merge request espressif/esp-idf!42828
This commit is contained in:
Marius Vikhammer
2025-10-27 14:46:58 +08:00
5 changed files with 92 additions and 6 deletions
@@ -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.
@@ -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();
@@ -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();
}
@@ -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);
@@ -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