certbot/certbot-ci/certbot_integration_tests/certbot_tests/context.py
Adrien Ferrand b67fda8832
Fix integration tests on Windows (#7271)
* Fix account_tests

* Fix hook executable test

* Remove the temporary decorator @broken_on_windows

* Fix util_test

* No broken unit test on Windows anymore

* More elegant mock

* Fix context manager

* Fix lint

* Fix mypy

* Adapt coverage

* Corrections

* Fix lint

* Adapt coverage

* Update certbot/tests/compat/filesystem_test.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Update util_test.py

* Fix pylint

* Forbid os.access

* Update os_test.py

* Update os.py

* Fix lint

* Update filesystem.py

* Update filesystem.py

* Update filesystem.py

* Update os.py

* Start fixing tests

* Platform independent hooks

* Fix probe fd close

* Add broken_on_windows for integration tests

* Fix a lot of tests

* Use a python hook script, to prepare cross-platform

* New approach to be compliant with Linux and Windows on hook scripts

* New tests fixed

* Test for permissions on Windows

* Permissions comparison for Windows

* No broken tests in certbot core anymore

* Change mode

* Specific config for appveyor

* Use forked pebble for now

* Various fixes

* Assert file permissions for world on private keys

* Clean code

* Fix several things

* Add integration target

* Optimize integration env

* Re-enable all AppVeyor envs

* Use again official pebble

* Update pebble_artifacts.py

* Set PYTEST_ADDOPTS silently

* Update appveyor.yml

* Pin pywin32 for tests, give a minimal requirement for certbot.

* Remove injection of nginx in PATH

* Clean debug code

* Various cleanup, ensure to remove workspace after tests

* Update tox target

* Improve assertions. Control the keyword echoed in hooks

* Fix for virtualenv on Python 3.7.4 for Windows

* Update certbot-ci/certbot_integration_tests/certbot_tests/assertions.py

Co-Authored-By: Brad Warren <bmw@users.noreply.github.com>

* Add conditionally pywin in certbot-ci like in certbot
2019-08-07 00:02:16 +02:00

83 lines
3.7 KiB
Python

"""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)