Skip to content

Commit b821e25

Browse files
committed
tests: subsys: Add test that verifies west debug command
Add test that checks if platform can be debugged with - west attach - west debug. Add test variant with debug optimizations and thread info enabled. Signed-off-by: Sebastian Głąb <[email protected]>
1 parent d91bad7 commit b821e25

File tree

5 files changed

+181
-0
lines changed

5 files changed

+181
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
cmake_minimum_required(VERSION 3.20.0)
8+
9+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
10+
project(west_debug)
11+
12+
target_sources(app PRIVATE src/main.c)

tests/subsys/west_debug/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CONFIG_LOG=y
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
import logging
8+
import re
9+
import subprocess
10+
from pathlib import Path
11+
12+
import psutil
13+
from twister_harness import DeviceAdapter
14+
15+
logger = logging.getLogger(__name__)
16+
17+
18+
# Kill parent process and all child processes (if started)
19+
def _kill(proc):
20+
try:
21+
for child in psutil.Process(proc.pid).children(recursive=True):
22+
child.kill()
23+
proc.kill()
24+
except Exception as e:
25+
logger.exception(f"Could not kill process - {e}")
26+
27+
28+
def test_west_debug(dut: DeviceAdapter):
29+
"""
30+
Compile and flash test application on MCU.
31+
Start debug session by calling `west debug` command.
32+
Set brakepoint and check that breakpoint was hit.
33+
"""
34+
BUILD_DIR = str(dut.device_config.build_dir)
35+
COLLECT_TIMEOUT = 5.0
36+
EXPECTED = r"18\s+counter\+\+;"
37+
38+
logger.debug(f"{dut.device_config=}")
39+
40+
cmd = f"west debug -d {BUILD_DIR} --skip-rebuild"
41+
try:
42+
logger.info(f"Executing:\n{cmd}")
43+
proc = subprocess.Popen(
44+
cmd.split(),
45+
stdin=subprocess.PIPE,
46+
stdout=subprocess.PIPE,
47+
stderr=subprocess.STDOUT,
48+
encoding='UTF-8',
49+
text=True,
50+
)
51+
except OSError as exc:
52+
logger.error(f"Unable to start debug session:\n{cmd=}\n{exc=}")
53+
54+
try:
55+
# set breakpoint in main.c line 18 which is `counter++;`
56+
# continue
57+
# [breakpoint shall hit]
58+
# quit
59+
outs, errs = proc.communicate(input="b main.c:18\nc\nq\ny\n", timeout=COLLECT_TIMEOUT)
60+
except subprocess.TimeoutExpired:
61+
_kill(proc)
62+
finally:
63+
outs, errs = proc.communicate()
64+
logger.info(f"{outs=}\n{errs=}")
65+
66+
expected_str = re.search(EXPECTED, outs)
67+
assert expected_str is not None, f"Failed to match {EXPECTED} in {outs}"
68+
69+
70+
def test_west_attach(dut: DeviceAdapter):
71+
"""
72+
Compile and flash test application on MCU.
73+
Cal `west atach` command.
74+
Check response to where.
75+
"""
76+
BUILD_DIR = str(dut.device_config.build_dir)
77+
COLLECT_TIMEOUT = 5.0
78+
EXPECTED = r"in k_busy_wait \(usec_to_wait=500000\)"
79+
80+
cmd = f"west attach -d {BUILD_DIR} --skip-rebuild"
81+
try:
82+
logger.info(f"Executing:\n{cmd}")
83+
proc = subprocess.Popen(
84+
cmd.split(),
85+
stdin=subprocess.PIPE,
86+
stdout=subprocess.PIPE,
87+
stderr=subprocess.STDOUT,
88+
encoding='UTF-8',
89+
text=True,
90+
)
91+
except OSError as exc:
92+
logger.error(f"Unable to start debug session:\n{cmd=}\n{exc=}")
93+
94+
try:
95+
# where
96+
# quit
97+
outs, errs = proc.communicate(input="where\nq\ny\n", timeout=COLLECT_TIMEOUT)
98+
except subprocess.TimeoutExpired:
99+
_kill(proc)
100+
finally:
101+
outs, errs = proc.communicate()
102+
logger.info(f"{outs=}\n{errs=}")
103+
104+
expected_str = re.search(EXPECTED, outs)
105+
assert expected_str is not None, f"Failed to match {EXPECTED} in {outs}"

tests/subsys/west_debug/src/main.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#include <zephyr/logging/log.h>
8+
LOG_MODULE_REGISTER(west_debug, LOG_LEVEL_INF);
9+
10+
#include <zephyr/kernel.h>
11+
12+
int main(void)
13+
{
14+
volatile int counter = 1;
15+
16+
while (true) {
17+
LOG_INF("%d: Hello from %s", counter, CONFIG_BOARD_TARGET);
18+
counter++;
19+
k_busy_wait(500000);
20+
}
21+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
common:
2+
tags: ci_tests_subsys_west_debug
3+
harness: pytest
4+
harness_config:
5+
pytest_dut_scope: session
6+
pytest_root:
7+
- "pytest/test_west_debug.py"
8+
timeout: 20
9+
platform_allow:
10+
- nrf52dk/nrf52832
11+
- nrf52840dk/nrf52840
12+
- nrf5340dk/nrf5340/cpuapp
13+
- nrf5340dk/nrf5340/cpuapp/ns
14+
- nrf5340dk/nrf5340/cpunet
15+
- nrf54h20dk/nrf54h20/cpuapp
16+
- nrf54h20dk/nrf54h20/cpuflpr
17+
- nrf54h20dk/nrf54h20/cpuppr
18+
- nrf54h20dk/nrf54h20/cpuppr/xip
19+
- nrf54h20dk/nrf54h20/cpurad
20+
- nrf54l15dk/nrf54l05/cpuapp
21+
- nrf54l15dk/nrf54l10/cpuapp
22+
- nrf54l15dk/nrf54l10/cpuapp/ns
23+
- nrf54l15dk/nrf54l15/cpuapp
24+
- nrf54l15dk/nrf54l15/cpuapp/ns
25+
- nrf54l15dk/nrf54l15/cpuflpr
26+
- nrf54l15dk/nrf54l15/cpuflpr/xip
27+
- nrf54lm20dk/nrf54lm20a/cpuapp
28+
- nrf54lm20dk/nrf54lm20a/cpuapp/ns
29+
- nrf54lm20dk/nrf54lm20a/cpuflpr
30+
- nrf54ls05dk/nrf54ls05b/cpuapp
31+
- nrf54lv10dk/nrf54lv10a/cpuapp
32+
- nrf54lv10dk/nrf54lv10a/cpuapp/ns
33+
- nrf54lv10dk/nrf54lv10a/cpuflpr
34+
integration_platforms:
35+
- nrf54lm20dk/nrf54lm20a/cpuapp
36+
37+
tests:
38+
subsys.west_debug.normal: {}
39+
subsys.west_debug.thread_info:
40+
extra_args:
41+
- CONFIG_DEBUG_OPTIMIZATIONS=y
42+
- CONFIG_DEBUG_THREAD_INFO=y

0 commit comments

Comments
 (0)