mirror of
https://github.com/MrUnknownDE/OpenIris-ESPIDF.git
synced 2026-04-26 17:43:44 +02:00
Initial support for a hardware test harness with pytest and UV
This commit is contained in:
165
tests/conftest.py
Normal file
165
tests/conftest.py
Normal file
@@ -0,0 +1,165 @@
|
||||
import dotenv
|
||||
import pytest
|
||||
import time
|
||||
|
||||
from tests.utils import (
|
||||
OpenIrisDeviceManager,
|
||||
has_command_failed,
|
||||
get_current_ports,
|
||||
get_new_port,
|
||||
)
|
||||
|
||||
board_capabilities = {
|
||||
"esp_eye": ["wired", "wireless"],
|
||||
"esp32AIThinker": ["wireless"],
|
||||
"esp32Cam": ["wireless"],
|
||||
"esp32M5Stack": ["wireless"],
|
||||
"facefocusvr_eye_L": ["wired", "measure_current"],
|
||||
"facefocusvr_eye_R": ["wired", "measure_current"],
|
||||
"facefocusvr_face": ["wired", "measure_current"],
|
||||
"project_babble": ["wireless", "wired"],
|
||||
"seed_studio": ["wireless", "wired"],
|
||||
"wrooms3": ["wireless", "wired"],
|
||||
"wrooms3QIO": ["wireless", "wired"],
|
||||
"wrover": ["wireless", "wired"],
|
||||
}
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption("--board", action="store")
|
||||
parser.addoption(
|
||||
"--connection",
|
||||
action="store",
|
||||
help="Defines how to connect to the given board, wireless by ip/mdns or wired by com/cdc",
|
||||
)
|
||||
|
||||
|
||||
def pytest_configure(config):
|
||||
config.addinivalue_line(
|
||||
"markers", "has_capability(cap): skip if the board does not have the capability"
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def check_capability_marker(request, board_lacks_capability):
|
||||
"""
|
||||
Autorun on each test, checks if the board we started with, has the required capability
|
||||
|
||||
This lets us skip tests that are impossible to run on some boards - like for example:
|
||||
|
||||
It's impossible to run wired tests on a wireless board
|
||||
It's impossible to run tests for measuring current on boards without this feature
|
||||
"""
|
||||
if marker := request.node.get_closest_marker("has_capability"):
|
||||
if not len(marker.args):
|
||||
raise ValueError(
|
||||
"has_capability marker must be provided with a capability to check"
|
||||
)
|
||||
|
||||
required_capability = marker.args[0]
|
||||
if board_lacks_capability(required_capability):
|
||||
pytest.skip(f"Board does not have capability {required_capability}")
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def board_name(request):
|
||||
board_name = request.config.getoption("--board")
|
||||
if not board_name:
|
||||
raise ValueError("No board defined")
|
||||
|
||||
yield board_name
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def board_lacks_capability(board_name):
|
||||
def func(capability: str):
|
||||
if board_name:
|
||||
if board_name not in board_capabilities:
|
||||
raise ValueError(f"Unknown board {board_name}")
|
||||
|
||||
return capability not in board_capabilities[board_name]
|
||||
return True
|
||||
|
||||
return func
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def board_connection(request):
|
||||
"""
|
||||
Grabs the specified connection connection method, to be used ONLY for the initial connection. Everything after it HAS to be handled via Device Manager.
|
||||
Ports WILL change throughout the tests, device manager can keep track of that and reconnect the board as needed.
|
||||
"""
|
||||
board_connection = request.config.getoption("--connection")
|
||||
|
||||
if not board_connection:
|
||||
raise ValueError("No connection method defined")
|
||||
|
||||
yield board_connection
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def config():
|
||||
config = dotenv.dotenv_values()
|
||||
yield config
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def openiris_device_manager(board_connection, config):
|
||||
manager = OpenIrisDeviceManager()
|
||||
manager.get_device(board_connection, config)
|
||||
yield manager
|
||||
|
||||
if manager._device:
|
||||
manager._device.disconnect()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def get_openiris_device(openiris_device_manager):
|
||||
def func():
|
||||
return openiris_device_manager.get_device()
|
||||
|
||||
return func
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def ensure_board_in_mode(openiris_device_manager, config):
|
||||
"""
|
||||
Given the OpenIrisDevice manager, grabs the current device and ensures it's in the required mode
|
||||
|
||||
if not, sends the command to switch and attempts reconnection if necessary, returning the device back
|
||||
"""
|
||||
supported_modes = ["wifi", "uvc"]
|
||||
|
||||
def func(mode, device):
|
||||
if mode not in supported_modes:
|
||||
raise ValueError(f"{mode} is not a supported mode")
|
||||
|
||||
command_result = device.send_command("get_device_mode")
|
||||
if has_command_failed(command_result):
|
||||
raise ValueError(f"Failed to get device mode, error: {command_result}")
|
||||
|
||||
current_mode = command_result["results"][0]["result"]["data"]["mode"].lower()
|
||||
if mode == current_mode:
|
||||
return device
|
||||
|
||||
old_ports = get_current_ports()
|
||||
command_result = device.send_command("switch_mode", {"mode": mode})
|
||||
if has_command_failed(command_result):
|
||||
raise ValueError("Failed to switch mode, rerun the tests")
|
||||
|
||||
print("Rebooting the board after changing mode")
|
||||
device.send_command("restart_device")
|
||||
|
||||
sleep_timeout = int(config["SWITCH_MODE_REBOOT_TIME"])
|
||||
print(
|
||||
f"Sleeping for {sleep_timeout} seconds to allow the device to switch modes and boot up"
|
||||
)
|
||||
time.sleep(sleep_timeout)
|
||||
new_ports = get_current_ports()
|
||||
|
||||
new_device = openiris_device_manager.get_device(
|
||||
get_new_port(old_ports, new_ports), config
|
||||
)
|
||||
return new_device
|
||||
|
||||
return func
|
||||
Reference in New Issue
Block a user