certbot/certbot-ci/certbot_integration_tests/nginx_tests/test_main.py
Adrien Ferrand 618e0562a0 [Unix] Create a framework for certbot integration tests: PART 4 (#6958)
This PR is the part 4 to implement #6541. It adds the integration tests for the nginx certbot plugin, and corresponds to the certbot-ci translation of certbot-nginx/tests/boulder-integration.sh that is executed for each PR.

As with certbot core tests, tests are written in Python, and executed by pytest, against a dynamic Boulder/Pebble instance setup. Tests are parallelized, of course, and a specific IntegrationTestsContext class, extended the one from certbot core tests, is crafter for these specific tests: its main goal is to setup a specific nginx instance for the current test.

On top of that, I use the test parametrization feature of Pytest, to drastically reduce the size of the actual code: indeed, the 6 tests from the original bash script share the same logic. So using a parametrization, one unique test is written, that is then executed 6 times against 6 different sets of parameters.

Note that the module integration_tests.nginx_tests.nginx_config do the same, but in Python, than certbot-nginx/tests/boulder-integration.conf.sh. The latter will be removed in a future PR, with all other bash scripts.

* Add nginx tests

* Distribute the other_port

* Load a pre-generated key/cert for nginx config

* Correct preload, remove a test, simplify a variable

* Integrate assertion directly in the test function

* Check process is not terminated

* Add spaces in the nginx config

* Add comments

* Use indirection

* Allow external cert

* Add coverage threshold for certbot-nginx
2019-04-23 13:29:48 -07:00

56 lines
2.3 KiB
Python

"""Module executing integration tests against certbot with nginx plugin."""
import os
import ssl
import pytest
from certbot_integration_tests.nginx_tests import context as nginx_context
@pytest.fixture()
def context(request):
# Fixture request is a built-in pytest fixture describing current test request.
integration_test_context = nginx_context.IntegrationTestsContext(request)
try:
yield integration_test_context
finally:
integration_test_context.cleanup()
@pytest.mark.parametrize('certname_pattern, params, context', [
('nginx.{0}.wtf', ['run'], {'default_server': True}),
('nginx2.{0}.wtf', ['--preferred-challenges', 'http'], {'default_server': True}),
# Overlapping location block and server-block-level return 301
('nginx3.{0}.wtf', ['--preferred-challenges', 'http'], {'default_server': True}),
# No matching server block; default_server exists
('nginx4.{0}.wtf', ['--preferred-challenges', 'http'], {'default_server': True}),
# No matching server block; default_server does not exist
('nginx5.{0}.wtf', ['--preferred-challenges', 'http'], {'default_server': False}),
# Multiple domains, mix of matching and not
('nginx6.{0}.wtf,nginx7.{0}.wtf', ['--preferred-challenges', 'http'], {'default_server': False}),
], indirect=['context'])
def test_certificate_deployment(certname_pattern, params, context):
"""
Test various scenarios to deploy a certificate to nginx using certbot.
"""
domains = certname_pattern.format(context.worker_id)
command = ['--domains', domains]
command.extend(params)
context.certbot_test_nginx(command)
lineage = domains.split(',')[0]
server_cert = ssl.get_server_certificate(('localhost', context.tls_alpn_01_port))
with open(os.path.join(context.workspace, 'conf/live/{0}/cert.pem'.format(lineage)), 'r') as file:
certbot_cert = file.read()
assert server_cert == certbot_cert
command = ['--authenticator', 'nginx', '--installer', 'nginx',
'--nginx-server-root', context.nginx_root,
'rollback', '--checkpoints', '1']
context._common_test_no_force_renew(command)
with open(context.nginx_config_path, 'r') as file_h:
current_nginx_config = file_h.read()
assert context.nginx_config == current_nginx_config