1
0
mirror of https://github.com/thib8956/nginx-proxy synced 2025-02-24 09:48:14 +00:00

Merge pull request #2164 from rhansen/tests

chore: minor test improvements
This commit is contained in:
Nicolas Duchon 2023-02-28 08:49:12 +01:00 committed by GitHub
commit 6e9d46e672
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 36 deletions

View File

@ -322,31 +322,28 @@ def wait_for_nginxproxy_to_be_ready():
logging.debug("nginx-proxy ready") logging.debug("nginx-proxy ready")
break break
def find_docker_compose_file(request):
"""
helper for fixture functions to figure out the name of the docker-compose file to consider.
- if the test module provides a `docker_compose_file` variable, take that @pytest.fixture
- else, if a yaml file exists with the same name as the test module (but for the `.yml` extension), use that def docker_compose_file(request):
- otherwise use `docker-compose.yml`. """Fixture naming the docker-compose file to consider.
If a YAML file exists with the same name as the test module (with the `.py` extension replaced
with `.yml` or `.yaml`), use that. Otherwise, use `docker-compose.yml` in the same directory
as the test module.
Tests can override this fixture to specify a custom location.
""" """
test_module_dir = os.path.dirname(request.module.__file__) test_module_dir = os.path.dirname(request.module.__file__)
yml_file = os.path.join(test_module_dir, request.module.__name__ + '.yml') yml_file = os.path.join(test_module_dir, request.module.__name__ + '.yml')
yaml_file = os.path.join(test_module_dir, request.module.__name__ + '.yaml') yaml_file = os.path.join(test_module_dir, request.module.__name__ + '.yaml')
default_file = os.path.join(test_module_dir, 'docker-compose.yml') default_file = os.path.join(test_module_dir, 'docker-compose.yml')
docker_compose_file_module_variable = getattr(request.module, "docker_compose_file", None) if os.path.isfile(yml_file):
if docker_compose_file_module_variable is not None: docker_compose_file = yml_file
docker_compose_file = os.path.join( test_module_dir, docker_compose_file_module_variable) elif os.path.isfile(yaml_file):
if not os.path.isfile(docker_compose_file): docker_compose_file = yaml_file
raise ValueError(f"docker compose file {docker_compose_file!r} could not be found. Check your test module `docker_compose_file` variable value.")
else: else:
if os.path.isfile(yml_file): docker_compose_file = default_file
docker_compose_file = yml_file
elif os.path.isfile(yaml_file):
docker_compose_file = yaml_file
else:
docker_compose_file = default_file
if not os.path.isfile(docker_compose_file): if not os.path.isfile(docker_compose_file):
logging.error("Could not find any docker-compose file named either '{0}.yml', '{0}.yaml' or 'docker-compose.yml'".format(request.module.__name__)) logging.error("Could not find any docker-compose file named either '{0}.yml', '{0}.yaml' or 'docker-compose.yml'".format(request.module.__name__))
@ -419,34 +416,72 @@ def connect_to_all_networks():
return [connect_to_network(network) for network in networks] return [connect_to_network(network) for network in networks]
class DockerComposer(contextlib.AbstractContextManager):
def __init__(self):
self._docker_compose_file = None
def __exit__(self, *exc_info):
self._down()
def _down(self):
if self._docker_compose_file is None:
return
for network in self._networks:
disconnect_from_network(network)
docker_compose_down(self._docker_compose_file)
self._docker_compose_file = None
def compose(self, docker_compose_file):
if docker_compose_file == self._docker_compose_file:
return
self._down()
if docker_compose_file is None:
return
remove_all_containers()
docker_compose_up(docker_compose_file)
self._networks = connect_to_all_networks()
wait_for_nginxproxy_to_be_ready()
time.sleep(3) # give time to containers to be ready
self._docker_compose_file = docker_compose_file
############################################################################### ###############################################################################
# #
# Py.test fixtures # Py.test fixtures
# #
############################################################################### ###############################################################################
@pytest.fixture(scope="module")
def docker_compose(request):
"""
pytest fixture providing containers described in a docker compose file. After the tests, remove the created containers
A custom docker compose file name can be defined in a variable named `docker_compose_file`. @pytest.fixture(scope="module")
def docker_composer():
with DockerComposer() as d:
yield d
@pytest.fixture
def ca_root_certificate():
return CA_ROOT_CERTIFICATE
@pytest.fixture
def monkey_patched_dns():
original_dns_resolver = monkey_patch_urllib_dns_resolver()
yield
restore_urllib_dns_resolver(original_dns_resolver)
@pytest.fixture
def docker_compose(monkey_patched_dns, docker_composer, docker_compose_file):
"""Ensures containers described in a docker compose file are started.
A custom docker compose file name can be specified by overriding the `docker_compose_file`
fixture.
Also, in the case where pytest is running from a docker container, this fixture makes sure Also, in the case where pytest is running from a docker container, this fixture makes sure
our container will be attached to all the docker networks. our container will be attached to all the docker networks.
""" """
docker_compose_file = find_docker_compose_file(request) docker_composer.compose(docker_compose_file)
original_dns_resolver = monkey_patch_urllib_dns_resolver()
remove_all_containers()
docker_compose_up(docker_compose_file)
networks = connect_to_all_networks()
wait_for_nginxproxy_to_be_ready()
time.sleep(3) # give time to containers to be ready
yield docker_client yield docker_client
for network in networks:
disconnect_from_network(network)
docker_compose_down(docker_compose_file)
restore_urllib_dns_resolver(original_dns_resolver)
@pytest.fixture() @pytest.fixture()

View File

@ -1,6 +1,5 @@
import re import re
import subprocess import subprocess
import os
import backoff import backoff
import docker import docker
@ -219,7 +218,7 @@ def test_custom_dhparam_is_supported(docker_compose):
# Only `web2` has a site-specific DH param file (which overrides all other DH config) # Only `web2` has a site-specific DH param file (which overrides all other DH config)
# Other tests here use `web5` explicitly, or implicitly (via ENV `DEFAULT_HOST`, otherwise first HTTPS server) # Other tests here use `web5` explicitly, or implicitly (via ENV `DEFAULT_HOST`, otherwise first HTTPS server)
def test_custom_dhparam_is_supported_per_site(docker_compose): def test_custom_dhparam_is_supported_per_site(docker_compose, ca_root_certificate):
container_name="dh-file" container_name="dh-file"
sut_container = docker_client.containers.get(container_name) sut_container = docker_client.containers.get(container_name)
assert sut_container.status == "running" assert sut_container.status == "running"
@ -242,7 +241,7 @@ def test_custom_dhparam_is_supported_per_site(docker_compose):
# - `web2` has it's own cert provisioned at `/etc/nginx/certs/web2.nginx-proxy.tld.crt`. # - `web2` has it's own cert provisioned at `/etc/nginx/certs/web2.nginx-proxy.tld.crt`.
can_verify_chain_of_trust( can_verify_chain_of_trust(
sut_container, sut_container,
ca_cert = f"{os.getcwd()}/certs/ca-root.crt", ca_cert = ca_root_certificate,
fqdn = 'web2.nginx-proxy.tld' fqdn = 'web2.nginx-proxy.tld'
) )