Skip to content

Commit 1ea4bcd

Browse files
Merge branch 'master' into test-teardown-dut-th-cleanup-impl
2 parents 0814b8e + ca3e67c commit 1ea4bcd

300 files changed

Lines changed: 36975 additions & 2023 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
---
2+
name: python-test-runner
3+
description: >-
4+
Guidelines and instructions for building prerequisite example applications
5+
and running python-based integration and certification tests located in
6+
`src/python_testing/`. Use this skill to run important regression tests
7+
during developement or, when building new example apps, or when there is a
8+
need to execute python test scripts or "certification test scripts" or
9+
mentions of run_python_test.py and local.py.
10+
---
11+
12+
# Python Test Runner
13+
14+
This skill provides expert guidelines for running Python-based integration and
15+
certification tests located in `src/python_testing/`.
16+
17+
## Prerequisite 1: Activating the Python Environment
18+
19+
Before running any Python tests, you must compile (if one doesn't exist in out/)
20+
and activate the project's Python virtual environment.
21+
22+
> [!IMPORTANT] Different runner methods may expect different virtual
23+
> environments. The modern local runner script (`local.py`) hardcodes `out/venv`
24+
> as its Python environment. Ensure you compile and activate this specific
25+
> folder:
26+
27+
```bash
28+
./scripts/build_python.sh -i out/venv --enable_ipv4 true
29+
source out/venv/bin/activate
30+
```
31+
32+
Be sure to check the arguments in the `build_python.sh` script before setting up
33+
the virtual environment. Run the shell script with the `--help` argument to see
34+
all available options that may be relevant for the tests.
35+
36+
---
37+
38+
## Prerequisite 2: Building the Example Application
39+
40+
Matter Python tests execute against a compiled device simulator application.
41+
Before you can run any test locally, you must identify, map, and compile the
42+
required application from source.
43+
44+
> [!NOTE] For many modern Python tests, the use of the **`all-devices-app`** is
45+
> preferred, which allows simulating specific device type(s) on endpoints.
46+
> However, many existing tests continue to use **`chip-all-clusters-app`**, and
47+
> some domain-specific tests may require other specialized apps (e.g.,
48+
> `chip-energy-management-app`).
49+
50+
### 1. Identify the Required Application
51+
52+
Open the Python test file (e.g., `src/python_testing/TC_FAN_3_3.py`) and locate
53+
the **`=== BEGIN CI TEST ARGUMENTS ===`** block near the top of the file. Under
54+
the `app` parameter, you will see the application defined as an environment
55+
variable, such as:
56+
57+
- `app: ${ALL_CLUSTERS_APP}`
58+
- `app: ${ALL_DEVICES_APP}`
59+
60+
These environment variables map to specific compiled applications. Locally, you
61+
will need to know where these apps are built (usually in the `out/` directory)
62+
to reference them correctly.
63+
64+
### 2. Map Environment Variable to a Build Target
65+
66+
To compile the required application, match the environment variable from the
67+
test header to a buildable target defined in `scripts/build/build/targets.py`.
68+
69+
Typical mappings:
70+
71+
- `${ALL_CLUSTERS_APP}` -> Target: `linux-x64-all-clusters-clang` (builds
72+
`chip-all-clusters-app`)
73+
- `${ALL_DEVICES_APP}` -> Target: `linux-x64-all-devices-clang` (builds
74+
`all-devices-app`)
75+
76+
To see the full list of compile targets available in the project:
77+
78+
```bash
79+
scripts/run_in_build_env.sh "./scripts/build/build_examples.py targets"
80+
```
81+
82+
### 3. Build the Target
83+
84+
Activate the environment and use the `build_examples.py` tool to compile the
85+
application.
86+
87+
```bash
88+
source scripts/activate.sh
89+
./scripts/build/build_examples.py --target {build_target} build
90+
```
91+
92+
Example:
93+
94+
```bash
95+
source scripts/activate.sh
96+
./scripts/build/build_examples.py --target linux-x64-all-devices-clang build
97+
```
98+
99+
Once compiled, the application binary will be located in its corresponding
100+
target folder under `out/` (e.g.
101+
`out/linux-x64-all-devices-clang/all-devices-app`). Keep track of this local
102+
path, as you will pass it explicitly to the execution commands.
103+
104+
---
105+
106+
## Determining Test Arguments
107+
108+
The header comments at the top of each python test file define the parameters
109+
used for both the example app and the script.
110+
111+
> [!TIP] When running locally and manually passing arguments, ignore or remove
112+
> environment-variable-based arguments (like `${TRACE_APP}` or
113+
> `${TRACE_TEST_JSON}`) from your command line. These are intended for CI
114+
> pipelines.
115+
116+
### Excluding Arguments During Local Testing
117+
118+
When running tests manually on a local workstation, you can (and sometimes
119+
should) omit certain CI-mandated arguments depending on your specific testing
120+
goal:
121+
122+
- **Omitting `--factory-reset` and `--commissioning-method`**: If you are
123+
running multiple test scripts sequentially against the _same_ active device
124+
session or commissioning window, you should omit these flags. Factory
125+
resetting or re-commissioning is unnecessary if the device is already
126+
configured and commissioned on the controller.
127+
- **Reusing KVS Storage**: If you wish to verify state persistence across
128+
application restarts (e.g. simulating a power cycle), make sure you do _not_
129+
pass `--factory-reset` or delete your `--KVS` database files.
130+
131+
---
132+
133+
## Identifying Test Header Parameters
134+
135+
The header comments at the top of each python test file define the parameters
136+
used for both the example app and the script. You can understand what each
137+
parameter does using this description:
138+
139+
- **`app`**: Indicates the application to be used in the test.
140+
- _Example_: `app: ${ALL_DEVICES_APP}`
141+
- **`factory-reset`**: Determines whether a factory reset should be performed
142+
before the test (i.e., wiping persistent KVS files).
143+
- _Example_: `factory-reset: true`
144+
- **`quiet`**: Sets the verbosity level of the test run. When set to `true`,
145+
the test runner generates less output.
146+
- _Example_: `quiet: true`
147+
- **`app-args`**: Specifies the arguments to be passed to the application
148+
during the test.
149+
- _Example_: `--discriminator 1234 --KVS kvs1`
150+
- **`--discriminator`**: Specifies the discriminator value used by the
151+
application during commissioning to uniquely identify the device during
152+
the discovery phase. This will change the pairing code for the device
153+
- **`--KVS`**: Specifies the path to the Key-Value Store (KVS) file. The
154+
KVS is a persistent database used by the application to store state
155+
(such as commissioned fabrics, node IDs, etc.) so that they survive
156+
application restarts. Specifying a unique KVS path prevents state
157+
interference between concurrent test runs.
158+
- **`app-ready-pattern`**: Regular expression pattern to match against the
159+
application's stdout to determine when the application has completed
160+
initialization. The test runner blocks script execution until this pattern
161+
is found.
162+
- _Example_: `"Manual pairing code: \\[\\d+\\]"`
163+
- **`app-stdin-pipe`**: Path to a named pipe that the test runner can use to
164+
pipe standard input command strings into the application process.
165+
- _Example_: `dut-input`
166+
- **`script-args`**: Specifies the CLI arguments to be passed to the test
167+
script itself.
168+
- _Example_:
169+
`--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021`
170+
171+
---
172+
173+
## Python Script Command Line Arguments
174+
175+
When running the test script directly (using Python) or passing arguments inside
176+
`--script-args`, you can customize the execution. Use `--help` on any script to
177+
get a full list of arguments. Key parameters include:
178+
179+
- **`--storage-path`**: Configures the file path where local state and
180+
credentials are persisted (e.g., `--storage-path admin_storage.json`).
181+
Providing this argument avoids state conflicts between concurrent runs.
182+
Defaults to `admin_storage.json` in the current working directory.
183+
- **`--commissioning-method`**: Specifies the method to use for commissioning
184+
(e.g. `on-network`). Because `chip-tool` and the python controller do not
185+
share credentials, the python script must commission the simulator target.
186+
- **Pairing Codes**:
187+
- `--discriminator` (e.g. `1234`)
188+
- `--passcode` (e.g. `20202021`)
189+
- `--qr-code`
190+
- `--manual-code`
191+
- **`--tests`**: Filters which test case(s) within the script to execute.
192+
- **`--PICS`**: Path to the PICS XML file or directory defining supported
193+
features.
194+
- **Custom Script Arguments (PIXITs)**: Used for passing custom config values
195+
to the script. Must be supplied in `key:value` format:
196+
- `--bool-arg` (e.g. `--bool-arg pixit_name:False`)
197+
- `--int-arg`
198+
- `--float-arg`
199+
- `--string-arg`
200+
- `--json-arg`
201+
- `--hex-arg`
202+
203+
---
204+
205+
## Running Tests: Method 1 (CI Meta Runner - Recommended)
206+
207+
The project provides a high-level local test harness script,
208+
`./scripts/tests/local.py`. This is the **preferred and most automated method**
209+
for running python tests locally because it pulls test metadata and CI arguments
210+
directly from the headers of the Python test scripts.
211+
212+
### Setup Requirements
213+
214+
This script hardcodes the virtual environment location to `out/venv`. You must
215+
compile and activate this specific virtual environment path before running the
216+
command:
217+
218+
```bash
219+
./scripts/build_python.sh -i out/venv --enable_ipv4 true
220+
source out/venv/bin/activate
221+
```
222+
223+
### Executing Tests
224+
225+
Use the `python-tests` subcommand and specify a filter using `--test-filter` to
226+
target specific test suites:
227+
228+
```bash
229+
./scripts/tests/local.py python-tests --test-filter {test_name}
230+
```
231+
232+
### Mapping Apps using `--override-binary-path`
233+
234+
Because the script reads the CI blocks directly, it parses variables like
235+
`app: ${ALL_CLUSTERS_APP}`. By default, it attempts to look for built binaries
236+
in default output folders. If your compiled binaries are located in a
237+
non-standard build path, you must map the CI variable to your local compiled
238+
file using `--override-binary-path`:
239+
240+
```bash
241+
./scripts/tests/local.py python-tests \
242+
--test-filter {test_name} \
243+
--override-binary-path {CI_APP_VARIABLE} {path_to_local_built_binary}
244+
```
245+
246+
### Execution Example:
247+
248+
```bash
249+
./scripts/tests/local.py python-tests \
250+
--test-filter TC_RR_1_1 \
251+
--override-binary-path ALL_CLUSTERS_APP out/linux-x64-all-clusters-no-ble/chip-all-clusters-app
252+
```
253+
254+
### Notable Arguments for `local.py python-tests`
255+
256+
- **`--test-filter`**: Runs only the test scripts that match this glob pattern
257+
(e.g., `TC_RR_1_1` or `TC_FAN_*`).
258+
- **`--override-binary-path`**: Maps a CI environment variable (e.g.,
259+
`ALL_CLUSTERS_APP`, `ALL_DEVICES_APP`) to a specific path where the
260+
application is built. Can be passed multiple times.
261+
- **`--fail-log-dir`**: Specifies a directory to write logs when a test fails
262+
(creates `{test_name}.out.log` and `{test_name}.err.log` inside the
263+
directory). If not specified, failed test logs are printed directly to
264+
stdout/stderr.
265+
- **`--skip`**: Excludes specific test names or patterns from running.
266+
- **`--include-nightly`**: Includes slow nightly tests that are skipped by
267+
default.
268+
- **`--keep-going`**: Instructs the runner to continue executing subsequent
269+
tests even if a previous test in the queue fails.
270+
- **`--help`**: View the help dialog for more information.
271+
272+
---
273+
274+
## Running Tests: Method 2 (Combined Runner)
275+
276+
This uses the `run_python_test.py` script directly to manage starting the app,
277+
running the test, and collecting logs. Unlike `local.py`, you must explicitly
278+
provide all arguments since it does not read metadata blocks from the files.
279+
280+
### Combined Runner Template
281+
282+
With the Python environment active:
283+
284+
```bash
285+
./scripts/tests/run_python_test.py \
286+
--factory-reset \
287+
--app {path_to_compiled_app_binary} \
288+
--app-args "{app_arguments}" \
289+
--script {path_to_python_script} \
290+
--script-args "{script_arguments}"
291+
```
292+
293+
### Combined Examples
294+
295+
#### Example A: Contact Sensor (All-Devices) Test
296+
297+
```bash
298+
./scripts/tests/run_python_test.py \
299+
--factory-reset \
300+
--app ./out/linux-x64-all-devices-clang/all-devices-app \
301+
--app-args "--device contact-sensor:1 --discriminator 1234 --KVS kvs1" \
302+
--script src/python_testing/TC_IDM_2_3.py \
303+
--script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values"
304+
```
305+
306+
Note that the `--endpoint` script argument is relevant for most apps and tests.
307+
Some tests may exclude an endpoint argument and use the default one (which often
308+
is EP 0), but it is best to explicitly specify which endpoint should be used.
309+
310+
#### Example B: All Clusters App Test
311+
312+
```bash
313+
./scripts/tests/run_python_test.py \
314+
--factory-reset \
315+
--app ./out/linux-x64-all-clusters-clang/chip-all-clusters-app \
316+
--app-args "--discriminator 1234 --KVS kvs1" \
317+
--script src/python_testing/TC_GC_2_2.py \
318+
--script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --endpoint 1"
319+
```
320+
321+
---
322+
323+
## Running Tests: Method 3 (Two Terminals)
324+
325+
This method is useful for interactive debugging, allowing you to monitor the
326+
application's stdout logs side-by-side with the test script runner.
327+
328+
### Step A: Start the Example Application
329+
330+
In one terminal, run your locally built application binary:
331+
332+
```bash
333+
./out/linux-x64-all-devices-clang/all-devices-app \
334+
--device contact-sensor:1 \
335+
--discriminator 1234 \
336+
--KVS kvs1
337+
```
338+
339+
Note that the all devices app should always specify a device type and endpoint,
340+
in the format `device-type:endpoint-number`
341+
342+
### Step B: Run the Python Test Script
343+
344+
In a second terminal, run the python script after activating the Python virtual
345+
environment:
346+
347+
```bash
348+
source out/venv/bin/activate
349+
350+
python3 src/python_testing/TC_IDM_2_3.py \
351+
--storage-path admin_storage.json \
352+
--commissioning-method on-network \
353+
--discriminator 1234 \
354+
--passcode 20202021 \
355+
--PICS src/app/tests/suites/certification/ci-pics-values
356+
```

.devcontainer/devcontainer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
},
2929
"customizations": {
3030
"vscode": {
31-
// Add the IDs of extensions you want installed when the container is created in the array below.
3231
"extensions": [
3332
"mcu-debug.debug-tracker-vscode",
3433
"aaron-bond.better-comments",

.github/actions/notify-slack-failure/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ runs:
6666
if [[ ${#CONTENT} -gt 300 ]]; then
6767
CONTENT="${CONTENT:0:300}..."
6868
fi
69-
EXTRA_TEXT="\n*Failed Tests:* ${CONTENT}"
69+
EXTRA_TEXT=" *Failed Tests:* ${CONTENT}"
7070
fi
7171
fi
7272
73-
PAYLOAD_TEXT="🚨 *CI Failure Alert* 🚨\n*Job:* ${JOB_TEXT}\n*Run Details:* <${RUN_URL}|View Pipeline Logs>${EXTRA_TEXT}"
73+
PAYLOAD_TEXT="🚨 *CI Failure Alert* 🚨 *Job:* ${JOB_TEXT} *Run Details:* <${RUN_URL}|View Pipeline Logs>${EXTRA_TEXT:-}"
7474
7575
JSON_PAYLOAD=$(python3 -c 'import json, sys; print(json.dumps({"text": sys.argv[1]}))' "$PAYLOAD_TEXT")
7676

.github/workflows/build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ jobs:
384384
scripts/run_in_build_env.sh 'virtualenv pyenv'
385385
source pyenv/bin/activate
386386
python -m ensurepip --upgrade
387-
python -m pip install out/controller/python/matter*.whl
387+
python -m pip install out/obj/src/controller/python/matter-controller-wheels/*.whl
388388
389389
- name: Run Python tests
390390
shell: bash

0 commit comments

Comments
 (0)