# Run Sequence: What Happens When You Start Tests

This document walks through the exact order of operations when you run the framework with pytest, what gets called, and where configuration/data is fetched from.

## High-level flow

1. You run pytest from PowerShell
2. pytest reads `pytest.ini` and loads configured plugins (including our custom `conftest_plugin`)
3. Test discovery collects tests under `tests/`
4. Session fixtures run:
   - `config()` loads YAML configuration
   - `lin()` selects and connects the LIN interface (Mock or BabyLin)
   - `flash_ecu()` optionally flashes the ECU (if enabled)
5. Tests execute using fixtures and call interface methods
6. Our plugin extracts test metadata (Title, Requirements, Steps) from docstrings
7. Reports are written to `reports/report.html` and `reports/junit.xml`

## Detailed call sequence

```mermaid
sequenceDiagram
  autonumber
  participant U as User (PowerShell)
  participant P as pytest
  participant PI as pytest.ini
  participant PL as conftest_plugin.py
  participant T as Test Discovery (tests/*)
  participant F as Fixtures (conftest.py)
  participant C as Config Loader (ecu_framework/config.py)
  participant PS as Power Supply (optional)
  participant L as LIN Adapter (mock/BabyLIN SDK)
  participant X as HexFlasher (optional)
  participant R as Reports (HTML/JUnit)

  U->>P: python -m pytest [args]
  P->>PI: Read addopts, markers, plugins
  P->>PL: Load custom plugin hooks
  P->>T: Collect tests
  P->>F: Init session fixtures
  F->>C: load_config(workspace_root)
  C-->>F: EcuTestConfig (merged dataclasses)
  F->>L: Create interface (mock or BabyLIN SDK)
  L-->>F: Instance ready
  F->>L: connect()
  alt flash.enabled and hex_path provided
    F->>X: HexFlasher(lin).flash_hex(hex_path)
    X-->>F: Flash result (ok/fail)
  end
  opt power_supply.enabled and port provided
    Note over PS: owon_psu_quick_demo may open PSU via ecu_framework.power.owon_psu
  end
  loop for each test
    P->>PL: runtest_makereport(item, call)
    Note over PL: Parse docstring and attach metadata
    P->>L: send()/receive()/request()
    L-->>P: Frames or None (timeout)
  end
  P->>R: Write HTML (with metadata columns)
  P->>R: Write JUnit XML
```

```text
PowerShell → python -m pytest
  ↓
pytest loads pytest.ini
  - addopts: --junitxml, --html, --self-contained-html, -p conftest_plugin
  - markers registered
  ↓
pytest collects tests in tests/
  ↓
Session fixture: config()
  → calls ecu_framework.config.load_config(workspace_root)
    → determines config file path by precedence
    → merges YAML + overrides into dataclasses (EcuTestConfig)
    → optionally merges config/owon_psu.yaml (or OWON_PSU_CONFIG) into power_supply
  ↓
Session fixture: lin(config)
  → chooses interface by config.interface.type
    - mock → ecu_framework.lin.mock.MockBabyLinInterface(...)
  - babylin → ecu_framework.lin.babylin.BabyLinInterface(...)
  → lin.connect()
  ↓
Optional session fixture: flash_ecu(config, lin)
  → if config.flash.enabled and hex_path set
  → ecu_framework.flashing.HexFlasher(lin).flash_hex(hex_path)
  ↓
Test functions execute
  → use the lin fixture to send/receive/request
  ↓
Reporting plugin (conftest_plugin.py)
  → pytest_runtest_makereport parses test docstring
  → attaches user_properties: title, requirements, steps, expected_result
  → pytest-html hooks add Title and Requirements columns
  ↓
Reports written
  → reports/report.html (HTML with metadata columns)
  → reports/junit.xml (JUnit XML for CI)
```

## Where information is fetched from

- pytest configuration: `pytest.ini`
- YAML config (default): `config/test_config.yaml`
- YAML override via env var: `ECU_TESTS_CONFIG`
- BabyLIN SDK wrapper and SDF path: `interface.sdf_path` and `interface.schedule_nr` in YAML
- Test metadata: parsed from each test’s docstring
- Markers: declared in `pytest.ini`, attached in tests via `@pytest.mark.*`

## Key components involved

- `tests/conftest.py`: defines `config`, `lin`, and `flash_ecu` fixtures
- `ecu_framework/config.py`: loads and merges configuration into dataclasses
- `ecu_framework/lin/base.py`: abstract LIN interface contract and frame shape
- `ecu_framework/lin/mock.py`: mock behavior for send/receive/request
- `ecu_framework/lin/babylin.py`: BabyLIN SDK wrapper adapter (real hardware via BabyLIN_library.py)
- `ecu_framework/flashing/hex_flasher.py`: placeholder flashing logic
- `conftest_plugin.py`: report customization and metadata extraction

## Edge cases and behavior

- If `interface.type` is `babylin` but the SDK wrapper or libraries cannot be loaded, hardware tests are skipped
- If `flash.enabled` is true but `hex_path` is missing, flashing fixture skips
- Timeouts are honored in `receive()` and `request()` implementations
- Invalid frame IDs (outside 0x00–0x3F) or data > 8 bytes will raise in `LinFrame`
