diff --git a/config/runtime/base/pull_labs.jinja2 b/config/runtime/base/pull_labs.jinja2 index 1cfb7f6061..3b4cfd1ee4 100644 --- a/config/runtime/base/pull_labs.jinja2 +++ b/config/runtime/base/pull_labs.jinja2 @@ -77,6 +77,13 @@ "url": "{{ instance_callback }}/node/{{ node.id }}", "token_name": "{{ callback_token_name | default('kernelci-pipeline-callback') }}" } +{%- if tuxrun_parameters %} + ,"parameters": { +{%- for k, v in tuxrun_parameters.items() %} + "{{ k }}": "{{ v }}"{{ "," if not loop.last else "" }} +{%- endfor %} + } +{%- endif %} {%- if node.artifacts.metadata %} ,"integrity": { "sha256": { diff --git a/kernelci/runtime/pull_labs.py b/kernelci/runtime/pull_labs.py index 331ea69272..dab325fed4 100644 --- a/kernelci/runtime/pull_labs.py +++ b/kernelci/runtime/pull_labs.py @@ -269,6 +269,28 @@ def get_log_parser(self): return LogParser(log) +LEGACY_FVP_ARCH_VERSION = { + "linux-5.15.y": "9.5", + "linux-6.1.y": "9.5", +} + + +def compute_tuxrun_parameters(platform_name, node): + """Build tuxrun --parameters K=V values per job. + + Clamps FVP_ARM_ARCH_VERSION on FVP jobs for legacy trees that + cannot boot on newer Arm architecture versions. + """ + params = {} + if platform_name and platform_name.startswith("fvp-"): + branch = ( + node.get("data", {}).get("kernel_revision", {}).get("branch", "") + ) + if branch in LEGACY_FVP_ARCH_VERSION: + params["FVP_ARM_ARCH_VERSION"] = LEGACY_FVP_ARCH_VERSION[branch] + return params + + class PullLabs(Runtime): """Runtime implementation for PULL_LABS protocol @@ -288,6 +310,9 @@ def get_params(self, job, api_config=None): params = super().get_params(job, api_config) params["timeout"] = self.config.timeout params["poll_interval"] = self.config.poll_interval + params["tuxrun_parameters"] = compute_tuxrun_parameters( + job.platform_config.name, job.node + ) return params def generate(self, job, params): diff --git a/tests/test_runtime.py b/tests/test_runtime.py index c8f5ec04f0..b8b2f88679 100644 --- a/tests/test_runtime.py +++ b/tests/test_runtime.py @@ -12,6 +12,7 @@ import kernelci.config import kernelci.runtime +from kernelci.runtime.pull_labs import compute_tuxrun_parameters class _FakeResponse: @@ -345,3 +346,40 @@ def post_handler(url, payload): job_id = lab._submit("jobdef") assert job_id == 123 assert captured["json"]["definition"] == "jobdef" + + +def _node_with_branch(branch): + return {"data": {"kernel_revision": {"branch": branch}}} + + +def test_compute_tuxrun_parameters_legacy_fvp(): + """Old stable trees on FVP clamp to an older Arm arch version.""" + for branch in ("linux-5.15.y", "linux-6.1.y"): + params = compute_tuxrun_parameters( + "fvp-aemva", _node_with_branch(branch) + ) + assert params == {"FVP_ARM_ARCH_VERSION": "9.5"} + + +def test_compute_tuxrun_parameters_modern_fvp(): + """Mainline and modern stable trees on FVP keep the default arch version.""" + for branch in ("master", "linux-6.6.y", "linux-6.12.y", "linux-next"): + params = compute_tuxrun_parameters( + "fvp-aemva", _node_with_branch(branch) + ) + assert params == {} + + +def test_compute_tuxrun_parameters_non_fvp(): + """Non-FVP platforms get no tuxrun parameters regardless of branch.""" + for platform in ("qemu-arm64", "rpi4", "rk3588"): + params = compute_tuxrun_parameters( + platform, _node_with_branch("linux-5.15.y") + ) + assert params == {} + + +def test_compute_tuxrun_parameters_missing_branch(): + """Nodes lacking kernel_revision.branch get an empty parameter set.""" + assert compute_tuxrun_parameters("fvp-aemva", {}) == {} + assert compute_tuxrun_parameters("fvp-aemva", {"data": {}}) == {}