Source code for test_automation.targets.fvp.plugin

#
# SPDX-FileCopyrightText: <text>Copyright 2025 Arm Limited
# and/or its affiliates <open-source-office@arm.com></text>
#
# SPDX-License-Identifier: MIT
#

import os
from pathlib import Path
import logging
import sys

from test_automation.targets.fvp.autofvpnetworking import (
    TelnetSessionManager as TM,
)
from test_automation.targets.fvp.fvp_controller import LocalFVP
from test_automation.targets.registry import (
    register_platform,
    DriverBundle,
)

[docs] logger = logging.getLogger(__name__)
@register_platform("fvp")
[docs] def make_fvp_bundle(platform_dict, cfg) -> DriverBundle: """ Build and return a driver instance for the ``fvp`` platform. :param platform_dict: Platform configuration mapping as loaded from YAML. :param cfg: Global configuration object and forwarded to the telnet session manager for context. :returns: A :class:`DriverBundle`. """ platform_name = platform_dict["name"] telnet = TM(config=cfg, platform=platform_name, test_name="session") fvp_device = LocalFVP(platform_config=platform_dict, telnet_manager=telnet) def _login_primary(mgr: TM, plat: dict): """ Log in on the primary console using the session manager's prompt maps. :param mgr: Active :class:`TelnetSessionManager` that manages console sessions. :param plat: Platform configuration mapping (expects ``port_map`` with ``default_console``). :raises AssertionError: If the expected prompts are not observed on the primary console during login. :returns: ``None``. """ mapping = mgr.terminal_to_port primary_console = plat["port_map"]["default_console"] assert ( primary_console in mapping ), f"Primary console ({primary_console}) not found" port = mapping[primary_console] login_prompt = mgr.login_prompt_map.get( primary_console, mgr.default_login_prompt ) shell_prompt = mgr.shell_prompt_map.get( primary_console, mgr.default_shell_prompt ) assert mgr.wait_for_prompt_in_log(port, login_prompt, timeout=100), ( f"Login prompt '{login_prompt}' not seen on " f"{primary_console}:{port}" ) assert mgr.wait_for_prompt_in_log(port, login_prompt, timeout=100), ( f"Login prompt '{login_prompt}' not seen on " f"{primary_console}:{port}" ) mgr.sessions[port].sendline("root") assert mgr.wait_for_prompt_in_log(port, shell_prompt, timeout=100), ( f"Shell prompt '{shell_prompt}' not seen on " f"{primary_console}:{port}" ) logger.info("Logged in on %s:%d", primary_console, port) def _export_env(pytestconfig, plat: dict) -> None: """ Optionally export environment variables for FVP execution. Sets ``FVP_BINARY`` from ``--fvp-binary`` or existing environment, and attempts to locate ``Crypto.so`` under the model base directory. If the provided binary path does not exist, the process exits. :param pytestconfig: Pytest configuration object used to read command-line options. :param plat: Platform configuration mapping (context only; not modified). :returns: ``None``. :raises SystemExit: If an invalid FVP binary path is supplied. """ fvp_bin_cli = pytestconfig.getoption("--fvp-binary") fvp_bin = fvp_bin_cli or os.environ.get("FVP_BINARY") if not fvp_bin: logger.info("No --fvp-binary provided; skipping FVP env export") return bin_path = Path(fvp_bin).expanduser().resolve() if not bin_path.exists(): logger.warning("FVP binary does not exist: %s", bin_path) sys.exit(1) model_dir = bin_path.parent fvp_base_dir = model_dir.parent.parent os.environ["FVP_BINARY"] = str(bin_path) # Optional Crypto.so autodiscovery crypto_path = None try: for p in fvp_base_dir.rglob("Crypto.so"): crypto_path = str(p.resolve()) break except Exception as e: logger.warning("Error searching for Crypto.so: %s", e) if crypto_path: os.environ["FVP_CRYPTO_PATH"] = crypto_path logger.debug("Found Crypto.so at: %s", crypto_path) else: logger.warning("Crypto.so not found under %s", fvp_base_dir) return DriverBundle( driver=fvp_device, manager=telnet, login_primary=_login_primary, export_env=_export_env, )