From 418f513726ff52e1956d513baeaf288434673d58 Mon Sep 17 00:00:00 2001 From: Sarvesh Bodakhe Date: Tue, 1 Sep 2026 13:58:14 +0530 Subject: [PATCH] test(wifi): wait for the idle task after esp_wifi_deinit in Wi-Fi UTs The Wi-Fi task deletes itself when esp_wifi_deinit() is called, and FreeRTOS only reclaims its TCB and stack from the idle task afterwards. Test apps that read the heap right after deinit therefore see that memory as still allocated and report a leak, most visibly as the eloop unit tests failing on ESP32. Wait for the idle task at every point where a test deinitialises Wi-Fi before a leak check, replacing the single-tick delays that only matched what esp_wifi_deinit() already waits for internally. (cherry picked from commit bff264775a70ed33f5f89d1ffd666ac666a5a7f0) --- .../wifi_function/main/test_wifi_country.c | 9 +++++++-- .../wifi_function/main/test_wifi_init.c | 17 +++++++++++------ .../test_apps/wifi_nvs_config/main/app_main.c | 6 +++++- .../wpa_supplicant/test_apps/main/test_eloop.c | 3 ++- .../test_apps/main/test_wifi_external_bss.c | 5 +++-- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/components/esp_wifi/test_apps/wifi_function/main/test_wifi_country.c b/components/esp_wifi/test_apps/wifi_function/main/test_wifi_country.c index 1cbb3a79e90..cd520fa96c3 100644 --- a/components/esp_wifi/test_apps/wifi_function/main/test_wifi_country.c +++ b/components/esp_wifi/test_apps/wifi_function/main/test_wifi_country.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -8,6 +8,8 @@ #include "esp_log.h" #include "test_utils.h" #include "unity_test_utils.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" #define TAG "test_wifi" #define EMPH_STR(s) "****** "s" ******" @@ -36,6 +38,8 @@ TEST_CASE("wifi set country code", "[wifi_init]") ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit")); TEST_ESP_OK(esp_wifi_deinit()); + /* Let the idle task reclaim the deleted Wi-Fi task's stack and TCB before the leak check. */ + vTaskDelay(pdMS_TO_TICKS(300)); ESP_LOGI(TAG, EMPH_STR("esp_wifi_init")); TEST_ESP_OK(esp_wifi_init(&cfg)); @@ -56,7 +60,8 @@ TEST_CASE("wifi set country code", "[wifi_init]") ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit")); TEST_ESP_OK(esp_wifi_deinit()); - vTaskDelay(1); + /* Let the idle task reclaim the deleted Wi-Fi task's stack and TCB before the leak check. */ + vTaskDelay(pdMS_TO_TICKS(300)); ESP_LOGI(TAG, "test passed..."); } diff --git a/components/esp_wifi/test_apps/wifi_function/main/test_wifi_init.c b/components/esp_wifi/test_apps/wifi_function/main/test_wifi_init.c index cb522f8875c..46e43bfef4f 100644 --- a/components/esp_wifi/test_apps/wifi_function/main/test_wifi_init.c +++ b/components/esp_wifi/test_apps/wifi_function/main/test_wifi_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -60,7 +60,8 @@ static void wifi_driver_can_start_on_APP_CPU_task(void* arg) TEST_ESP_OK(esp_wifi_init(&cfg)); ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit...")); TEST_ESP_OK(esp_wifi_deinit()); - vTaskDelay(1); + /* Let the idle task reclaim the deleted Wi-Fi task's stack and TCB before the leak check. */ + vTaskDelay(pdMS_TO_TICKS(300)); ESP_LOGI(TAG, EMPH_STR("event_deinit")); TEST_ESP_OK(event_deinit()); ESP_LOGI(TAG, "exit task..."); @@ -99,7 +100,8 @@ TEST_CASE("Calling esp_wifi_stop() with start", "[wifi_init]") TEST_ESP_OK(esp_wifi_stop()); ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit")); TEST_ESP_OK(esp_wifi_deinit()); - vTaskDelay(1); + /* Let the idle task reclaim the deleted Wi-Fi task's stack and TCB before the leak check. */ + vTaskDelay(pdMS_TO_TICKS(300)); ESP_LOGI(TAG, EMPH_STR("event_deinit")); TEST_ESP_OK(event_deinit()); ESP_LOGI(TAG, "test passed..."); @@ -116,7 +118,8 @@ TEST_CASE("Calling esp_wifi_stop() without start", "[wifi_init]") TEST_ESP_OK(esp_wifi_stop()); ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit")); TEST_ESP_OK(esp_wifi_deinit()); - vTaskDelay(1); + /* Let the idle task reclaim the deleted Wi-Fi task's stack and TCB before the leak check. */ + vTaskDelay(pdMS_TO_TICKS(300)); ESP_LOGI(TAG, EMPH_STR("event_deinit")); TEST_ESP_OK(event_deinit()); ESP_LOGI(TAG, "test passed..."); @@ -137,7 +140,8 @@ TEST_CASE("Calling esp_wifi_deinit() without stop", "[wifi_init]") TEST_ESP_OK(esp_wifi_stop()); ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit")); TEST_ESP_OK(esp_wifi_deinit()); - vTaskDelay(1); + /* Let the idle task reclaim the deleted Wi-Fi task's stack and TCB before the leak check. */ + vTaskDelay(pdMS_TO_TICKS(300)); ESP_LOGI(TAG, EMPH_STR("event_deinit")); TEST_ESP_OK(event_deinit()); ESP_LOGI(TAG, "test passed..."); @@ -154,7 +158,8 @@ TEST_CASE("Calling esp_wifi_connect() without start", "[wifi_init]") TEST_ESP_ERR(ESP_ERR_WIFI_NOT_STARTED, esp_wifi_connect()); ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit")); TEST_ESP_OK(esp_wifi_deinit()); - vTaskDelay(1); + /* Let the idle task reclaim the deleted Wi-Fi task's stack and TCB before the leak check. */ + vTaskDelay(pdMS_TO_TICKS(300)); ESP_LOGI(TAG, EMPH_STR("event_deinit")); TEST_ESP_OK(event_deinit()); ESP_LOGI(TAG, "test passed..."); diff --git a/components/esp_wifi/test_apps/wifi_nvs_config/main/app_main.c b/components/esp_wifi/test_apps/wifi_nvs_config/main/app_main.c index 35c3a9f5107..d9227a59865 100644 --- a/components/esp_wifi/test_apps/wifi_nvs_config/main/app_main.c +++ b/components/esp_wifi/test_apps/wifi_nvs_config/main/app_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -11,6 +11,8 @@ #include "esp_wifi.h" #include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" // Some resources are lazy allocated in wifi and lwip // #define TEST_MEMORY_LEAK_THRESHOLD (-1546) @@ -39,6 +41,8 @@ void setUp(void) void tearDown(void) { ESP_ERROR_CHECK(esp_wifi_deinit()); + /* Let the idle task reclaim the deleted Wi-Fi task's stack and TCB before the leak check. */ + vTaskDelay(pdMS_TO_TICKS(300)); size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); check_leak(before_free_8bit, after_free_8bit, "8BIT"); diff --git a/components/wpa_supplicant/test_apps/main/test_eloop.c b/components/wpa_supplicant/test_apps/main/test_eloop.c index 6e5cec7811e..39d564ab01b 100644 --- a/components/wpa_supplicant/test_apps/main/test_eloop.c +++ b/components/wpa_supplicant/test_apps/main/test_eloop.c @@ -97,6 +97,8 @@ static void eloop_test_wifi_stop(void) { TEST_ESP_OK(esp_wifi_stop()); TEST_ESP_OK(esp_wifi_deinit()); + /* Let the idle task reclaim the deleted Wi-Fi task's stack and TCB before the leak check. */ + vTaskDelay(300 / portTICK_PERIOD_MS); } static void reset_timeout_ctx(struct timeout_test_ctx *ctx, void *sem) @@ -269,7 +271,6 @@ TEST_CASE("Test eloop timers run", "[eloop]") vTaskDelay(250 / portTICK_PERIOD_MS); fired_before_stop = t; eloop_test_wifi_stop(); - vTaskDelay(300 / portTICK_PERIOD_MS); TEST_ASSERT_EQUAL(fired_before_stop, t); TEST_ASSERT_TRUE(t >= 1); TEST_ASSERT_TRUE(t < 6); diff --git a/components/wpa_supplicant/test_apps/main/test_wifi_external_bss.c b/components/wpa_supplicant/test_apps/main/test_wifi_external_bss.c index e63355d9225..6143421a504 100644 --- a/components/wpa_supplicant/test_apps/main/test_wifi_external_bss.c +++ b/components/wpa_supplicant/test_apps/main/test_wifi_external_bss.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -105,7 +105,8 @@ static void stop_wifi(void) } vTaskDelay(500 / portTICK_PERIOD_MS); TEST_ESP_OK(esp_wifi_deinit()); - vTaskDelay(1); + /* Let the idle task reclaim the deleted Wi-Fi task's stack and TCB before the leak check. */ + vTaskDelay(300 / portTICK_PERIOD_MS); } static void start_wifi_as_sta(void)