Task WDT: add a panic test case for to test panic on both CPU cores

This commit is contained in:
Omar Chebib 2022-07-15 19:38:23 +08:00
parent e25cda2c40
commit 2f7bae7a6e
3 changed files with 119 additions and 14 deletions

View File

@ -248,7 +248,7 @@ static void check_reset_reason_task_wdt(void)
}
TEST_CASE_MULTIPLE_STAGES("reset reason ESP_RST_TASK_WDT after task watchdog",
"[reset_reason][reset=abort,"RESET"]",
"[reset_reason][reset="RESET"]",
do_task_wdt,
check_reset_reason_task_wdt);

View File

@ -16,7 +16,11 @@ static const char* get_test_name(void);
static void test_abort(void);
static void test_abort_cache_disabled(void);
static void test_int_wdt(void);
static void test_task_wdt(void);
static void test_task_wdt_cpu0(void);
#if !CONFIG_FREERTOS_UNICORE
static void test_task_wdt_cpu1(void);
static void test_task_wdt_both_cpus(void);
#endif
static void test_storeprohibited(void);
static void test_cache_error(void);
static void test_int_wdt_cache_disabled(void);
@ -50,7 +54,11 @@ void app_main(void)
HANDLE_TEST(test_abort);
HANDLE_TEST(test_abort_cache_disabled);
HANDLE_TEST(test_int_wdt);
HANDLE_TEST(test_task_wdt);
HANDLE_TEST(test_task_wdt_cpu0);
#if !CONFIG_FREERTOS_UNICORE
HANDLE_TEST(test_task_wdt_cpu1);
HANDLE_TEST(test_task_wdt_both_cpus);
#endif
HANDLE_TEST(test_storeprohibited);
HANDLE_TEST(test_cache_error);
HANDLE_TEST(test_int_wdt_cache_disabled);
@ -87,13 +95,41 @@ static void test_int_wdt(void)
}
}
static void test_task_wdt(void)
static void test_task_wdt_cpu0(void)
{
while (true) {
;
}
}
#if !CONFIG_FREERTOS_UNICORE
static void infinite_loop(void* arg) {
(void) arg;
while(1) {
;
}
}
static void test_task_wdt_cpu1(void)
{
xTaskCreatePinnedToCore(infinite_loop, "Infinite loop", 1024, NULL, 1, NULL, 1);
while (true) {
vTaskDelay(1);
}
}
static void test_task_wdt_both_cpus(void)
{
xTaskCreatePinnedToCore(infinite_loop, "Infinite loop", 1024, NULL, 4, NULL, 1);
/* Give some time to the task on CPU 1 to be scheduled */
vTaskDelay(1);
xTaskCreatePinnedToCore(infinite_loop, "Infinite loop", 1024, NULL, 4, NULL, 0);
while (true) {
;
}
}
#endif
static void __attribute__((no_sanitize_undefined)) test_storeprohibited(void)
{
*(int*) 0x1 = 0;

View File

@ -18,6 +18,16 @@ CONFIGS = [
pytest.param('panic', marks=[pytest.mark.esp32, pytest.mark.esp32s2]),
]
# An ESP32-only config, used for tests requiring two cores
CONFIGS_ESP32 = [
pytest.param('coredump_flash_bin_crc', marks=[pytest.mark.esp32]),
pytest.param('coredump_flash_elf_sha', marks=[pytest.mark.esp32]),
pytest.param('coredump_uart_bin_crc', marks=[pytest.mark.esp32]),
pytest.param('coredump_uart_elf_crc', marks=[pytest.mark.esp32]),
pytest.param('gdbstub', marks=[pytest.mark.esp32]),
pytest.param('panic', marks=[pytest.mark.esp32]),
]
def get_default_backtrace(config: str) -> List[str]:
return [config, 'app_main', 'main_task', 'vPortTaskWrapper']
@ -28,11 +38,16 @@ def common_test(dut: PanicTestDut, config: str, expected_backtrace: Optional[Lis
dut.expect_exact('Entering gdb stub now.')
dut.start_gdb()
frames = dut.gdb_backtrace()
if not dut.match_backtrace(frames, expected_backtrace):
raise AssertionError(
'Unexpected backtrace in test {}:\n{}'.format(config, pformat(frames))
)
dut.revert_log_level()
# Make sure frames and the expected_backtrace have the same size, else, an exception will occur
if expected_backtrace is not None:
size = min(len(frames), len(expected_backtrace))
frames = frames[0:size]
expected_backtrace = expected_backtrace[0:size]
if not dut.match_backtrace(frames, expected_backtrace):
raise AssertionError(
'Unexpected backtrace in test {}:\n{}'.format(config, pformat(frames))
)
dut.revert_log_level()
return
if 'uart' in config:
@ -47,14 +62,14 @@ def common_test(dut: PanicTestDut, config: str, expected_backtrace: Optional[Lis
@pytest.mark.parametrize('config', CONFIGS, indirect=True)
@pytest.mark.generic
def test_task_wdt(dut: PanicTestDut, config: str, test_func_name: str) -> None:
def test_task_wdt_cpu0(dut: PanicTestDut, config: str, test_func_name: str) -> None:
dut.expect_test_func_name(test_func_name)
dut.expect_exact(
'Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:'
)
dut.expect_exact('CPU 0: main')
dut.expect(r'abort\(\) was called at PC [0-9xa-f]+ on core 0')
dut.expect_none('register dump:')
dut.expect_exact('Print CPU 0 (current core) backtrace')
dut.expect_backtrace()
dut.expect_elf_sha256()
dut.expect_none('Guru Meditation')
@ -64,9 +79,63 @@ def test_task_wdt(dut: PanicTestDut, config: str, test_func_name: str) -> None:
dut,
config,
expected_backtrace=[
# Backtrace interrupted when abort is called, IDF-842
'panic_abort',
'esp_system_abort',
'test_task_wdt_cpu0',
'app_main'
],
)
else:
common_test(dut, config)
@pytest.mark.parametrize('config', CONFIGS_ESP32, indirect=True)
@pytest.mark.generic
def test_task_wdt_cpu1(dut: PanicTestDut, config: str, test_func_name: str) -> None:
dut.expect_test_func_name(test_func_name)
dut.expect_exact(
'Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:'
)
dut.expect_exact('CPU 1: Infinite loop')
dut.expect_none('register dump:')
dut.expect_exact('Print CPU 1 backtrace')
dut.expect_backtrace()
dut.expect_elf_sha256()
dut.expect_none('Guru Meditation')
if config == 'gdbstub':
common_test(
dut,
config,
expected_backtrace=[
'infinite_loop'
],
)
else:
common_test(dut, config)
@pytest.mark.parametrize('config', CONFIGS_ESP32, indirect=True)
@pytest.mark.generic
def test_task_wdt_both_cpus(dut: PanicTestDut, config: str, test_func_name: str) -> None:
dut.expect_test_func_name(test_func_name)
dut.expect_exact(
'Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:'
)
dut.expect_exact('CPU 0: Infinite loop')
dut.expect_exact('CPU 1: Infinite loop')
dut.expect_none('register dump:')
dut.expect_exact('Print CPU 0 (current core) backtrace')
dut.expect_backtrace()
dut.expect_exact('Print CPU 1 backtrace')
dut.expect_backtrace()
dut.expect_elf_sha256()
dut.expect_none('Guru Meditation')
if config == 'gdbstub':
common_test(
dut,
config,
expected_backtrace=[
'infinite_loop'
],
)
else: