Skip to content

Commit cd198de

Browse files
committed
tests: misc: dtdoctor: cover cell errors end to end
Give the fixture devicetree a GPIO controller carrying real 'pin'/'flags' cells and a consumer that uses them, then check a bad cell, index and name against the build's real edt.pickle, and run the bad-cell shape through the wrapper with the toolchain the application was built with. The consumer's property is 'dtdoctor-gpios' while its names come from 'gpio-names', so the fixture also pins the specifier-space naming rule rather than just asserting it in a unit test. Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NS18GhZ19Qeb67QoRkCu7K
1 parent 04b883b commit cd198de

4 files changed

Lines changed: 85 additions & 2 deletions

File tree

tests/misc/dtdoctor/app.overlay

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
*
1313
* The two nodes also give the compatible two DT_INST() instances, which is
1414
* what the DT_INST()/DT_DRV_COMPAT diagnosis reports on.
15+
*
16+
* dtdoctor_gpio carries the cells ('pin' and 'flags') that the specifier
17+
* diagnosis has to find, which live in the controller's binding rather than
18+
* in the consumer's. Note that 'dtdoctor-gpios' entries are named through
19+
* 'gpio-names': names are keyed by the specifier space, not by the property.
1520
*/
1621
/ {
1722
chosen {
@@ -27,9 +32,17 @@
2732
status = "disabled";
2833
};
2934

35+
dtdoctor_gpio: dtdoctor-gpio-controller {
36+
compatible = "vnd,dtdoctor-gpio";
37+
gpio-controller;
38+
#gpio-cells = <2>;
39+
};
40+
3041
dtdoctor_enabled: dtdoctor-enabled-device {
3142
compatible = "vnd,dtdoctor-device";
3243
dtdoctor-speed = <115200>;
44+
dtdoctor-gpios = <&dtdoctor_gpio 13 1>;
45+
gpio-names = "red";
3346
status = "okay";
3447
};
3548
};

tests/misc/dtdoctor/dts/bindings/vnd,dtdoctor-device.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,8 @@ properties:
1212
dtdoctor-optional:
1313
type: int
1414
description: declared here but never set, and with no default
15+
dtdoctor-gpios:
16+
type: phandle-array
17+
description: specifier space for the cell diagnoses
18+
gpio-names:
19+
type: string-array
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# SPDX-FileCopyrightText: Copyright The Zephyr Project Contributors
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Fake GPIO controller, used by the DT Doctor integration test
5+
6+
compatible: "vnd,dtdoctor-gpio"
7+
8+
gpio-cells:
9+
- pin
10+
- flags
11+
12+
properties:
13+
gpio-controller:
14+
type: boolean
15+
required: true
16+
"#gpio-cells":
17+
type: int
18+
required: true

tests/misc/dtdoctor/verify_dtdoctor.py

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,36 @@ def test_analyzer_reports_enabled_node_without_driver(edt, edt_pickle):
9696
device_symbol("DT_N_INST_0_vnd_no_such_compat"),
9797
"No node with compatible 'vnd_no_such_compat' exists",
9898
),
99+
(
100+
"DT_N_NODELABEL_dtdoctor_enabled_P_dtdoctor_gpios_IDX_0_VAL_pn",
101+
"has no 'pn' cell in entry 0 of the 'dtdoctor-gpios' property",
102+
),
103+
(
104+
"DT_N_NODELABEL_dtdoctor_enabled_P_dtdoctor_gpios_IDX_4_VAL_pin",
105+
"has no entry 4 in the 'dtdoctor-gpios' property: there is only 1",
106+
),
107+
(
108+
"DT_N_NODELABEL_dtdoctor_enabled_P_dtdoctor_gpios_NAME_blue_VAL_pin",
109+
"has no entry named 'blue' in the 'dtdoctor-gpios' property",
110+
),
99111
]
100112

101113

102114
@pytest.mark.parametrize(
103115
'symbol, expected',
104116
TESTDATA_MACROS,
105-
ids=['nodelabel', 'alias', 'chosen', 'property', 'unset-property', 'instance', 'compatible'],
117+
ids=[
118+
'nodelabel',
119+
'alias',
120+
'chosen',
121+
'property',
122+
'unset-property',
123+
'instance',
124+
'compatible',
125+
'cell',
126+
'cell-index',
127+
'cell-name',
128+
],
106129
)
107130
def test_analyzer_reverse_engineers_macro(edt_pickle, symbol, expected):
108131
proc = run_analyzer(edt_pickle, symbol)
@@ -111,6 +134,26 @@ def test_analyzer_reverse_engineers_macro(edt_pickle, symbol, expected):
111134
assert expected in proc.stdout
112135

113136

137+
def test_analyzer_names_the_cell_controller(edt_pickle):
138+
# The cells come from the controller's binding, not from the node the macro names,
139+
# which is the indirection the diagnosis exists to spare the user
140+
proc = run_analyzer(edt_pickle, "DT_N_NODELABEL_dtdoctor_enabled_P_dtdoctor_gpios_IDX_0_VAL_pn")
141+
assert proc.returncode == 0
142+
assert "dtdoctor_gpio: /dtdoctor-gpio-controller" in proc.stdout
143+
assert " - pin" in proc.stdout
144+
assert "vnd,dtdoctor-gpio.yaml" in proc.stdout
145+
146+
147+
def test_analyzer_uses_the_specifier_space_for_names(edt_pickle):
148+
# 'dtdoctor-gpios' entries are named through 'gpio-names', not 'dtdoctor-gpio-names'
149+
proc = run_analyzer(
150+
edt_pickle, "DT_N_NODELABEL_dtdoctor_enabled_P_dtdoctor_gpios_NAME_blue_VAL_pin"
151+
)
152+
assert proc.returncode == 0
153+
assert "Entry names come from its 'gpio-names' property:" in proc.stdout
154+
assert " - red" in proc.stdout
155+
156+
114157
def test_analyzer_suggests_a_real_nodelabel(edt_pickle):
115158
# A near miss on a label that does exist has to come back as a suggestion
116159
proc = run_analyzer(edt_pickle, device_symbol("DT_N_NODELABEL_dtdoctor_enabld"))
@@ -155,13 +198,17 @@ def test_wrapper_diagnoses_compile_error(edt, edt_pickle, cc, tmp_path, template
155198
device_symbol("DT_N_INST_5_vnd_dtdoctor_device"),
156199
"so instance 5 does not exist",
157200
),
201+
(
202+
"DT_N_NODELABEL_dtdoctor_enabled_P_dtdoctor_gpios_IDX_0_VAL_pn",
203+
"has no 'pn' cell in entry 0",
204+
),
158205
]
159206

160207

161208
@pytest.mark.parametrize(
162209
'symbol, expected',
163210
TESTDATA_WRAPPER_MACROS,
164-
ids=['nodelabel', 'property', 'instance'],
211+
ids=['nodelabel', 'property', 'instance', 'cell'],
165212
)
166213
def test_wrapper_diagnoses_unexpanded_macro(edt_pickle, cc, tmp_path, symbol, expected):
167214
# The whole point of these shapes is that they reach the compiler unexpanded, so the

0 commit comments

Comments
 (0)