From 9525bf437dfcccd052129d2bbb114b446d382f6e Mon Sep 17 00:00:00 2001 From: David Brown Date: Fri, 9 Aug 2024 11:31:03 +0000 Subject: [PATCH 1/2] test: move `docker` folder to `docker_test` labgrid_genrule was clashing namepsaces on the docker python library during `import docker` if the folder was also named `docker` --- e2e/{docker => docker_test}/BUILD.bazel | 0 e2e/{docker => docker_test}/local-ubuntu.16.04-gnu.yaml | 0 e2e/{docker => docker_test}/manager.py | 3 ++- e2e/{docker => docker_test}/ssh.py | 0 e2e/{docker => docker_test}/version.txt | 0 5 files changed, 2 insertions(+), 1 deletion(-) rename e2e/{docker => docker_test}/BUILD.bazel (100%) rename e2e/{docker => docker_test}/local-ubuntu.16.04-gnu.yaml (100%) rename e2e/{docker => docker_test}/manager.py (75%) rename e2e/{docker => docker_test}/ssh.py (100%) rename e2e/{docker => docker_test}/version.txt (100%) diff --git a/e2e/docker/BUILD.bazel b/e2e/docker_test/BUILD.bazel similarity index 100% rename from e2e/docker/BUILD.bazel rename to e2e/docker_test/BUILD.bazel diff --git a/e2e/docker/local-ubuntu.16.04-gnu.yaml b/e2e/docker_test/local-ubuntu.16.04-gnu.yaml similarity index 100% rename from e2e/docker/local-ubuntu.16.04-gnu.yaml rename to e2e/docker_test/local-ubuntu.16.04-gnu.yaml diff --git a/e2e/docker/manager.py b/e2e/docker_test/manager.py similarity index 75% rename from e2e/docker/manager.py rename to e2e/docker_test/manager.py index cca44f05..9493eb11 100644 --- a/e2e/docker/manager.py +++ b/e2e/docker_test/manager.py @@ -4,6 +4,7 @@ from contextlib import contextmanager from typing import Iterator from python.runfiles import Runfiles +from os import environ from labgrid.executor.manager import Data, Manager @@ -11,6 +12,6 @@ from labgrid.executor.manager import Data, Manager @contextmanager def manager() -> Iterator[Run]: runfiles = Runfiles.Create() - config = runfiles.Rlocation("_main/docker/local-ubuntu.16.04-gnu.yaml") + config = runfiles.Rlocation("_main/docker_test/local-ubuntu.16.04-gnu.yaml") env = {"LG_ENV": config} yield Data(env=env) diff --git a/e2e/docker/ssh.py b/e2e/docker_test/ssh.py similarity index 100% rename from e2e/docker/ssh.py rename to e2e/docker_test/ssh.py diff --git a/e2e/docker/version.txt b/e2e/docker_test/version.txt similarity index 100% rename from e2e/docker/version.txt rename to e2e/docker_test/version.txt -- GitLab From 1e02dc545f499796d5360a762fa9d61e611f6d2d Mon Sep 17 00:00:00 2001 From: David Brown Date: Fri, 9 Aug 2024 14:18:10 +0000 Subject: [PATCH 2/2] test: exmaple pytest + labgrid test Uses docker as the 'device' under test (all I had available) Has a py_binary (pytest_exmaple.py) that launches pytest with the passed into LG_ENV variable and runs all tests available in the file Uses a small sh_test target 'pytest_report' to parse the result of running pytest and propogate errors as well as the JUNIT XML file Run with: bazelisk test docker_test:pytest_report --- e2e/MODULE.bazel | 9 ++++++++ e2e/docker_test/BUILD.bazel | 35 ++++++++++++++++++++++++++++++- e2e/docker_test/pytest_example.py | 32 ++++++++++++++++++++++++++++ e2e/docker_test/pytest_report.sh | 20 ++++++++++++++++++ e2e/python/requirements.in | 1 + e2e/python/requirements.txt | 14 +++++++++++++ 6 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 e2e/docker_test/pytest_example.py create mode 100755 e2e/docker_test/pytest_report.sh create mode 100644 e2e/python/requirements.in create mode 100644 e2e/python/requirements.txt diff --git a/e2e/MODULE.bazel b/e2e/MODULE.bazel index 5c468eec..966693d5 100644 --- a/e2e/MODULE.bazel +++ b/e2e/MODULE.bazel @@ -30,3 +30,12 @@ dev.toolchain( ignore_root_user_error = True, python_version = "3.11", ) + +# Download PyPI dependencies +pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") +pip.parse( + hub_name = "pip_hub", + python_version = "3.11", + requirements_lock = "//python:requirements.txt", +) +use_repo(pip, "pip_hub") \ No newline at end of file diff --git a/e2e/docker_test/BUILD.bazel b/e2e/docker_test/BUILD.bazel index cc34f9a0..47e9b82f 100644 --- a/e2e/docker_test/BUILD.bazel +++ b/e2e/docker_test/BUILD.bazel @@ -24,7 +24,16 @@ py_binary( args = ["--lg-env=$(location local-ubuntu.16.04-gnu.yaml)"], data = ["local-ubuntu.16.04-gnu.yaml"], tags = ["manual"], - deps = ["@rules_labgrid//labgrid/python"], + deps = ["@rules_labgrid//labgrid/python", "@pip_hub//pytest"], +) + +py_binary( + name = "pytest_example", + srcs = ["pytest_example.py"], + args = ["--lg-env=$(location local-ubuntu.16.04-gnu.yaml)"], + data = ["local-ubuntu.16.04-gnu.yaml"], + tags = ["manual"], + deps = ["@rules_labgrid//labgrid/python", "@pip_hub//pytest"], ) # An execution manager that is responsible for setting up the LabGrid environment @@ -90,6 +99,14 @@ labgrid_genrule( tools = [":ssh"], ) +labgrid_genrule( + name = "run_pytest", + outs = ["pytest.log", "pytest.xml"], + cmd = "JUNIT=$(execpath pytest.xml) $(location :pytest_example) > $(execpath pytest.log)", + tags = ["manual"], + tools = [":pytest_example"], +) + # Transition the above `genrule` to the Docker platform labgrid_transition( name = "transition", @@ -98,6 +115,13 @@ labgrid_transition( tags = ["manual"], ) +labgrid_transition( + name = "pytest_transition", + srcs = [":pytest.xml"], + platforms = [":platform"], + tags = ["manual"], +) + # Check that the output of `/proc/version` from within the container is what we expect diff_file_test( name = "test", @@ -106,3 +130,12 @@ diff_file_test( b = ":transition", tags = ["manual"], ) + +# Shell test rule that simply moves the result of pytest into expected XML location and propogates a failure code if needed +sh_test( + name = "pytest_report", + size = "small", + args = ["$(location :pytest_transition)"], + srcs = ["pytest_report.sh"], + data = [":pytest_transition"] +) \ No newline at end of file diff --git a/e2e/docker_test/pytest_example.py b/e2e/docker_test/pytest_example.py new file mode 100644 index 00000000..8265812e --- /dev/null +++ b/e2e/docker_test/pytest_example.py @@ -0,0 +1,32 @@ +from __future__ import annotations + +from labgrid.target import Target +from labgrid.protocol import CommandProtocol + +import pytest +import logging +from typing import Iterator +from os import environ + + +# Get the docker image into a correct state (not a fan of having +# to know that we're working with Docker here, but probably not a problem +# for the real system) +@pytest.fixture(scope='session') +def shell_cmd(target: Target) -> Iterator[CommandProtocol]: + strategy = target.get_driver('DockerStrategy') + strategy.transition("accessible") + shell = target.get_driver('CommandProtocol') + return shell + +# Simplest of checks over the command protocal +def test_uname_system(shell_cmd: CommandProtocol): + result = '\n'.join(shell_cmd.run_check("grep VERSION= /etc/os-release")) + logging.info(result) + assert 'VERSION="16.04.4 LTS (Xenial Xerus)"' == result + +if __name__ == "__main__": + f = environ.get("LG_ENV") + junit = environ.get("JUNIT") + pytest.main([__file__, f"--lg-env={f}", f"--junit-xml={junit}"]) + diff --git a/e2e/docker_test/pytest_report.sh b/e2e/docker_test/pytest_report.sh new file mode 100755 index 00000000..e87c764f --- /dev/null +++ b/e2e/docker_test/pytest_report.sh @@ -0,0 +1,20 @@ +# Copy the JUNIT to where Bazel expects it +cp $1 $XML_OUTPUT_FILE + +# Check for failures in the XML +grep failures=\"0\" $1 > /dev/null +fail_check=$? + +# Check for errors in the XML +grep errors=\"0\" $1 > /dev/null +error_check=$? + +if [ $fail_check -ne 0 ] || [ $error_check -ne 0] +then + echo "Failures found in pytest XML log" + cat $1 + exit 1 +fi + +# All is good! +exit 0 \ No newline at end of file diff --git a/e2e/python/requirements.in b/e2e/python/requirements.in new file mode 100644 index 00000000..35663079 --- /dev/null +++ b/e2e/python/requirements.in @@ -0,0 +1 @@ +pytest==8.3.2 \ No newline at end of file diff --git a/e2e/python/requirements.txt b/e2e/python/requirements.txt new file mode 100644 index 00000000..9f65a494 --- /dev/null +++ b/e2e/python/requirements.txt @@ -0,0 +1,14 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile +# +iniconfig==2.0.0 + # via pytest +packaging==24.1 + # via pytest +pluggy==1.5.0 + # via pytest +pytest==8.3.2 + # via -r requirements.in -- GitLab