diff options
Diffstat (limited to 'certbot-ci/certbot_integration_tests/certbot_tests/context.py')
-rw-r--r-- | certbot-ci/certbot_integration_tests/certbot_tests/context.py | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/certbot-ci/certbot_integration_tests/certbot_tests/context.py b/certbot-ci/certbot_integration_tests/certbot_tests/context.py new file mode 100644 index 000000000..6f8670000 --- /dev/null +++ b/certbot-ci/certbot_integration_tests/certbot_tests/context.py @@ -0,0 +1,83 @@ +"""Module to handle the context of integration tests.""" +import logging +import os +import shutil +import sys +import tempfile + +from certbot_integration_tests.utils import certbot_call + + +class IntegrationTestsContext(object): + """General fixture describing a certbot integration tests context""" + def __init__(self, request): + self.request = request + + if hasattr(request.config, 'slaveinput'): # Worker node + self.worker_id = request.config.slaveinput['slaveid'] + acme_xdist = request.config.slaveinput['acme_xdist'] + else: # Primary node + self.worker_id = 'primary' + acme_xdist = request.config.acme_xdist + + self.acme_server = acme_xdist['acme_server'] + self.directory_url = acme_xdist['directory_url'] + self.tls_alpn_01_port = acme_xdist['https_port'][self.worker_id] + self.http_01_port = acme_xdist['http_port'][self.worker_id] + self.other_port = acme_xdist['other_port'][self.worker_id] + # Challtestsrv REST API, that exposes entrypoints to register new DNS entries, + # is listening on challtestsrv_port. + self.challtestsrv_port = acme_xdist['challtestsrv_port'] + + self.workspace = tempfile.mkdtemp() + self.config_dir = os.path.join(self.workspace, 'conf') + + probe = tempfile.mkstemp(dir=self.workspace) + os.close(probe[0]) + self.hook_probe = probe[1] + + self.manual_dns_auth_hook = ( + '{0} -c "import os; import requests; import json; ' + "assert not os.environ.get('CERTBOT_DOMAIN').startswith('fail'); " + "data = {{'host':'_acme-challenge.{{0}}.'.format(os.environ.get('CERTBOT_DOMAIN'))," + "'value':os.environ.get('CERTBOT_VALIDATION')}}; " + "request = requests.post('http://localhost:{1}/set-txt', data=json.dumps(data)); " + "request.raise_for_status(); " + '"' + ).format(sys.executable, self.challtestsrv_port) + self.manual_dns_cleanup_hook = ( + '{0} -c "import os; import requests; import json; ' + "data = {{'host':'_acme-challenge.{{0}}.'.format(os.environ.get('CERTBOT_DOMAIN'))}}; " + "request = requests.post('http://localhost:{1}/clear-txt', data=json.dumps(data)); " + "request.raise_for_status(); " + '"' + ).format(sys.executable, self.challtestsrv_port) + + def cleanup(self): + """Cleanup the integration test context.""" + shutil.rmtree(self.workspace) + + def certbot(self, args, force_renew=True): + """ + Execute certbot with given args, not renewing certificates by default. + :param args: args to pass to certbot + :param force_renew: set to False to not renew by default + :return: output of certbot execution + """ + command = ['--authenticator', 'standalone', '--installer', 'null'] + command.extend(args) + return certbot_call.certbot_test( + command, self.directory_url, self.http_01_port, self.tls_alpn_01_port, + self.config_dir, self.workspace, force_renew=force_renew) + + def get_domain(self, subdomain='le'): + """ + Generate a certificate domain name suitable for distributed certbot integration tests. + This is a requirement to let the distribution know how to redirect the challenge check + from the ACME server to the relevant pytest-xdist worker. This resolution is done by + appending the pytest worker id to the subdomain, using this pattern: + {subdomain}.{worker_id}.wtf + :param subdomain: the subdomain to use in the generated domain (default 'le') + :return: the well-formed domain suitable for redirection on + """ + return '{0}.{1}.wtf'.format(subdomain, self.worker_id) |