# Configuration Resolution: What is read and when

This document explains how configuration is loaded, merged, and provided to tests and interfaces.

## 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` or `babylin`
    - `channel`: LIN channel index (0-based in SDK wrapper)
    - `bitrate`: LIN bitrate (e.g., 19200); usually defined by SDF
    - `sdf_path`: Path to SDF file (hardware; required for typical operation)
    - `schedule_nr`: Schedule number to start on connect (hardware)
    - `node_name`: Optional node identifier (informational)
    - `dll_path`, `func_names`: Legacy fields from the old ctypes adapter; not used with the SDK wrapper
  - `flash: FlashConfig`
    - `enabled`: whether to flash before tests
    - `hex_path`: path to HEX file

## YAML examples

Minimal mock configuration (default):

```yaml
interface:
  type: mock
  channel: 1
  bitrate: 19200
flash:
  enabled: false
```

Hardware (BabyLIN SDK wrapper) configuration:

```yaml
interface:
  type: babylin
  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"
```

## 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
```

## How tests and adapters consume config

- `lin` fixture picks `mock` or `babylin` based on `interface.type`
- Mock adapter uses `bitrate` and `channel` to simulate timing/behavior
- BabyLIN adapter (SDK wrapper) 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.
- `flash_ecu` uses `flash.enabled` and `flash.hex_path`

## Tips

- Keep multiple YAMLs and switch via `ECU_TESTS_CONFIG`
- Check path validity for `sdf_path` and `hex_path` before running hardware tests
- 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
