diff --git a/test/unit/refs/definitions/qemu-lava-job-definition.yaml b/test/unit/refs/definitions/qemu-lava-job-definition.yaml new file mode 100644 index 0000000..16679c6 --- /dev/null +++ b/test/unit/refs/definitions/qemu-lava-job-definition.yaml @@ -0,0 +1,77 @@ +actions: +- deploy: + images: + bios: + url: https://ci.trustedfirmware.org/job/tf-a-builder/2422951/artifact/artefacts/debug/qemu_bios.bin + initrd: + compression: gz + image_arg: -initrd {initrd} + url: https://ci.trustedfirmware.org/job/tf-a-builder/2422951/artifact/artefacts/debug/rootfs.bin.gz + kernel: + image_arg: -kernel {kernel} + url: https://ci.trustedfirmware.org/job/tf-a-builder/2422951/artifact/artefacts/debug/kernel.bin + to: tmpfs +- boot: + media: tmpfs + method: qemu + prompts: + - root@tf-busyboot:/root# + timeout: + minutes: 2 +- test: + interactive: + - name: interactive_uart0_0 + prompts: + - root@tf-busyboot:/root# + script: + - command: /bin/uname -a + name: interactive_command_uart0_0 + successes: + - message: Linux +context: + arch: aarch64 + cpu: max + extra_options: + - -smp 1 + - -m 1024 + machine: virt +device_type: qemu +job_name: qemu-linux-qemu-default +metadata: + build_url: https://ci.trustedfirmware.org/job/tf-a-builder/2422951/ + emulator: qemu-virt + test_config: qemu-default +priority: medium +timeouts: + actions: + auto-login-action: + minutes: 2 + boot-image-retry: + minutes: 2 + boot-qemu-image: + minutes: 2 + bootloader-action: + minutes: 3 + bootloader-commands: + minutes: 3 + bootloader-interrupt: + seconds: 30 + bootloader-retry: + minutes: 3 + download-retry: + minutes: 5 + lava-test-shell: + minutes: 3 + login-action: + minutes: 5 + nfs-deploy: + minutes: 10 + power-off: + seconds: 10 + reset-device: + seconds: 30 + connection: + minutes: 2 + job: + minutes: 15 +visibility: public diff --git a/test/unit/test_device.py b/test/unit/test_device.py index 6d665c5..674e6f7 100644 --- a/test/unit/test_device.py +++ b/test/unit/test_device.py @@ -10,7 +10,8 @@ from tuxlava.__main__ import main from tuxlava.devices import Device -from tuxlava.devices.fvp import FVPLAVA, FVPMorelloAndroid +from tuxlava.devices.fvp import FVPMorelloAndroid +from tuxlava.devices.lava import FVPLAVA, QemuLAVA from tuxlava.devices.qemu import QemuArmv5 from tuxlava.exceptions import InvalidArgument @@ -22,6 +23,7 @@ def test_select(): assert Device.select("qemu-armv5") == QemuArmv5 assert Device.select("fvp-morello-android") == FVPMorelloAndroid assert Device.select("fvp-lava") == FVPLAVA + assert Device.select("qemu-lava") == QemuLAVA with pytest.raises(InvalidArgument): Device.select("Hello") @@ -2073,6 +2075,15 @@ def artefacts(tmp_path): ], "fvp-lava-job-definition.yaml", ), + ( + [ + "--device", + "qemu-lava", + "--job-definition", + f"{BASE}/refs/definitions/qemu-lava-job-definition.yaml", + ], + "qemu-lava-job-definition.yaml", + ), ( [ "--device", @@ -3538,6 +3549,7 @@ def test_definition(monkeypatch, mocker, capsys, tmpdir, artefacts, args, filena "'ssh-host', ssh-user', 'ssh-identity-file' are required argument for ssh device", ), (["--device", "fvp-lava"], "Missing argument --job-definition"), + (["--device", "qemu-lava"], "Missing argument --job-definition"), ( [ "--device", diff --git a/tuxlava/devices/__init__.py b/tuxlava/devices/__init__.py index e6df88a..0e00c53 100644 --- a/tuxlava/devices/__init__.py +++ b/tuxlava/devices/__init__.py @@ -102,3 +102,4 @@ def extra_assets(self, tmpdir, **kwargs) -> List[str]: import tuxlava.devices.qemu # noqa: E402,F401 import tuxlava.devices.ssh # noqa: E402,F401 import tuxlava.devices.flasher # noqa: E402,F401 +import tuxlava.devices.lava # noqa: E402,F401 diff --git a/tuxlava/devices/fvp.py b/tuxlava/devices/fvp.py index 6cc413d..a2cda98 100644 --- a/tuxlava/devices/fvp.py +++ b/tuxlava/devices/fvp.py @@ -9,8 +9,6 @@ from typing import Any, Dict, List, Optional import re -import urllib -import yaml from tuxlava import templates from tuxlava.devices import Device from tuxlava.exceptions import InvalidArgument @@ -333,27 +331,3 @@ class FVPMorelloGrub(MorelloFVPDevice): kernel_start_message = "Press enter to boot the selected OS" prompts = ["highlighted entry will be executed"] support_tests = True - - -class FVPLAVA(FVPDevice): - name = "fvp-lava" - - def validate(self, job_definition, **kwargs): - if not job_definition: - raise InvalidArgument("Missing argument --job-definition") - parsed_url = urllib.parse.urlparse(job_definition) - job_definition = urllib.parse.unquote(parsed_url.path) - with open(job_definition, "r") as job_file: - try: - # Load yaml and dump data as string to verify that - # lava job definition is valid - yaml_data = yaml.dump(yaml.safe_load(job_file)) - self.job_definition = yaml_data - except Exception: - raise InvalidArgument("Unable to load LAVA job definition") - return - - def default(self, options) -> None: ... # noqa: E704 - - def definition(self, **kwargs): - return self.job_definition diff --git a/tuxlava/devices/lava.py b/tuxlava/devices/lava.py new file mode 100644 index 0000000..79c0c47 --- /dev/null +++ b/tuxlava/devices/lava.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# +# vim: set ts=4 +# +# Copyright 2026-present Linaro Limited +# +# SPDX-License-Identifier: MIT + +from urllib.parse import unquote, urlparse + +import yaml + +from tuxlava.devices import Device +from tuxlava.devices.fvp import FVPDevice +from tuxlava.devices.qemu import QemuDevice +from tuxlava.exceptions import InvalidArgument + + +class LAVADevice(Device): + real_device = False + + def validate(self, job_definition, **kwargs): + if not job_definition: + raise InvalidArgument("Missing argument --job-definition") + parsed_url = urlparse(job_definition) + job_definition = unquote(parsed_url.path) + with open(job_definition, "r") as job_file: + try: + # Load yaml and dump data as string to verify that + # lava job definition is valid + yaml_data = yaml.dump(yaml.safe_load(job_file)) + self.job_definition = yaml_data + except Exception: + raise InvalidArgument("Unable to load LAVA job definition") + return + + def default(self, options) -> None: ... # noqa: E704 + + def definition(self, **kwargs): + return self.job_definition + + +class FVPLAVA(LAVADevice, FVPDevice): + name = "fvp-lava" + + +class QemuLAVA(LAVADevice, QemuDevice): + name = "qemu-lava"