From b61bafb1d70db46e0063b66b7a8ec58f995d0d4b Mon Sep 17 00:00:00 2001 From: Sebastian Birunt Date: Tue, 10 Jun 2025 15:25:25 +0100 Subject: [PATCH 1/4] refactor: program runfiles Move program runfiles logic from `bazel/labgrid/runner` to `labgrid/run`. It will allow to remove `include_runfiles` from `FileTransfer`. --- labgrid/run/run.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/labgrid/run/run.py b/labgrid/run/run.py index c5b242f..77cfb23 100644 --- a/labgrid/run/run.py +++ b/labgrid/run/run.py @@ -20,7 +20,14 @@ def run( ) -> int: with runner() as r: program_remote = program_prefix / program.name - uploads += [FileTransfer(program_remote, program, include_runfiles=True)] + uploads += [FileTransfer(program_remote, program)] + + program_runfiles = program.with_suffix(".runfiles") + if program_runfiles.exists(): + uploads += [ + FileTransfer(program_remote.with_suffix(".runfiles"), program_runfiles) + ] + cmd = join((f"./{program_remote}", *arguments)) r.put(uploads) -- GitLab From d3a205a0880977837e671114233fe82216fc9347 Mon Sep 17 00:00:00 2001 From: Sebastian Birunt Date: Tue, 10 Jun 2025 15:35:07 +0100 Subject: [PATCH 2/4] refactor: remove `include_runfiles` BREAKING CHANGE This change removes `include_runfiles` from `FileTransfer`. Runfiles are handled explicitly by `labgrid/run`. --- bazel/labgrid/runner/runner.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/bazel/labgrid/runner/runner.py b/bazel/labgrid/runner/runner.py index 0134be2..d3789e5 100644 --- a/bazel/labgrid/runner/runner.py +++ b/bazel/labgrid/runner/runner.py @@ -28,16 +28,11 @@ class FileTransfer: remote: PurePath local: Path optional: bool - # FIXME: Decide whether or not to transfer runfiles implicitly instead of using a flag - include_runfiles: bool - def __init__( - self, remote: str, local: str = "", optional=False, include_runfiles=False - ): + def __init__(self, remote: str, local: str = "", optional=False): object.__setattr__(self, "remote", PurePath(remote)) object.__setattr__(self, "local", Path(local if local else remote)) object.__setattr__(self, "optional", optional) - object.__setattr__(self, "include_runfiles", include_runfiles) def _log_level(value): @@ -96,12 +91,6 @@ class Runner: self._run(f"{self._tools.mkdir(remote.parent)}") self._transfer.put(local, remote) - if upload.include_runfiles: - src_runfiles = local.with_suffix(".runfiles") - dest_runfiles = remote.with_suffix(".runfiles") - if src_runfiles.exists(): - self._transfer.put(f"{src_runfiles}", f"{dest_runfiles}") - def get(self, downloads: Iterator[FileTransfer], code: int): """Files to transfer from the device to the host. -- GitLab From 06df427c2207f7c89f68dd9e9b4a5bd9f1efe78e Mon Sep 17 00:00:00 2001 From: Sebastian Birunt Date: Tue, 10 Jun 2025 09:02:47 +0100 Subject: [PATCH 3/4] fix: runfiles location Assumption for runfiles location next to binary target to run is not always ture. Location will differ when bazel target is defined as a subpackage, e.g.: `//test/check:test`. Add `--program-runfiles-dir` attribute for the runfiles to look for. --- labgrid/run/__main__.py | 14 +++++++++++++- labgrid/run/run.py | 11 +++++------ labgrid/test/rule.bzl | 1 + 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/labgrid/run/__main__.py b/labgrid/run/__main__.py index b9021c5..3ff6df0 100644 --- a/labgrid/run/__main__.py +++ b/labgrid/run/__main__.py @@ -1,7 +1,7 @@ #! /usr/bin/env python3 from __future__ import annotations -from argparse import REMAINDER, ArgumentParser, ArgumentTypeError +from argparse import REMAINDER, ArgumentParser, ArgumentTypeError, Namespace from os import environ, getenv from pathlib import Path, PurePath from string import Template @@ -30,6 +30,12 @@ def arguments(prsr: ArgumentParser) -> None: default="", help="Prefix of the path to the program on the device.", ) + prsr.add_argument( + "--program-runfiles-dir", + type=unquoted, + default="", + help="Location of the program runfiles to transfer to the target device. Defaults to `.runfiles`.", + ) prsr.add_argument( "--env", help=( @@ -105,6 +111,11 @@ def put(value: str) -> FileTransfer: return FileTransfer(remote, local) +def program_runfiles_dir(args: Namespace) -> str: + dir = args.program_runfiles_dir or str(args.program.with_suffix(".runfiles")) + return resolve(dir) + + def main(exe: Path, *args: str) -> int: prsr = ArgumentParser( prog=str(exe), description="Runs a command on a LabGrid device." @@ -118,6 +129,7 @@ def main(exe: Path, *args: str) -> int: parsed.program, *parsed.arguments, program_prefix=PurePath(parsed.program_prefix), + program_runfiles_dir=program_runfiles_dir(parsed), downloads=parsed.downloads, uploads=parsed.uploads, env=dict(parsed.env), diff --git a/labgrid/run/run.py b/labgrid/run/run.py index 77cfb23..a968ab7 100644 --- a/labgrid/run/run.py +++ b/labgrid/run/run.py @@ -14,19 +14,18 @@ def run( program: Path, *arguments: str, program_prefix: PurePath, + program_runfiles_dir: Path, downloads: Iterator[FileTransfer], uploads: Iterator[FileTransfer], env: Mapping[str, str], ) -> int: with runner() as r: program_remote = program_prefix / program.name - uploads += [FileTransfer(program_remote, program)] + program_remote_runfiles = program_prefix / program_runfiles_dir.name - program_runfiles = program.with_suffix(".runfiles") - if program_runfiles.exists(): - uploads += [ - FileTransfer(program_remote.with_suffix(".runfiles"), program_runfiles) - ] + uploads += [FileTransfer(program_remote, program)] + if program_runfiles_dir.exists(): + uploads += [FileTransfer(program_remote_runfiles, program_runfiles_dir)] cmd = join((f"./{program_remote}", *arguments)) diff --git a/labgrid/test/rule.bzl b/labgrid/test/rule.bzl index d88cb20..20b7bf9 100644 --- a/labgrid/test/rule.bzl +++ b/labgrid/test/rule.bzl @@ -76,6 +76,7 @@ def implementation(ctx): args.add("--") args.add(to_rlocation_path(ctx, ctx.executable._run)) args.add_all(["--program-prefix", paths.dirname(ctx.executable.src.short_path)]) + args.add_all(["--program-runfiles-dir", paths.join(ctx.workspace_name, ctx.label.package, "{}.runfiles".format(ctx.attr.src.label.name))]) args.add_all(env.items(), map_each = _env) args.add("--") args.add(to_rlocation_path(ctx, ctx.executable.src)) -- GitLab From 38e5fbb60337d8fed464e5bfdead6817e2396701 Mon Sep 17 00:00:00 2001 From: Sebastian Birunt Date: Wed, 11 Jun 2025 13:41:01 +0100 Subject: [PATCH 4/4] test: verify `labgrid_test` src Add tests to verify `labgrid_test.src` target can be defined in separate bazel packages (upper and lower). --- e2e/test/BUILD.bazel | 9 +++++++++ e2e/test/subdir/BUILD.bazel | 19 +++++++++++++++++++ e2e/test/subdir/hello.py | 18 ++++++++++++++++++ e2e/test/subdir/hello.txt | 1 + 4 files changed, 47 insertions(+) create mode 100644 e2e/test/subdir/BUILD.bazel create mode 100644 e2e/test/subdir/hello.py create mode 100644 e2e/test/subdir/hello.txt diff --git a/e2e/test/BUILD.bazel b/e2e/test/BUILD.bazel index 4e243af..7289279 100644 --- a/e2e/test/BUILD.bazel +++ b/e2e/test/BUILD.bazel @@ -7,6 +7,7 @@ py_binary( srcs = ["hello.py"], data = [":hello.txt"], main = "hello.py", + visibility = [":__subpackages__"], deps = ["@rules_python//python/runfiles"], ) @@ -17,6 +18,14 @@ labgrid_test( platform = "@rules_labgrid//labgrid/platform:localhost", ) +# Regression test for: https://gitlab.arm.com/bazel/rules_labgrid/-/issues/77 +labgrid_test( + name = "src-in-subpackage", + size = "small", + src = "//test/subdir:inner", + platform = "@rules_labgrid//labgrid/platform:localhost", +) + write_file( name = "greeting", out = "greeting.py", diff --git a/e2e/test/subdir/BUILD.bazel b/e2e/test/subdir/BUILD.bazel new file mode 100644 index 0000000..3a2dc24 --- /dev/null +++ b/e2e/test/subdir/BUILD.bazel @@ -0,0 +1,19 @@ +load("@rules_labgrid//labgrid/test:defs.bzl", "labgrid_test") +load("@rules_python//python:defs.bzl", "py_binary") + +py_binary( + name = "inner", + srcs = ["hello.py"], + data = [":hello.txt"], + main = "hello.py", + visibility = ["//test:__subpackages__"], + deps = ["@rules_python//python/runfiles"], +) + +# Regression test for: https://gitlab.arm.com/bazel/rules_labgrid/-/issues/77 +labgrid_test( + name = "src-in-upper-package", + size = "small", + src = "//test:inner", + platform = "@rules_labgrid//labgrid/platform:localhost", +) diff --git a/e2e/test/subdir/hello.py b/e2e/test/subdir/hello.py new file mode 100644 index 0000000..776c96f --- /dev/null +++ b/e2e/test/subdir/hello.py @@ -0,0 +1,18 @@ +import unittest +from pathlib import Path + +from python.runfiles import Runfiles + + +def _runfile(path): + r = Runfiles.Create() + return Path(r.Rlocation(path)).read_text() + + +class HelloTestCase(unittest.TestCase): + def test(self): + self.assertEqual(_runfile("_main/test/subdir/hello.txt").rstrip(), "world") + + +if __name__ == "__main__": + unittest.main() diff --git a/e2e/test/subdir/hello.txt b/e2e/test/subdir/hello.txt new file mode 100644 index 0000000..cc628cc --- /dev/null +++ b/e2e/test/subdir/hello.txt @@ -0,0 +1 @@ +world -- GitLab