Package: pytest-docker-registry-fixtures
pytest-docker-registry-fixturesOverviewPytest fixtures to instantiate and populated local docker registries, usinglovely-pytest-dockeranddocker-py, for testing.Getting StartedUpdatesetup.pyto include:fromdistutils.coreimportsetupsetup(tests_require=["pytest-docker-registry-fixtures"])All fixtures should be automatically included via thepytest11entry point.importrequestsimportpytestfrompytest_docker_registry_fixturesimportDockerRegistryInsecure,DockerRegistrySecure# Optional, for typing@pytest.mark.push_image("busybox:1.30.1","alpine")deftest_docker_registry_secure(docker_registry_secure:DockerRegistrySecure):response=requests.head(f"https://{docker_registry_secure.endpoint}/v2/",headers=docker_registry_secure.auth_header,verify=str(docker_registry_secure.cacerts),)assertresponse.status_code==200deftest_docker_registry_insecure(docker_registry_insecure:DockerRegistryInsecure):response=requests.head(f"http://{docker_registry_insecure.endpoint}/v2/")assertresponse.status_code==200Thepush_imagemark can optionally be added to stage images in the registry prior to testing. SeeMarkersfor details.InstallationFrompypi.org$ pip install pytest_docker_registry_fixturesFrom source code$gitclonehttps://github.com/crashvb/pytest-docker-registry-fixtures
$cdpytest-docker-registry-fixtures
$virtualenvenv
$sourceenv/bin/activate
$python-mpipinstall--editable.[dev]Fixturesdocker_clientCreates a Docker client using configuration values from environment variables. This fixture is used to replicate images into a registry.fromdockerimportDockerClientdeftest_docker_pull(docker_client:DockerClient):image=docker_client.image.pull("busybox:1.30.1")docker_registry_auth_headerRetrieves an HTTP basic authentication header that is populated with credentials that can access the secure docker registry service. The credentials are retrieved from thedocker_registry_passwordanddocker_registry_usernamefixtures. This fixture is used to replicate docker images into the secure docker registry service.docker_registry_cacertsLocates a user-defined CA trust store (tests/cacerts) to use to verify connections to the secure docker registry service. If one cannot be located, a temporary trust store is created containing certificates fromcertifiand thedocker_registry_certsfixture. This fixture is used to instantiate the secure docker registry service.docker_registry_certsReturns the paths of the self-signed certificate authority certificate, certificate, and private key that are used by the secure docker registry service. This fixture is used to instantiate the secure docker registry service.NamedTuple FieldsThe following fields are defined in the tuple provided by this fixture:ca_certificate- Path to the self-signed certificate authority certificate.ca_private_key- Path to the self-signed certificate authority private key.certificate- Path to the certificate.private_key- Path to the private key.Typing is provided bypytest_docker_registry_fixtures.DockerRegistryCerts.docker_registry_htpasswdProvides the path to a htpasswd file that is used by the secure docker registry service. If a user-defined htpasswd file (tests/htpasswd) can be located, it is used. Otherwise, a temporary htpasswd file is created using credentials from thedocker_registry_passwordanddocker_registry_usernamefixtures. This fixture is used to instantiate the secure docker registry service.docker_registry_insecureConfigures and instantiates a docker registry without TLS or authentication.importrequestsfrompytest_docker_registry_fixturesimportDockerRegistryInsecure# Optional, for typingdeftest_docker_registry_insecure(docker_registry_insecure:DockerRegistryInsecure):forimage_nameindocker_registry_insecure.images:response=requests.head(f"http://{docker_registry_insecure.endpoint}/v2/{image_name.image}/manifests/{image_name.tag}",)assertresponse.status_code==200assert"Docker-Content-Digest"inresponse.headersNamedTuple FieldsThe following fields are defined in the tuple provided by this fixture:docker_client- fromdocker_clientdocker_compose- Path to the fully instantiated docker-compose configuration.endpoint- Endpoint of the insecure docker registry service.endpoint_name- Endpoint of the insecure docker registry service, by service name.images- List of images that were replicated into the insecure docker registry service.service_name- Name of the service within the docker-compose configuration.Typing is provided bypytest_docker_registry_fixtures.DockerRegistryInsecure.docker_registry_passwordProvides a generated password to use for authentication to the secure docker registry service. This fixture is used to replicate docker images into the secure docker registry service.docker_registry_secureConfigures and instantiates a TLS enabled docker registry with HTTP basic authorization.importrequestsfrompytest_docker_registry_fixturesimportDockerRegistrySecure# Optional, for typingdeftest_docker_registry_secure(docker_registry_secure:DockerRegistrySecure):forimage_nameindocker_registry_secure.images:response=requests.head(f"https://{docker_registry_secure.endpoint}/v2/{image_name.image}/manifests/{image_name.tag}",headers=docker_registry_secure.auth_header,verify=str(docker_registry_secure.cacerts),)assertresponse.status_code==200assert"Docker-Content-Digest"inresponse.headersNamedTuple FieldsThe following fields are defined in the tuple provided by this fixture:auth_header- fromdocker_registry_auth_header.cacerts- fromdocker_registry_cacerts.certs- fromdocker_registry_certs.docker_client- Docker client, fromdocker_client, with injected authentication credentials for the secure docker registry service.docker_compose- Path to the fully instantiated docker-compose configuration.endpoint- Endpoint of the secure docker registry service.endpoint_name- Endpoint of the secure docker registry service, by service name.htpasswd- fromdocker_registry_htpasswdimages- List of images that were replicated into the secure docker registry service.password- fromdocker_registry_password.service_name- Name of the service within the docker-compose configuration.ssl_context- fromdocker_registry_ssl_context.username- fromdocker_registry_username.Typing is provided bypytest_docker_registry_fixtures.DockerRegistrySecure.docker_registry_ssl_contextProvides an SSL context containing the CA trust store from thedocker_registry_cacertsfixture. This fixture is used to instantiate the secure docker registry service.docker_registry_usernameProvides a generated username to use for authentication to the secure docker registry service. This fixture is used to replicate docker images into the secure docker registry service.pdrf_docker_compose_insecureThis fixture uses thedocker_compose_filesfixture to locate a user-defined docker-compose configuration file (typicallytests/docker-compose.yml) that contains thepytest-docker-registry-insecureservice. If one cannot be located, an embedded configuration is copied to a temporary location and returned. This fixture is used to instantiate the insecure docker registry service.pdrf_docker_compose_secureThis fixture uses thedocker_compose_filesfixture to locate a user-defined docker-compose configuration file (typicallytests/docker-compose.yml) that contains thepytest-docker-registry-secureservice. If one cannot be located, an embedded configuration is copied to a temporary location and returned. This fixture is used to instantiate the secure docker registry service; however, unlike the configuration returned by thepdrf_docker_compose_insecurefixture, this configuration will be treated as a template; the$PATH_CERTIFICATE,$PATH_HTPASSWD, and$PATH_KEYtokens will be populated with the absolute paths provided by thedocker_registry_certsanddocker_registry_htpasswdfixtures, as appropriate.Markerspytest.mark.push_imageThis marker specifies the docker image name(s) that should be replicated to the docker registry service(s) prior to testing. It can ...... decorate individual tests:importpytestfrompytest_docker_registry_fixturesimportDockerRegistrySecure# Optional, for typing@pytest.mark.push_image("busybox:1.30.1","alpine","python,mysql:latest")deftest_docker_registry_secure(docker_registry_secure:DockerRegistrySecure):...... be specified in thepytestmarklist at the module level:#!/usr/bin/env pythonimportpytestpytestmark=[pytest.mark.push_image("busybox:1.30.1","alpine","python,mysql:latest")]...... or be provided via the corresponding--push-imagecommand-line argument:python-mpytest--push-imagebusybox:1.30.1--push-imagealpine--push-imagepython,mysql:latest...This marker supports being specified multiple times, and removes duplicate image names (seeLimitationsbelow).A helper function,get_pushed_images, is included for test scenarios that  wish to inspect the maker directly:importpytestfrompytest_docker_registry_fixturesimportDockerRegistrySecure,get_pushed_images,ImageName@pytest.mark.push_image("busybox:1.30.1")deftest_docker_registry_secure(docker_registry_secure:DockerRegistrySecure,request):image_name=ImageName.parse(get_pushed_images(request)[0])Enumerated FixturesIt is possible to instantiate multiple registry instances using the corresponding enumerated fixtures. Allfixtureslisted above have _*list(e.g.docker_registry_secure->docker_registry_secure_list) versions that will return enumerated lists of corresponding data type.For example:importrequestsfromtypingimportList# Optional, for typingfrompytest_docker_registry_fixturesimportDockerRegistrySecure# Optional, for typingdeftest_docker_registry_secure_list(docker_registry_secure_list:List[DockerRegistrySecure]):fordocker_registry_secureindocker_registry_secure_list:forimage_nameindocker_registry_secure.images:response=requests.head(f"https://{docker_registry_secure.endpoint}/v2/{image_name.image}/manifests/{image_name.tag}",headers=docker_registry_secure.auth_header,verify=str(docker_registry_secure.cacerts),)assertresponse.status_code==200assert"Docker-Content-Digest"inresponse.headersIt is possible to use both singular and enumerated fixtures within the same test context; however, the same values will be returned for the singular fixture as the first enumerated list value (i.e. docker_registry_secure == docker_registry_secure_list[0]). To avoid complications with lower layers, mainly docker-compose, and to allow for this interchangeability, caching is used internally.By default, the scale factor of the enumerated instances is set to one (n=1). This value can be changed by overriding thepdrf_scale_factorfixture, as follows:importpytest@pytest.fixture(scope="session")defpdrf_scale_factor()->int:return4This fixture will be used to scale both the insecure and secure docker registries.LimitationsAll the fixtures provided by this package aresessionscoped; and will only be executed once per test execution.Thepush_imagemarker is processed as part of thedocker_registry_insecureanddocker_registry_securefixtures. As such:allmarkers will be aggregated during initialization of the session, and processed prior test execution.Pushed images will be replicated to both the insecure and secure docker registries, if both are instantiated.A working docker client is required to push images.At most 10 insecure and 10 secure docker registries are supported using the embedded docker compose.It is not currently possible to specify into which enumerated registry instances images should be replicated. As such, and for backwards compatibility, they will only be replicated into the first instance of each of the insecure and secure docker registries.DevelopmentSource Control