ecu-tests/docs/05_architecture_overview.md
Hosam-Eldin Mostafa afd9da8206 docs: hardware test infrastructure, session-managed PSU, settle-then-validate
Documents the new layers introduced over the past several commits.

- docs/19_frame_io_and_alm_helpers.md (new): full reference for the
  FrameIO and AlmTester helpers — three access levels (high/mid/low),
  full API tables, fixture wiring, cookbook patterns, and §7
  describing the four-phase SETUP/PROCEDURE/ASSERT/TEARDOWN test
  pattern with the three template flavors plus a §7.4 link to the
  PSU+LIN template.

- docs/14_power_supply.md: rewritten and expanded.
    §3 cross-platform port resolution (Windows / WSL1 / WSL2 +
       usbipd-win / Linux native compatibility table)
    §4 auto-detection via idn_substr
    §5 session-managed power: contract for tests, must-not list,
       what changed in the existing tests
    §6 the settle-then-validate pattern: two-delays table (PSU
       bench-dependent vs ECU firmware-dependent), copy-paste
       example, tuning guidance for ECU_VALIDATION_TIME_S
    §6 PSU settling characterization (-m psu_settling)
    §7 library API reference table + safe_off_on_close
    §9 troubleshooting expanded with WSL2 usbipd-win + dialout

- docs/18_test_catalog.md: voltage-tolerance section refreshed for
  the settle-then-validate shape, new "Hardware – PSU settling
  (opt-in)" category, new §8 "Hardware-test infrastructure"
  documenting conftest.py, frame_io.py, alm_helpers.py,
  psu_helpers.py, and both templates.

- docs/05_architecture_overview.md: components list split into
  framework core / hardware test layer / artifacts. Mermaid diagram
  gained a Hardware-test helpers subgraph showing FrameIO,
  AlmTester, rgb_to_pwm, and the templates. Data/control flow
  summary describes the session-managed PSU and the helper layer.

- docs/15_report_properties_cheatsheet.md: PSU section split into
  per-test (function-scoped rp) and module-scoped (testsuite
  property) blocks; added psu_resolved_port, psu_resolved_idn,
  psu_settled_s, validation_time_s.

- docs/README.md: links to the new doc 19.

- README.md, TESTING_FRAMEWORK_GUIDE.md: project-structure trees
  expanded to show the full current layout — every file and
  directory under tests/hardware/ (conftest, helpers, templates,
  tests), tests/unit/, config/, docs/, scripts/, and vendor/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 19:02:42 +02:00

5.9 KiB
Raw Blame History

Architecture Overview

This document provides a high-level view of the frameworks components and how they interact, plus a Mermaid diagram for quick orientation.

Components

Framework core (ecu_framework/)

  • Config Loader — ecu_framework/config.py (YAML → dataclasses)
  • LIN Abstraction — ecu_framework/lin/base.py (LinInterface, LinFrame)
  • Mock LIN Adapter — ecu_framework/lin/mock.py
  • MUM LIN Adapter — ecu_framework/lin/mum.py (Melexis Universal Master via pylin + pymumclient)
  • BabyLIN Adapter — ecu_framework/lin/babylin.py (SDK wrapper → BabyLIN_library.py; DEPRECATED, kept for legacy rigs only)
  • LDF Database — ecu_framework/lin/ldf.py (LdfDatabase/Frame over ldfparser; per-frame pack/unpack)
  • Flasher — ecu_framework/flashing/hex_flasher.py
  • Power Supply (PSU) control — ecu_framework/power/owon_psu.py (serial SCPI + cross-platform port resolver)
  • PSU quick demo script — vendor/Owon/owon_psu_quick_demo.py

Hardware test layer (tests/hardware/)

  • Project-wide fixtures — tests/conftest.py (config, lin, ldf, flash_ecu, rp)
  • Hardware-suite fixtures — tests/hardware/conftest.py (session-scoped, autouse PSU; the bench is powered up once at session start and stays on for every test in the suite)
  • Generic LDF I/O — tests/hardware/frame_io.py (FrameIO — send/receive/pack/unpack for any LDF frame plus raw-bus escape hatches)
  • ALM domain helpers — tests/hardware/alm_helpers.py (AlmTester — force_off / wait_for_state / measure_animating_window / assert_pwm_*)
  • PSU settle helpers — tests/hardware/psu_helpers.py (wait_until_settled, apply_voltage_and_settle — measured-rail-then-validation pattern shared by all voltage-changing tests)
  • RGB→PWM calculator — vendor/rgb_to_pwm.py (consumed by AlmTester.assert_pwm_*)
  • Test templates (not collected) — tests/hardware/_test_case_template.py, tests/hardware/_test_case_template_psu_lin.py

Tests, reporting, artifacts

  • Tests (pytest) — modules under tests/{,unit,plugin,hardware}/
  • Reporting Plugin — conftest_plugin.py (docstring → report metadata)
  • Reports — reports/report.html, reports/junit.xml, reports/summary.md, reports/requirements_coverage.json

Mermaid architecture diagram

flowchart TB
  subgraph Tests_and_Pytest [Tests & Pytest]
    T[tests/* &#40;test bodies&#41;]
    CF[tests/conftest.py<br/>config, lin, ldf, flash_ecu, rp]
    HCF[tests/hardware/conftest.py<br/>SESSION psu &#40;autouse&#41;]
    PL[conftest_plugin.py]
  end

  subgraph Hardware_Helpers [Hardware-test helpers]
    FIO[tests/hardware/frame_io.py<br/>FrameIO]
    ALM[tests/hardware/alm_helpers.py<br/>AlmTester]
    RGB[vendor/rgb_to_pwm.py]
    TPL[tests/hardware/_test_case_template*.py<br/>not collected]
  end

  subgraph Framework
    CFG[ecu_framework/config.py]
    BASE[ecu_framework/lin/base.py]
    MOCK[ecu_framework/lin/mock.py]
    MUM[ecu_framework/lin/mum.py]
    BABY[ecu_framework/lin/babylin.py<br/>DEPRECATED]
    LDF[ecu_framework/lin/ldf.py]
    FLASH[ecu_framework/flashing/hex_flasher.py]
    POWER[ecu_framework/power/owon_psu.py<br/>SerialParams, OwonPSU,<br/>resolve_port]
  end

  subgraph Artifacts
    REP[reports/report.html<br/>reports/junit.xml<br/>reports/summary.md]
    YAML[config/*.yaml<br/>test_config.yaml<br/>mum.example.yaml<br/>babylin.example.yaml — deprecated]
    PSU_YAML[config/owon_psu.yaml<br/>OWON_PSU_CONFIG]
    MELEXIS[Melexis pylin + pymumclient<br/>MUM @ 192.168.7.2]
    SDK[vendor/BabyLIN_library.py<br/>platform libs<br/>DEPRECATED]
    OWON[vendor/Owon/owon_psu_quick_demo.py]
    LDFFILE[vendor/*.ldf]
    LDFLIB[ldfparser PyPI]
  end

  T --> CF
  T --> HCF
  CF --> CFG
  CF --> BASE
  CF --> MOCK
  CF --> MUM
  CF --> BABY
  CF --> FLASH
  HCF --> POWER
  T --> FIO
  T --> ALM
  ALM --> FIO
  ALM --> RGB
  TPL -.copy & edit.-> T

  PL --> REP

  CFG --> YAML
  CFG --> PSU_YAML
  MUM --> MELEXIS
  BABY --> SDK
  LDF --> LDFLIB
  LDF --> LDFFILE
  POWER --> PSU_YAML
  T --> OWON
  T --> REP

Data and control flow summary

  • Tests use fixtures to obtain config and a connected LIN adapter
  • Config loader reads YAML (or env override), returns typed dataclasses
  • LIN calls are routed through the interface abstraction to the selected adapter
  • Hardware tests sit on top of two helpers: FrameIO (LDF-driven send / receive / pack / unpack for any frame) and AlmTester (ALM_Node domain patterns built on FrameIO). Both are imported as siblings from tests/hardware/ — see docs/19_frame_io_and_alm_helpers.md
  • The hardware-suite tests/hardware/conftest.py defines a session-scoped, autouse psu fixture: on benches where the Owon PSU powers the ECU, the supply is opened once at session start, parked at config.power_supply.set_voltage / set_current, and left enabled for every test. Voltage-tolerance tests perturb voltage and restore in finally; they never toggle output. See docs/14_power_supply.md §5.
  • Flasher (optional) uses the same LinInterface to program the ECU
  • Power supply control (optional) uses ecu_framework/power/owon_psu.py and reads config.power_supply (merged with config/owon_psu.yaml or OWON_PSU_CONFIG when present). The quick demo script under vendor/Owon/ provides a quick manual flow
  • Reporting plugin parses docstrings and enriches the HTML report

Extending the architecture

  • Add new bus adapters by implementing LinInterface
  • Add new ECU-domain helpers next to AlmTester (e.g. BcmTester) on top of FrameIO; share fixtures via tests/hardware/conftest.py
  • Add new bench instrument controllers next to OwonPSU under ecu_framework/power/ or a new ecu_framework/instruments/ package, expose them as session-scoped fixtures
  • Add new report sinks (e.g., JSON or a DB) by extending the plugin