import os import pathlib import typing as t import pytest from ecu_framework.config import load_config, EcuTestConfig from ecu_framework.lin.base import LinInterface from ecu_framework.lin.mock import MockBabyLinInterface try: from ecu_framework.lin.babylin import BabyLinInterface # type: ignore except Exception: BabyLinInterface = None # type: ignore WORKSPACE_ROOT = pathlib.Path(__file__).resolve().parents[1] @pytest.fixture(scope="session") def config() -> EcuTestConfig: cfg = load_config(str(WORKSPACE_ROOT)) return cfg @pytest.fixture(scope="session") def lin(config: EcuTestConfig) -> t.Iterator[LinInterface]: iface_type = config.interface.type if iface_type == "mock": lin = MockBabyLinInterface(bitrate=config.interface.bitrate, channel=config.interface.channel) elif iface_type == "babylin": if BabyLinInterface is None: pytest.skip("BabyLin interface not available in this environment") lin = BabyLinInterface( dll_path=config.interface.dll_path, bitrate=config.interface.bitrate, channel=config.interface.channel, node_name=config.interface.node_name, func_names=config.interface.func_names, sdf_path=config.interface.sdf_path, schedule_nr=config.interface.schedule_nr, ) else: raise RuntimeError(f"Unknown interface type: {iface_type}") lin.connect() yield lin lin.disconnect() @pytest.fixture(scope="session", autouse=False) def flash_ecu(config: EcuTestConfig, lin: LinInterface) -> None: if not config.flash.enabled: pytest.skip("Flashing disabled in config") # Lazy import to avoid dependency during mock-only runs from ecu_framework.flashing import HexFlasher if not config.flash.hex_path: pytest.skip("No HEX path provided in config") flasher = HexFlasher(lin) ok = flasher.flash_hex(config.flash.hex_path) if not ok: pytest.fail("ECU flashing failed")