Restructures tests/hardware/ so that fixture access is controlled by
directory layout — pytest only walks upward through conftest.py files,
so a PSU test physically cannot request fio/alm/nad.
Layout:
- tests/hardware/conftest.py (unchanged: PSU fixtures)
- tests/hardware/mum/conftest.py NEW: _require_mum (session autouse),
fio (session), nad (session),
alm (session), _reset_to_off
(function autouse)
- tests/hardware/mum/** MUM tests + swe5/ + swe6/
- tests/hardware/psu/** PSU-only tests
- tests/hardware/babylin/** deprecated BabyLIN E2E
What this removes (was duplicated before):
- 7 verbatim copies of the `fio` fixture
- 6 copies of the `alm` fixture
- 6 copies of the `_reset_to_off` autouse
- 9 inline `if config.interface.type != "mum": pytest.skip(...)` gates
What this changes by design:
- fio / alm / nad scope: module → session. NAD discovery happens once
per run instead of once per module. The helpers are immutable beyond
their constructor args, so sharing them is safe; per-test state is
reset by the autouse `_reset_to_off`.
- test_overvolt.py: `_park_at_nominal` is now `_reset_to_off`, which
cleanly overrides the conftest's LED-only version (PSU + LED reset).
- test_mum_alm_animation_generated.py keeps a local `_reset_to_off` +
`_force_off` so its "no AlmTester anywhere" demonstration is preserved
via fixture override; the local `nad` is also retained because it
uses the typed `AlmStatus.receive` API.
Docs:
- docs/24_test_wiring.md NEW — describes the three-layer fixture
topology, lifecycle sequence diagram, helper class wiring, and the
playbook for adding a new framework component.
- docs/05_architecture_overview.md: add MCF (mum conftest) node to the
Mermaid diagram + mention it in the components list.
- docs/19_frame_io_and_alm_helpers.md: replace the per-module
fixture-wiring example with a request-fixtures-by-name snippet plus
the override pattern.
- Path references swept across docs/02, docs/14, docs/18, docs/20,
docs/README to point at the new locations.
Verified: pytest --collect-only collects 93 tests with no errors;
30 unit tests and 10 mock-only smoke tests pass; fixture-per-test
output shows PSU tests cannot see fio/alm/nad.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
153 lines
6.5 KiB
Markdown
153 lines
6.5 KiB
Markdown
# Configuration Resolution: What is read and when
|
|
|
|
This document explains how configuration is loaded, merged, and provided to tests and interfaces.
|
|
|
|
> Looking for the implementation deep-dive — merge semantics, type coercion,
|
|
> the forward-reference quirk in `EcuTestConfig`, and the PSU side-channel?
|
|
> See [`23_config_loader_internals.md`](23_config_loader_internals.md).
|
|
|
|
## Sources and precedence
|
|
|
|
From highest to lowest precedence:
|
|
|
|
1. In-code overrides (if `load_config(..., overrides=...)` is used)
|
|
2. Environment variable `ECU_TESTS_CONFIG` (absolute/relative path to YAML)
|
|
3. `config/test_config.yaml` (if present under the workspace root)
|
|
4. Built-in defaults
|
|
|
|
## Data model (dataclasses)
|
|
|
|
- `EcuTestConfig`
|
|
- `interface: InterfaceConfig`
|
|
- `type`: `mock`, `mum`, or `babylin` (deprecated)
|
|
- `channel`: LIN channel index (0-based in SDK wrapper) — BabyLIN-specific (deprecated)
|
|
- `bitrate`: LIN baudrate (e.g., 19200). The MUM uses this directly; BabyLIN typically takes it from the SDF (deprecated path)
|
|
- `sdf_path`: Path to SDF file (BabyLIN; deprecated — required for typical BabyLIN operation)
|
|
- `schedule_nr`: Schedule number to start on connect (BabyLIN; deprecated). `-1` = skip
|
|
- `node_name`: Optional node identifier (informational)
|
|
- `dll_path`, `func_names`: Deprecated legacy fields from the old ctypes adapter; not used with the SDK wrapper
|
|
- `host`: MUM IP address (MUM-only). Required when `type: mum`
|
|
- `lin_device`: MUM LIN device name (MUM-only, default `lin0`)
|
|
- `power_device`: MUM power-control device (MUM-only, default `power_out0`)
|
|
- `boot_settle_seconds`: Delay after MUM power-up before sending the first frame (default 0.5)
|
|
- `frame_lengths`: Optional `{frame_id: data_length}` map for the MUM adapter to drive slave-published reads. Hex keys like `0x0A` are supported in YAML. When `ldf_path` is set, this acts as an override on top of LDF-derived lengths.
|
|
- `ldf_path`: Optional path to a `.ldf` file. Tests can request the `ldf` fixture to obtain an `LdfDatabase` for per-frame `pack`/`unpack`; the MUM adapter additionally inherits frame lengths from the LDF. Relative paths resolve against the workspace root
|
|
- `flash: FlashConfig`
|
|
- `enabled`: whether to flash before tests
|
|
- `hex_path`: path to HEX file
|
|
- `power_supply: PowerSupplyConfig`
|
|
- `enabled`: whether PSU features/tests are active
|
|
- `port`: Serial device (e.g., `COM4`, `/dev/ttyUSB0`)
|
|
- `baudrate`, `timeout`, `eol`: line settings (e.g., `"\n"` or `"\r\n"`)
|
|
- `parity`: `N|E|O`
|
|
- `stopbits`: `1` or `2`
|
|
- `xonxoff`, `rtscts`, `dsrdtr`: flow control flags
|
|
- `idn_substr`: optional substring to assert in `*IDN?`
|
|
- `do_set`, `set_voltage`, `set_current`: optional demo/test actions
|
|
|
|
## YAML examples
|
|
|
|
Minimal mock configuration (default):
|
|
|
|
```yaml
|
|
interface:
|
|
type: mock
|
|
channel: 1
|
|
bitrate: 19200
|
|
flash:
|
|
enabled: false
|
|
```
|
|
|
|
Hardware via MUM (current default) — see also `config/mum.example.yaml`:
|
|
|
|
```yaml
|
|
interface:
|
|
type: mum
|
|
host: 192.168.7.2 # MUM IP address (USB-RNDIS default)
|
|
lin_device: lin0 # MUM LIN device name
|
|
power_device: power_out0 # MUM power-control device
|
|
bitrate: 19200 # LIN baudrate
|
|
boot_settle_seconds: 0.5 # Delay after power-up before first frame
|
|
frame_lengths:
|
|
0x0A: 8 # ALM_Req_A
|
|
0x11: 4 # ALM_Status
|
|
flash:
|
|
enabled: false
|
|
```
|
|
|
|
Hardware (BabyLIN SDK wrapper) configuration — DEPRECATED, prefer the MUM example above:
|
|
|
|
```yaml
|
|
interface:
|
|
type: babylin # deprecated
|
|
channel: 0 # 0-based channel index
|
|
bitrate: 19200 # optional; typically driven by SDF
|
|
node_name: "ECU_TEST_NODE"
|
|
sdf_path: "./vendor/Example.sdf"
|
|
schedule_nr: 0
|
|
flash:
|
|
enabled: true
|
|
hex_path: "firmware/ecu_firmware.hex"
|
|
|
|
Power supply configuration (either inline or merged from a dedicated YAML):
|
|
|
|
```yaml
|
|
power_supply:
|
|
enabled: true
|
|
port: COM4 # or /dev/ttyUSB0 on Linux
|
|
baudrate: 115200
|
|
timeout: 1.0
|
|
eol: "\n" # or "\r\n" if your device requires CRLF
|
|
parity: N # N|E|O
|
|
stopbits: 1 # 1|2
|
|
xonxoff: false
|
|
rtscts: false
|
|
dsrdtr: false
|
|
idn_substr: OWON
|
|
do_set: false
|
|
set_voltage: 5.0
|
|
set_current: 0.1
|
|
```
|
|
```
|
|
|
|
## Load flow
|
|
|
|
```text
|
|
tests/conftest.py: config() fixture
|
|
→ load_config(workspace_root)
|
|
→ check env var ECU_TESTS_CONFIG
|
|
→ else check config/test_config.yaml
|
|
→ else use defaults
|
|
→ convert dicts to EcuTestConfig dataclasses
|
|
→ provide to other fixtures/tests
|
|
|
|
Additionally, if present, a dedicated PSU YAML is merged into `power_supply`:
|
|
|
|
- Environment variable `OWON_PSU_CONFIG` (path to YAML), else
|
|
- `config/owon_psu.yaml` under the workspace root
|
|
|
|
This lets you keep machine-specific serial settings separate while still having
|
|
central defaults in `config/test_config.yaml`.
|
|
```
|
|
|
|
## How tests and adapters consume config
|
|
|
|
- `lin` fixture picks `mock`, `mum`, or `babylin` (deprecated) based on `interface.type`
|
|
- Mock adapter uses `bitrate` and `channel` to simulate timing/behavior
|
|
- MUM adapter uses `host`, `lin_device`, `power_device`, `bitrate`, `boot_settle_seconds`, and `frame_lengths` to open the MUM, set up the LIN bus, and power up the ECU on connect
|
|
- BabyLIN adapter (SDK wrapper, **DEPRECATED**) uses `sdf_path`, `schedule_nr`, `channel` to open the device, load the SDF, and start a schedule. `bitrate` is informational unless explicitly applied via commands/SDF. Selecting `interface.type: babylin` emits a `DeprecationWarning`.
|
|
- `flash_ecu` uses `flash.enabled` and `flash.hex_path`
|
|
- PSU-related tests or utilities read `config.power_supply` for serial parameters
|
|
and optional actions (IDN assertions, on/off toggle, set/measure). The reference
|
|
implementation is `ecu_framework/power/owon_psu.py`, with a hardware test in
|
|
`tests/hardware/psu/test_owon_psu.py` and a quick demo script in `vendor/Owon/owon_psu_quick_demo.py`.
|
|
|
|
## Tips
|
|
|
|
- Keep multiple YAMLs and switch via `ECU_TESTS_CONFIG`
|
|
- Check path validity for `sdf_path` and `hex_path` before running hardware tests
|
|
- For the deprecated BabyLIN path only: ensure `vendor/BabyLIN_library.py` and the platform-specific libraries from the SDK are available on `PYTHONPATH`
|
|
- Use environment-specific YAML files for labs vs. CI
|
|
- For PSU, prefer `OWON_PSU_CONFIG` or `config/owon_psu.yaml` to avoid committing
|
|
local COM port settings. Central defaults can live in `config/test_config.yaml`.
|