1# Copyright (c) 2024 Vestas Wind Systems A/S
2#
3# SPDX-License-Identifier: Apache-2.0
4
5"""
6Configuration of Zephyr CAN <=> host CAN test suite.
7"""
8
9import logging
10import re
11
12import pytest
13from can import Bus, BusABC
14from can_shell import CanShellBus
15from twister_harness import DeviceAdapter, Shell
16
17logger = logging.getLogger(__name__)
18
19def pytest_addoption(parser) -> None:
20    """Add local parser options to pytest."""
21    parser.addoption('--can-context', default=None,
22                     help='Configuration context to use for python-can (default: None)')
23
24@pytest.fixture(name='context', scope='session')
25def fixture_context(request, dut: DeviceAdapter) -> str:
26    """Return the name of the python-can configuration context to use."""
27    ctx = request.config.getoption('--can-context')
28
29    if ctx is None:
30        for fixture in dut.device_config.fixtures:
31            if fixture.startswith('can:'):
32                ctx = fixture.split(sep=':', maxsplit=1)[1]
33                break
34
35    logger.info('using python-can configuration context "%s"', ctx)
36    return ctx
37
38@pytest.fixture(name='chosen', scope='module')
39def fixture_chosen(shell: Shell) -> str:
40    """Return the name of the zephyr,canbus devicetree chosen device."""
41    chosen_regex = re.compile(r'zephyr,canbus:\s+(\S+)')
42    lines = shell.get_filtered_output(shell.exec_command('can_host chosen'))
43
44    for line in lines:
45        m = chosen_regex.match(line)
46        if m:
47            chosen = m.groups()[0]
48            logger.info('testing on zephyr,canbus chosen device "%s"', chosen)
49            return chosen
50
51    pytest.fail('zephyr,canbus chosen device not found or not ready')
52    return None
53
54@pytest.fixture
55def can_dut(dut: DeviceAdapter, shell: Shell, chosen: str) -> BusABC:
56    """Return DUT CAN bus."""
57    bus = CanShellBus(dut, shell, chosen)
58    yield bus
59    bus.shutdown()
60    dut.clear_buffer()
61
62@pytest.fixture
63def can_host(context: str) -> BusABC:
64    """Return host CAN bus."""
65    bus = Bus(config_context = context)
66    yield bus
67    bus.shutdown()
68