diff --git a/bazel/labgrid/driver/BUILD.bazel b/bazel/labgrid/driver/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..bb93750bc1addcf4ecb672c79b9d16a0b4f7b3e6 --- /dev/null +++ b/bazel/labgrid/driver/BUILD.bazel @@ -0,0 +1,19 @@ +load("@rules_python//python:defs.bzl", "py_library", "py_test") + +py_library( + name = "driver", + srcs = [ + "__init__.py", + "localhost.py", + ], + visibility = ["//visibility:public"], + deps = [ + "//labgrid:pkg", + ], +) + +py_test( + name = "test", + srcs = ["test.py"], + deps = [":driver"], +) diff --git a/bazel/labgrid/driver/__init__.py b/bazel/labgrid/driver/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..222c54ff5fdf387927c3cea5c482b22174618cf0 --- /dev/null +++ b/bazel/labgrid/driver/__init__.py @@ -0,0 +1 @@ +from .localhost import LocalhostDriver diff --git a/bazel/labgrid/driver/localhost.py b/bazel/labgrid/driver/localhost.py new file mode 100644 index 0000000000000000000000000000000000000000..3eacd46843606365318a11119c2efc71e9ad7f18 --- /dev/null +++ b/bazel/labgrid/driver/localhost.py @@ -0,0 +1,52 @@ +import attr + +from os import linesep +from shutil import copy, copytree +from subprocess import run, PIPE +from pathlib import Path + +from labgrid.factory import target_factory +from labgrid.step import step +from labgrid.driver import Driver +from labgrid.driver.commandmixin import CommandMixin +from labgrid.driver.exception import ExecutionError +from labgrid.protocol import CommandProtocol, FileTransferProtocol + + +@target_factory.reg_driver +@attr.s(eq=False) +class LocalhostDriver(CommandMixin, Driver, CommandProtocol, FileTransferProtocol): + """Driver that runs commands and performs file transfers against the local machine""" + + def get_status(self): + return 1 + + @Driver.check_active + def run(self, cmd, timeout=30.0, codec="utf-8", decodeerrors="strict"): + return self._run(cmd, timeout=timeout, codec=codec, decodeerrors=decodeerrors) + + def _run(self, cmd, *, timeout=30.0, codec="utf-8", decodeerrors="strict"): + process = run(cmd, stdout=PIPE, stderr=PIPE, shell=True, timeout=timeout, encoding=codec) + stdout = process.stdout.rstrip().split(linesep) + stderr = process.stderr.rstrip().split(linesep) + code = process.returncode + return (stdout, stderr, code) + + @Driver.check_active + @step(args=['source', 'destination']) + def put(self, source, destination): + self._copy(source, destination) + + @Driver.check_active + @step(args=['source', 'destination']) + def get(self, source, destination): + self._copy(source, destination) + + def _copy(self, source, destination): + path = Path(source) + if not path.exists(): + raise ExecutionError("File {} doesn't exist".format(path)) + if path.is_dir(): + copytree(source, destination) + else: + copy(source, destination) diff --git a/bazel/labgrid/driver/test.py b/bazel/labgrid/driver/test.py new file mode 100644 index 0000000000000000000000000000000000000000..19f75a205bfc6bbcd8a6223b3b8ef0b07bebd1cf --- /dev/null +++ b/bazel/labgrid/driver/test.py @@ -0,0 +1,10 @@ +from unittest import TestCase, main + + +class DriverTestCase(TestCase): + def test_imports(self): + from bazel.labgrid.driver import LocalhostDriver + + +if __name__ == "__main__": + main() diff --git a/bazel/labgrid/strategy/BUILD.bazel b/bazel/labgrid/strategy/BUILD.bazel index 86a34fd8c4ef5783e946f69d9b914fa1fb242b0f..2ed17721cedbaef4fe6222c06ad4675d9860d4ec 100644 --- a/bazel/labgrid/strategy/BUILD.bazel +++ b/bazel/labgrid/strategy/BUILD.bazel @@ -4,11 +4,13 @@ py_library( name = "strategy", srcs = [ "__init__.py", - "qemu/strategy.py", + "localhost.py", + "qemu.py", "transition.py", ], visibility = ["//visibility:public"], deps = [ + "//bazel/labgrid/driver", "//labgrid:pkg", ], ) diff --git a/bazel/labgrid/strategy/__init__.py b/bazel/labgrid/strategy/__init__.py index f55247258bd49357060cbcfe5f785719f8252dc3..9c22a21df84d10d35c5e90c19424d5b7b877e5d1 100644 --- a/bazel/labgrid/strategy/__init__.py +++ b/bazel/labgrid/strategy/__init__.py @@ -1,2 +1,3 @@ -from .qemu.strategy import QEMUStrategy +from .localhost import LocalhostStrategy +from .qemu import QEMUStrategy from .transition import transition diff --git a/bazel/labgrid/strategy/localhost.py b/bazel/labgrid/strategy/localhost.py new file mode 100644 index 0000000000000000000000000000000000000000..464d39e2f9399f394a6c06f59459e348883a513f --- /dev/null +++ b/bazel/labgrid/strategy/localhost.py @@ -0,0 +1,27 @@ +import enum + +import attr + +from labgrid.factory import target_factory +from labgrid.step import step +from labgrid.strategy import Strategy, StrategyError + + +class Status(enum.Enum): + shell = 1 + + +@target_factory.reg_driver +@attr.s(eq=False) +class LocalhostStrategy(Strategy): + status = attr.ib(default=Status.shell) + + @step() + def transition(self, status, *, step): + if not isinstance(status, Status): + status = Status[status] + if status == Status.shell: + step.skip("localhost is always in shell") + return + else: + raise StrategyError(f"can not transition to {status}") diff --git a/bazel/labgrid/strategy/qemu/strategy.py b/bazel/labgrid/strategy/qemu.py similarity index 100% rename from bazel/labgrid/strategy/qemu/strategy.py rename to bazel/labgrid/strategy/qemu.py diff --git a/bazel/labgrid/strategy/qemu/__init__.py b/bazel/labgrid/strategy/qemu/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/bazel/labgrid/strategy/test.py b/bazel/labgrid/strategy/test.py index 68a3521aa4be0e2657f387f9586c53eb5864287e..37fb4b15a294fae0382162fe76a93e43ad366e4a 100644 --- a/bazel/labgrid/strategy/test.py +++ b/bazel/labgrid/strategy/test.py @@ -1,12 +1,9 @@ -from __future__ import annotations - from unittest import TestCase, main -class QEMUStrategyTest(TestCase): +class StrategyTestCase(TestCase): def test_imports(self): - """Test that strategy is imported correctly""" - from bazel.labgrid.strategy import QEMUStrategy + from bazel.labgrid.strategy import LocalhostStrategy, QEMUStrategy, transition if __name__ == "__main__": diff --git a/constraint/device/BUILD.bazel b/constraint/device/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..52e02701510e3d109954dbca7b81f9a6d53297df --- /dev/null +++ b/constraint/device/BUILD.bazel @@ -0,0 +1,7 @@ +constraint_setting(name = "device") + +constraint_value( + name = "localhost", + constraint_setting = ":device", + visibility = ["//visibility:public"], +) diff --git a/e2e/docker/BUILD.bazel b/e2e/docker/BUILD.bazel index b0904144e867bd5354f4555fe5514041273c9521..0d6bf3709134d4e7eddd680ad42ef3c33962291d 100644 --- a/e2e/docker/BUILD.bazel +++ b/e2e/docker/BUILD.bazel @@ -1,34 +1,23 @@ load("@rules_diff//diff/file/test:defs.bzl", "diff_file_test") load("@rules_labgrid//labgrid/config/toolchain:defs.bzl", "labgrid_config_toolchain") -load("@rules_labgrid//labgrid/genrule:defs.bzl", "labgrid_genrule") load("@rules_labgrid//labgrid/run:defs.bzl", "labgrid_run") -load("@rules_labgrid//labgrid/run/binary:defs.bzl", "labgrid_run_binary") load("@rules_labgrid//labgrid/state:defs.bzl", "labgrid_state") -load("@rules_labgrid//labgrid/test:defs.bzl", "labgrid_test") load("@rules_python//python:defs.bzl", "py_binary") -TAGS = [ - "manual", - "requires-docker", -] - -# A constraint to register the toolchain to constraint_setting(name = "device") -# This value would usually be shared in a common definitions module constraint_value( - name = "constraint", + name = "docker", constraint_setting = ":device", ) -# A platform that describes the Docker "platform" platform( name = "platform", constraint_values = [ - ":constraint", - "@toolchain_utils//toolchain/constraint/cpu:amd64", + ":docker", "@toolchain_utils//toolchain/constraint/os:linux", ], + parents = ["@local_config_platform//:host"], ) labgrid_state( @@ -37,14 +26,12 @@ labgrid_state( final = "gone", ) -# Provide the toolchain with Bazel labgrid_config_toolchain( name = "config", - src = "local-ubuntu.16.04-gnu.yaml", + src = "config.yaml", state = ":docker-state", target_compatible_with = [ - ":constraint", - "@toolchain_utils//toolchain/constraint/cpu:amd64", + ":docker", "@toolchain_utils//toolchain/constraint/os:linux", ], deps = ["@pip//docker"], @@ -56,102 +43,18 @@ py_binary( deps = ["@pip//docker"], ) -py_binary( - name = "cat-with-runfiles", - srcs = ["cat.py"], - main = "cat.py", -) - labgrid_run( - name = "cat", - srcs = [":cat-with-runfiles"], - outs = ["run-on-device-with-runfiles.actual"], - cmd = "$(locations :cat-with-runfiles) /etc/os-release > $@", - platform = ":platform", -) - -labgrid_genrule( - name = "cp", - srcs = ["@ape//ape:cp"], - outs = ["run-on-device-and-transfer-file-back.actual"], - cmd = "$(location @rules_labgrid//labgrid/run) --get output.txt:$@ $(location @ape//ape:cp) /etc/os-release output.txt", + name = "os-release", + srcs = ["@ape//ape:cat"], + outs = ["stdout.log"], + cmd = "$(location @ape//ape:cat) /etc/os-release > $@", platform = ":platform", - tools = ["@rules_labgrid//labgrid/run"], -) - -labgrid_run_binary( - name = "cp_binary", - srcs = [ - "@ape//ape:cp", - ], - outs = ["run-binary-on-device-and-transfer-file-back.actual"], - args = [ - "--get", - "output.txt:$(location run-binary-on-device-and-transfer-file-back.actual)", - "$(location @ape//ape:cp)", - "/etc/os-release", - "output.txt", - ], - platform = ":platform", - tags = TAGS, - tool = "@rules_labgrid//labgrid/run", -) - -[ - diff_file_test( - name = name, - size = "small", - a = ":version.txt", - b = "{}.actual".format(name), - tags = TAGS, - ) - for name in ( - "run-on-device-with-runfiles", - "run-on-device-and-transfer-file-back", - "run-binary-on-device-and-transfer-file-back", - ) -] - -labgrid_genrule( - name = "printenv", - srcs = ["@ape//ape:printenv"], - outs = ["run-on-device-with-env.actual"], - cmd = "$(location @rules_labgrid//labgrid/run) --env HELLO=world -- $(location @ape//ape:printenv) HELLO > $@", - platform = ":platform", - tools = ["@rules_labgrid//labgrid/run"], ) diff_file_test( - name = "run-on-device-with-env", + name = "run", size = "small", - a = ":hello.txt", - b = ":run-on-device-with-env.actual", - tags = TAGS, -) - -py_binary( - name = "inner", - srcs = ["test_os_release.py"], - data = [":version.txt"], - main = "test_os_release.py", - deps = ["@rules_python//python/runfiles"], -) - -labgrid_test( - name = "test-on-device", - src = ":inner", - platform = ":platform", - tags = TAGS, -) - -# FIXME: This currently fails with a concurrency error -test_suite( - name = "test", + a = ":release.txt", + b = ":stdout.log", tags = ["manual"], - tests = [ - ":run-on-device-and-transfer-file-back", - ":run-on-device-with-env", - ":run-on-device-with-runfiles", - ":test-on-device", - ], ) diff --git a/e2e/docker/cat.py b/e2e/docker/cat.py deleted file mode 100644 index 13d94bc0fbde6818a7589a2d84f4aa37bec582eb..0000000000000000000000000000000000000000 --- a/e2e/docker/cat.py +++ /dev/null @@ -1,4 +0,0 @@ -import fileinput - -for line in fileinput.input(files="/etc/os-release"): - print(line, end="") diff --git a/e2e/docker/local-ubuntu.16.04-gnu.yaml b/e2e/docker/config.yaml similarity index 100% rename from e2e/docker/local-ubuntu.16.04-gnu.yaml rename to e2e/docker/config.yaml diff --git a/e2e/docker/version.txt b/e2e/docker/release.txt similarity index 100% rename from e2e/docker/version.txt rename to e2e/docker/release.txt diff --git a/e2e/localhost/BUILD.bazel b/e2e/localhost/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..5a261932413cadd310f5a4034b384e3b617f9637 --- /dev/null +++ b/e2e/localhost/BUILD.bazel @@ -0,0 +1,92 @@ +load("@rules_diff//diff/file/test:defs.bzl", "diff_file_test") +load("@rules_labgrid//labgrid/genrule:defs.bzl", "labgrid_genrule") +load("@rules_labgrid//labgrid/run:defs.bzl", "labgrid_run") +load("@rules_labgrid//labgrid/run/binary:defs.bzl", "labgrid_run_binary") +load("@rules_labgrid//labgrid/test:defs.bzl", "labgrid_test") +load("@rules_python//python:defs.bzl", "py_binary") + +labgrid_run( + name = "hello", + srcs = ["@ape//ape:echo"], + outs = ["run.actual"], + cmd = "$(location @ape//ape:echo) world > $@", + platform = "@rules_labgrid//platform:localhost", +) + +py_binary( + name = "echo-with-runfiles", + srcs = ["echo.py"], + main = "echo.py", +) + +labgrid_run( + name = "hello-with-runfiles", + srcs = [":echo-with-runfiles"], + outs = ["run-with-runfiles.actual"], + cmd = "$(locations :echo-with-runfiles) world > $@", + platform = "@rules_labgrid//platform:localhost", +) + +labgrid_genrule( + name = "hello-and-transfer-file-back", + # We need Bash to redirect to a file on the target + srcs = ["@ape//ape:bash"], + outs = ["run-and-transfer-file-back.actual"], + cmd = "$(location @rules_labgrid//labgrid/run) --get output.txt:$@ $(location @ape//ape:bash) -c 'echo world > output.txt'", + platform = "@rules_labgrid//platform:localhost", + tools = ["@rules_labgrid//labgrid/run"], +) + +labgrid_genrule( + name = "hello-with-env", + srcs = ["@ape//ape:printenv"], + outs = ["run-with-env.actual"], + cmd = "$(location @rules_labgrid//labgrid/run) --env HELLO=world -- $(location @ape//ape:printenv) HELLO > $@", + platform = "@rules_labgrid//platform:localhost", + tools = ["@rules_labgrid//labgrid/run"], +) + +labgrid_run_binary( + name = "hello-binary", + srcs = ["@ape//ape:bash"], + outs = ["run-binary.actual"], + args = [ + "--get", + "output.txt:$(location run-binary.actual)", + "$(location @ape//ape:bash)", + "-c", + "echo world > output.txt", + ], + platform = "@rules_labgrid//platform:localhost", + tool = "@rules_labgrid//labgrid/run", +) + +[ + diff_file_test( + name = name, + size = "small", + a = ":hello.txt", + b = "{}.actual".format(name), + ) + for name in ( + "run", + "run-with-runfiles", + "run-and-transfer-file-back", + "run-with-env", + "run-binary", + ) +] + +py_binary( + name = "inner", + srcs = ["test_hello.py"], + data = [":hello.txt"], + main = "test_hello.py", + deps = ["@rules_python//python/runfiles"], +) + +labgrid_test( + name = "test", + src = ":inner", + platform = "@rules_labgrid//platform:localhost", +) diff --git a/e2e/localhost/echo.py b/e2e/localhost/echo.py new file mode 100644 index 0000000000000000000000000000000000000000..48833b52bb7b4950074556b366dd95c552c1eaf6 --- /dev/null +++ b/e2e/localhost/echo.py @@ -0,0 +1,3 @@ +from sys import argv + +print(*argv[2:]) diff --git a/e2e/docker/hello.txt b/e2e/localhost/hello.txt similarity index 100% rename from e2e/docker/hello.txt rename to e2e/localhost/hello.txt diff --git a/e2e/docker/test_os_release.py b/e2e/localhost/test_hello.py similarity index 56% rename from e2e/docker/test_os_release.py rename to e2e/localhost/test_hello.py index 8928885a8a330e94ab1c91f4c406883feca2a47b..28db6b6e1ddd63ddcc8b8ad38d021385ed3aa4f9 100644 --- a/e2e/docker/test_os_release.py +++ b/e2e/localhost/test_hello.py @@ -3,16 +3,13 @@ from pathlib import Path from python.runfiles import Runfiles -def _cat(path): - return Path(path).read_text() - def _runfile(path): r = Runfiles.Create() return Path(r.Rlocation(path)).read_text() -class OSReleaseTestCase(unittest.TestCase): +class HelloTestCase(unittest.TestCase): def test(self): - self.assertEqual(_cat("/etc/os-release"), _runfile("_main/docker/version.txt")) + self.assertEqual(_runfile("_main/localhost/hello.txt").rstrip(), "world") if __name__ == "__main__": unittest.main() diff --git a/e2e/qemu/BUILD.bazel b/e2e/qemu/BUILD.bazel index d263f87556d15de234195c7d7a6fc9e98a9cff60..cc59a373414fac0b2afc711a3291ea4a9b8d292b 100644 --- a/e2e/qemu/BUILD.bazel +++ b/e2e/qemu/BUILD.bazel @@ -11,7 +11,7 @@ platform( ) labgrid_run( - name = "cat", + name = "os-release", srcs = ["@ape//ape:cat"], outs = ["stdout.log"], cmd = "$(location @ape//ape:cat) /etc/os-release > $@", @@ -19,8 +19,8 @@ labgrid_run( ) diff_file_test( - name = "test", + name = "run", size = "small", - a = ":stdout.log.expected", + a = ":release.txt", b = ":stdout.log", ) diff --git a/e2e/qemu/stdout.log.expected b/e2e/qemu/release.txt similarity index 100% rename from e2e/qemu/stdout.log.expected rename to e2e/qemu/release.txt diff --git a/labgrid/toolchain/config/localhost/BUILD.bazel b/labgrid/toolchain/config/localhost/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..b42a2926a0ad94641cbf5c07afe86828e9726cc0 --- /dev/null +++ b/labgrid/toolchain/config/localhost/BUILD.bazel @@ -0,0 +1,20 @@ +load("//labgrid/config/toolchain:defs.bzl", "labgrid_config_toolchain") +load("//labgrid/state:defs.bzl", "labgrid_state") + +labgrid_state( + name = "state", + desired = "shell", +) + +labgrid_config_toolchain( + name = "localhost", + src = "config.yaml", + state = ":state", + target_compatible_with = [ + "//constraint/device:localhost", + ], + deps = [ + "//bazel/labgrid/driver", + "//bazel/labgrid/strategy", + ], +) diff --git a/labgrid/toolchain/config/localhost/config.yaml b/labgrid/toolchain/config/localhost/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d77b5f108957fec7f3dd023de6fcc127de456767 --- /dev/null +++ b/labgrid/toolchain/config/localhost/config.yaml @@ -0,0 +1,8 @@ +targets: + main: + drivers: + LocalhostDriver: {} + LocalhostStrategy: {} +imports: + - bazel.labgrid.driver + - bazel.labgrid.strategy diff --git a/platform/BUILD.bazel b/platform/BUILD.bazel new file mode 100644 index 0000000000000000000000000000000000000000..2475fefe5fb9b092fcd208eb2ab620865dccb45d --- /dev/null +++ b/platform/BUILD.bazel @@ -0,0 +1,6 @@ +platform( + name = "localhost", + constraint_values = ["//constraint/device:localhost"], + parents = ["@local_config_platform//:host"], + visibility = ["//visibility:public"], +)