Skip to content

Commit 9f3a5eb

Browse files
committed
test(coredump): collect all expected uart data first, then process lazily
1 parent 4d02ae2 commit 9f3a5eb

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

tools/test_apps/system/panic/pytest_panic.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
1+
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
22
# SPDX-License-Identifier: CC0-1.0
33
import re
44
from typing import Any
@@ -120,14 +120,37 @@ def expect_coredump_flash_write_logs(dut: PanicTestDut, config: str) -> None:
120120
dut.expect_exact('Backing up stack @')
121121
dut.expect_exact('Restoring stack')
122122
dut.expect_exact('Core dump has been saved to flash.')
123-
dut.expect('Rebooting...')
123+
dut.expect(dut.REBOOT)
124+
125+
126+
def expect_coredump_uart_write_logs(dut: PanicTestDut, check_cpu_reset: Optional[bool] = True) -> Any:
127+
# ================= CORE DUMP START =================
128+
# B8AAAMAEgAGAAAAXAEAAAAAAABkAAAA
129+
# ...
130+
# ================= CORE DUMP END =================
131+
# Coredump checksum='9730d7ff'
132+
# Rebooting...
133+
# ..
134+
# rst:0xc (SW_CPU_RESET),boot:
135+
136+
# Read all uart logs until the end of the reset reason
137+
uart_str = dut.expect(',boot:', return_what_before_match=True).decode('utf-8', errors='ignore')
138+
coredump_base64 = uart_str.split(dut.COREDUMP_UART_START)[1].split(dut.COREDUMP_UART_END)[0].strip()
139+
uart_str = uart_str.split(dut.COREDUMP_UART_END)[1]
140+
assert re.search(dut.COREDUMP_CHECKSUM, uart_str)
141+
assert re.search(dut.REBOOT, uart_str)
142+
if check_cpu_reset:
143+
assert re.search(dut.CPU_RESET, uart_str)
144+
return coredump_base64
124145

125146

126147
def common_test(dut: PanicTestDut, config: str, expected_backtrace: Optional[List[str]] = None, check_cpu_reset: Optional[bool] = True,
127148
expected_coredump: Optional[Sequence[Union[str, Pattern[Any]]]] = None) -> None:
128149
if 'gdbstub' in config:
129150
if 'coredump' in config:
130-
dut.process_coredump_uart(expected_coredump, False)
151+
uart_str = dut.expect(dut.COREDUMP_CHECKSUM, return_what_before_match=True).decode('utf-8')
152+
coredump_base64 = uart_str.split(dut.COREDUMP_UART_START)[1].split(dut.COREDUMP_UART_END)[0].strip()
153+
dut.process_coredump_uart(coredump_base64, expected_coredump)
131154
dut.expect_exact('Entering gdb stub now.')
132155
dut.start_gdb_for_gdbstub()
133156
frames = dut.gdb_backtrace()
@@ -141,12 +164,14 @@ def common_test(dut: PanicTestDut, config: str, expected_backtrace: Optional[Lis
141164
expected_coredump = None
142165

143166
if 'uart' in config:
144-
dut.process_coredump_uart(expected_coredump)
167+
coredump_base64 = expect_coredump_uart_write_logs(dut, check_cpu_reset)
168+
dut.process_coredump_uart(coredump_base64, expected_coredump)
169+
check_cpu_reset = False # CPU reset is already checked in expect_coredump_uart_write_logs
145170
elif 'flash' in config:
146171
expect_coredump_flash_write_logs(dut, config)
147172
dut.process_coredump_flash(expected_coredump)
148173
elif 'panic' in config:
149-
dut.expect('Rebooting...', timeout=60)
174+
dut.expect(dut.REBOOT, timeout=60)
150175

151176
if check_cpu_reset:
152177
dut.expect_cpu_reset()

tools/test_apps/system/panic/test_panic_util/panic_dut.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
1+
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
22
# SPDX-License-Identifier: Unlicense OR CC0-1.0
33
import logging
44
import os
@@ -28,8 +28,11 @@ class PanicTestDut(IdfDut):
2828
BOOT_CMD_ADDR = 0x9000
2929
BOOT_CMD_SIZE = 0x1000
3030
DEFAULT_EXPECT_TIMEOUT = 10
31-
COREDUMP_UART_START = '================= CORE DUMP START ================='
32-
COREDUMP_UART_END = '================= CORE DUMP END ================='
31+
COREDUMP_UART_START = r'================= CORE DUMP START ================='
32+
COREDUMP_UART_END = r'================= CORE DUMP END ================='
33+
COREDUMP_CHECKSUM = r"Coredump checksum='([a-fA-F0-9]+)'"
34+
REBOOT = r'.*Rebooting\.\.\.'
35+
CPU_RESET = r'.*rst:.*(RTC_SW_CPU_RST|SW_CPU_RESET|SW_CPU)\b'
3336

3437
app: IdfApp
3538
serial: IdfSerial
@@ -106,7 +109,7 @@ def expect_reg_dump(self, core: Optional[int] = None) -> None:
106109

107110
def expect_cpu_reset(self) -> None:
108111
# no digital system reset for panic handling restarts (see IDF-7255)
109-
self.expect(r'.*rst:.*(RTC_SW_CPU_RST|SW_CPU_RESET|SW_CPU)')
112+
self.expect(self.CPU_RESET)
110113

111114
def expect_elf_sha256(self, caption: str = 'ELF file SHA256: ') -> None:
112115
"""Expect method for ELF SHA256 line"""
@@ -162,15 +165,8 @@ def _call_espcoredump(
162165
self.coredump_output.seek(0)
163166

164167
def process_coredump_uart(
165-
self, expected: Optional[List[Union[str, re.Pattern]]] = None, wait_reboot: bool = True
168+
self, coredump_base64: Any, expected: Optional[List[Union[str, re.Pattern]]] = None,
166169
) -> None:
167-
"""Extract the core dump from UART output of the test, run espcoredump on it"""
168-
self.expect(self.COREDUMP_UART_START)
169-
uart_data = self.expect('(.+)' + self.COREDUMP_UART_END)
170-
self.expect(re.compile(r"Coredump checksum='([a-fA-F0-9]+)'"))
171-
if wait_reboot:
172-
self.expect('Rebooting...')
173-
coredump_base64 = uart_data.group(1).decode('utf8')
174170
with open(os.path.join(self.logdir, 'coredump_data.b64'), 'w') as coredump_file:
175171
logging.info('Writing UART base64 core dump to %s', coredump_file.name)
176172
coredump_file.write(coredump_base64)

0 commit comments

Comments
 (0)