Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Minor test improvements #2164

Merged
merged 5 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
99 changes: 67 additions & 32 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,31 +322,28 @@ def wait_for_nginxproxy_to_be_ready():
logging.debug("nginx-proxy ready")
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
- else, if a yaml file exists with the same name as the test module (but for the `.yml` extension), use that
- otherwise use `docker-compose.yml`.
@pytest.fixture
def docker_compose_file(request):
"""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__)
yml_file = os.path.join(test_module_dir, request.module.__name__ + '.yml')
yaml_file = os.path.join(test_module_dir, request.module.__name__ + '.yaml')
default_file = os.path.join(test_module_dir, 'docker-compose.yml')

docker_compose_file_module_variable = getattr(request.module, "docker_compose_file", None)
if docker_compose_file_module_variable is not None:
docker_compose_file = os.path.join( test_module_dir, docker_compose_file_module_variable)
if not os.path.isfile(docker_compose_file):
raise ValueError(f"docker compose file {docker_compose_file!r} could not be found. Check your test module `docker_compose_file` variable value.")
if os.path.isfile(yml_file):
docker_compose_file = yml_file
elif os.path.isfile(yaml_file):
docker_compose_file = yaml_file
else:
if os.path.isfile(yml_file):
docker_compose_file = yml_file
elif os.path.isfile(yaml_file):
docker_compose_file = yaml_file
else:
docker_compose_file = default_file
docker_compose_file = default_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__))
Expand Down Expand Up @@ -419,34 +416,72 @@ def connect_to_all_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
#
###############################################################################


@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
def docker_composer():
with DockerComposer() as d:
yield d


@pytest.fixture
def ca_root_certificate():
return CA_ROOT_CERTIFICATE

A custom docker compose file name can be defined in a variable named `docker_compose_file`.

@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
our container will be attached to all the docker networks.
"""
docker_compose_file = find_docker_compose_file(request)
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
docker_composer.compose(docker_compose_file)
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()
Expand Down
5 changes: 2 additions & 3 deletions test/test_ssl/test_dhparam.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import re
import subprocess
import os

import backoff
import docker
Expand Down Expand Up @@ -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)
# 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"
sut_container = docker_client.containers.get(container_name)
assert sut_container.status == "running"
Expand All @@ -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`.
can_verify_chain_of_trust(
sut_container,
ca_cert = f"{os.getcwd()}/certs/ca-root.crt",
ca_cert = ca_root_certificate,
fqdn = 'web2.nginx-proxy.tld'
)

Expand Down