This is an automated email from the ASF dual-hosted git repository. tvb pushed a commit to branch tristan/add-docker-tests in repository https://gitbox.apache.org/repos/asf/buildstream-plugins.git
commit dc58cdfe06ffa49ea050bdd2bc6551310c78ec52 Author: Tristan van Berkom <[email protected]> AuthorDate: Mon Apr 25 20:05:03 2022 +0900 tests/sources/docker.py: Adding docker source test --- requirements/test-requirements.txt | 2 +- tests/sources/docker.py | 126 +++++++++++++++++++++ tests/sources/docker/elements/dockerhub-alpine.bst | 8 ++ tests/sources/docker/project.conf | 17 +++ 4 files changed, 152 insertions(+), 1 deletion(-) diff --git a/requirements/test-requirements.txt b/requirements/test-requirements.txt index ff91d56..3629ba7 100644 --- a/requirements/test-requirements.txt +++ b/requirements/test-requirements.txt @@ -6,4 +6,4 @@ pytest-datafiles >= 2.0 pylint pycodestyle pyftpdlib - +responses diff --git a/tests/sources/docker.py b/tests/sources/docker.py new file mode 100644 index 0000000..77da45c --- /dev/null +++ b/tests/sources/docker.py @@ -0,0 +1,126 @@ +import os + +from buildstream.exceptions import ErrorDomain +from buildstream._testing import cli # pylint: disable=unused-import +import pytest +import responses +from ruamel.yaml import YAML + +DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "docker") + +# Pylint and responses don't play well together +# pylint: disable=no-member + +def create_element(yaml, element_name, element_payload, project): + with open( + os.path.join(project, "elements", element_name), "w", encoding="utf-8" + ) as element_handle: + yaml.dump(element_payload, element_handle) + + [email protected](DATA_DIR) +def test_docker_fetch(cli, datafiles): + project = os.path.join(datafiles.dirname, datafiles.basename) + result = cli.run( + project=project, args=["source", "fetch", "dockerhub-alpine.bst"] + ) + result.assert_success() + + [email protected](DATA_DIR) +def test_docker_source_checkout(cli, datafiles): + project = os.path.join(datafiles.dirname, datafiles.basename) + checkout = os.path.join(cli.directory, "checkout") + result = cli.run( + project=project, + args=[ + "source", + "checkout", + "--directory", + checkout, + "dockerhub-alpine.bst", + ], + ) + result.assert_success() + # Rather than make assertions about the whole Alpine Linux image, verify + # that the /etc/os-release file exists as a sanity check. + assert os.path.isfile( + os.path.join(checkout, "dockerhub-alpine/etc/os-release") + ) + + [email protected](DATA_DIR) [email protected] +def test_handle_network_error(cli, datafiles): + # allow manifest to be fetched + responses.add_passthru( + "https://registry.hub.docker.com/v2/library/alpine/manifests/" + "sha256%3A4b8ffaaa896d40622ac10dc6662204f429f1c8c5714be62a6493a7895f66409" + ) + # allow authentication to go through + responses.add_passthru( + "https://auth.docker.io/" + "token?service=registry.docker.io&scope=repository:library/alpine:pull" + ) + # By not adding a rule for the blob, accessing + # "https://registry.hub.docker.com/v2/" \ + # "library/alpine/blobs/sha256%3Ab56ae66c29370df48e7377c8f9baa744a3958058a766793f821dadcb144a4647" + # will throw a `ConnectionError`. + + # attempt to fetch source + project = os.path.join(datafiles.dirname, datafiles.basename) + result = cli.run( + project=project, args=["source", "fetch", "dockerhub-alpine.bst"] + ) + # check that error is thrown + result.assert_task_error(ErrorDomain.SOURCE, None) + + # check that BuildStream still runs normally + result = cli.run(project=project, args=["show", "dockerhub-alpine.bst"]) + result.assert_success() + + [email protected](DATA_DIR) +def test_fetch_duplicate_layers(cli, datafiles): + # test that fetching a layer twice does not break the mirror directory + + project = str(datafiles) + yaml = YAML() + yaml.default_flow_style = False + + # images to pull + alpine_element = "alpine.bst" + alpine310 = { + "kind": "import", + "sources": [ + {"kind": "docker", "image": "library/alpine", "track": "3.10"} + ], + } + create_element(yaml, alpine_element, alpine310, project) + cli.run( + project=project, args=["source", "track", alpine_element] + ).assert_success() + cli.run( + project=project, args=["source", "fetch", alpine_element] + ).assert_success() + + # this image uses alpine3:10 as base a base layer + # shared layer has digest 03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0 + python36_element = "python36.bst" + python36_alpine310 = { + "kind": "import", + "sources": [ + { + "kind": "docker", + "image": "library/python", + "track": "3.6-alpine3.10", + } + ], + } + create_element(yaml, python36_element, python36_alpine310, project) + cli.run( + project=project, args=["source", "track", python36_element] + ).assert_success() + cli.run( + project=project, args=["source", "fetch", python36_element] + ).assert_success() diff --git a/tests/sources/docker/elements/dockerhub-alpine.bst b/tests/sources/docker/elements/dockerhub-alpine.bst new file mode 100644 index 0000000..3513087 --- /dev/null +++ b/tests/sources/docker/elements/dockerhub-alpine.bst @@ -0,0 +1,8 @@ +kind: import +description: Import an Alpine Linux image from Docker hub + +sources: +- kind: docker + image: library/alpine + track: latest + ref: 4b8ffaaa896d40622ac10dc6662204f429f1c8c5714be62a6493a7895f664098 diff --git a/tests/sources/docker/project.conf b/tests/sources/docker/project.conf new file mode 100644 index 0000000..f425a67 --- /dev/null +++ b/tests/sources/docker/project.conf @@ -0,0 +1,17 @@ +name: test +min-version: 2.0 +element-path: elements +plugins: +- origin: pip + package-name: buildstream-plugins + sources: + - docker +aliases: + alpine: https://bst-integration-test-images.ams3.cdn.digitaloceanspaces.com/ +options: + arch: + type: arch + description: Current architecture + values: + - x86-64 + - aarch64
