summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvg <vgm+dev@devys.org>2020-03-12 17:43:52 +0100
committervg <vgm+dev@devys.org>2020-03-12 17:43:52 +0100
commitcf2f1f2d3429650444685e07ee4e11bcd596bba8 (patch)
treed49b166e56befaedeebf1f6195e68759a0f6a8ad
parent0d836532023330efd8ffef7b23ad406ce0309f4e (diff)
downloadacme-dns-tiny-cf2f1f2d3429650444685e07ee4e11bcd596bba8.tar.gz
acme-dns-tiny-cf2f1f2d3429650444685e07ee4e11bcd596bba8.tar.bz2
acme-dns-tiny-cf2f1f2d3429650444685e07ee4e11bcd596bba8.zip
Rework test (coverage and refactorization)
- better coverage (add contact tests) - split one big test with a loop on a dict to single test functions, giving better view on test advance and report - factorization of _csr and _san_csr to a single function
-rw-r--r--tests/test_acme_dns_tiny.py189
1 files changed, 115 insertions, 74 deletions
diff --git a/tests/test_acme_dns_tiny.py b/tests/test_acme_dns_tiny.py
index 9a2562d..bb96765 100644
--- a/tests/test_acme_dns_tiny.py
+++ b/tests/test_acme_dns_tiny.py
@@ -2,9 +2,13 @@
import collections
+import inspect
+import logging
import os
+import subprocess
import sys
import tempfile
+
import pytest
@@ -14,20 +18,45 @@ sys.path.append(os.path.realpath("."))
import acme_dns_tiny
-DOMAIN = os.getenv('TEST_DOMAIN')
ACME_STAGING_DIRECTORY = \
'https://acme-staging-v02.api.letsencrypt.org/directory'
+DOMAIN = os.getenv('TEST_DOMAIN')
CONTACT = os.getenv('TEST_CONTACT') # form: mailto:name@domain
+SCRIPT = os.getenv('TEST_SCRIPT')
-def test_sanity_env():
- assert DOMAIN
- assert CONTACT
+def funcname():
+ return inspect.currentframe().f_back.f_code.co_name
-@pytest.fixture(scope='module')
-def casemap(tmpdir_factory):
+def parent_funcname():
+ return inspect.currentframe().f_back.f_back.f_code.co_name
+
+def assert_success(capsys, args):
+ name = parent_funcname()
+ logging.info(f'assert_success({name}, {args})')
+ acme_dns_tiny.main(args)
+ captured = capsys.readouterr()
+ #assert not captured.err
+ certlist = captured.out.split('-----BEGIN CERTIFICATE-----')
+ assert len(certlist) == 3
+ assert certlist[0] == ''
+ assert '-----END CERTIFICATE-----\n' in certlist[1]
+ assert '-----END CERTIFICATE-----\n' in certlist[2]
+ textchain = acme_dns_tiny.openssl(['x509', '-text', '-noout'],
+ stdin=captured.out)
+ assert 'Issuer' in textchain
+
+
+def assert_assertion(args):
+ name = parent_funcname()
+ logging.info(f'assert_assertion({name}, {args})')
+ with pytest.raises(ValueError):
+ acme_dns_tiny.main(args)
+
+@pytest.fixture(scope='module')
+def keys(tmpdir_factory):
tmpdir = tmpdir_factory.mktemp("data")
def _gen_key(name, size):
@@ -35,98 +64,110 @@ def casemap(tmpdir_factory):
acme_dns_tiny.openssl(['genrsa', '-out', path, str(size)])
return path
- account_key = _gen_key('account_key', 4096)
- domain_key = _gen_key('domain_key', 4096)
- weak_account_key = _gen_key('weak_account_key', 1024)
- weak_domain_key = _gen_key('weak_domain_key', 1024)
+ return {
+ 'account_key': _gen_key('account_key', 4096),
+ 'domain_key': _gen_key('domain_key', 4096),
+ 'weak_account_key': _gen_key('weak_account_key', 1024),
+ 'weak_domain_key': _gen_key('weak_domain_key', 1024),
+ }
+
+
+@pytest.fixture(scope='module')
+def csr_args(tmpdir_factory, keys):
+ tmpdir = tmpdir_factory.mktemp("data")
default_args = {
'--acme-directory': ACME_STAGING_DIRECTORY,
- '--script': 'tests/test_script.sh',
- '--account-key': account_key,
+ '--script': SCRIPT,
+ '--account-key': keys['account_key'],
#'--ttl': 60, # already the default
'--ttl': None,
'--contact': None,
- #'--contact': [CONTACT], # not supported by staging directory
'--verbose': None,
'--quiet': None,
}
- def _csr(name, domain_key, subj=f'/CN={DOMAIN}'):
+ def _csr(subj, key_name='domain_key', san=None, args={}):
+ name = parent_funcname()
+ domain_key = keys[key_name]
path = str(tmpdir.join(name))
- acme_dns_tiny.openssl([
- 'req', '-new', '-key', domain_key, '-subj', subj, '-out', path
- ])
- return {**default_args, '--csr': path}
-
- def _san_csr(name, subj='/', san=None):
- path = str(tmpdir.join(name))
- with tempfile.NamedTemporaryFile('w', encoding='utf8') as conf, \
- open('/etc/ssl/openssl.cnf', 'r', encoding='utf8') as orig:
- conf.write(orig.read())
- conf.write(f'\n[SAN]\nsubjectAltName={san}\n')
- conf.flush()
+ if san is None:
acme_dns_tiny.openssl([
- 'req', '-new', '-key', domain_key, '-subj', subj,
- '-reqexts', 'SAN', '-config', conf.name, '-out', path
+ 'req', '-new', '-key', domain_key, '-subj', subj, '-out', path
])
- return {**default_args, '--csr': path}
+ else:
+ with tempfile.NamedTemporaryFile('w', encoding='utf8') as conf, \
+ open('/etc/ssl/openssl.cnf', 'r', encoding='utf8') as orig:
+ conf.write(orig.read())
+ conf.write(f'\n[SAN]\nsubjectAltName={san}\n')
+ conf.flush()
+ acme_dns_tiny.openssl([
+ 'req', '-new', '-key', domain_key, '-subj', subj,
+ '-reqexts', 'SAN', '-config', conf.name, '-out', path
+ ])
+ return {**default_args, '--csr': path, **args}
- return {
- # single domain
- 'single': _csr('csr_single', domain_key),
+ return _csr
- # single, but weak account key used
- 'weakaccountkey': {
- **_csr('csr_simple', domain_key),
- '--account-key': weak_account_key,
- },
- # single, but weak domain key used to sign csr
- 'weakdomainkey': _csr('csr_weakdomain', weak_domain_key),
+def test_sanity_env():
+ assert bool(DOMAIN)
+ assert bool(CONTACT)
+ assert bool(SCRIPT)
- # single, csr wrongly signed by account key
- 'csrbyaccount': _csr('csr_byaccount', account_key),
- # wildcard domain in CN
- 'wildcard': _csr('csr_wildcard', domain_key, f'/CN=*.{DOMAIN}'),
+def test_sanity_command():
+ subprocess.run([SCRIPT, 'add', f'_acme-challenge.{DOMAIN}.', 'dummy'])
- # san only
- 'sanonly': _san_csr('csr_sanonly',
- san=f'DNS:{DOMAIN},DNS:www.{DOMAIN}'),
- # san and cn
- 'san': _san_csr('csr_san', subj=f'/CN={DOMAIN}',
- san=f'DNS:www.{DOMAIN}'),
+def test_success_single_domain_in_cn(csr_args, capsys):
+ subj = f'/CN={DOMAIN}'
+ assert_success(capsys, csr_args(subj))
- # san wildcard (domain + *.domain, contrary to wildcard in cn)
- 'wildcardsan': _san_csr('csr_wildcardsan',
- san=f'DNS:{DOMAIN},DNS:*.{DOMAIN}')
- }
+def test_success_wildcard_in_cn(csr_args, capsys):
+ subj = f'/CN=*.{DOMAIN}'
+ assert_success(capsys, csr_args(subj))
-def assert_certificate_chain(captured):
- #assert not captured.err
- certlist = captured.out.split('-----BEGIN CERTIFICATE-----')
- assert len(certlist) == 3
- assert certlist[0] == ''
- assert '-----END CERTIFICATE-----\n' in certlist[1]
- assert '-----END CERTIFICATE-----\n' in certlist[2]
- textchain = acme_dns_tiny.openssl(['x509', '-text', '-noout'],
- stdin=captured.out)
- assert 'Issuer' in textchain
+
+def test_success_san_only(csr_args, capsys):
+ subj = '/'
+ san = f'DNS:{DOMAIN},DNS:www.{DOMAIN}'
+ assert_success(capsys, csr_args(subj=subj, san=san))
+
+
+def test_success_san_only_contact(csr_args, capsys):
+ subj = '/'
+ san = f'DNS:{DOMAIN},DNS:www.{DOMAIN}'
+ args = {'--contact': [CONTACT]}
+ assert_success(capsys, csr_args(subj=subj, san=san, args=args))
+
+
+def test_success_san_contact(csr_args, capsys):
+ subj = f'/CN={DOMAIN}'
+ san = f'DNS:www.{DOMAIN}'
+ args = {'--contact': [CONTACT]}
+ assert_success(capsys, csr_args(subj=subj, san=san, args=args))
+
+
+def test_success_wildcard_san(csr_args, capsys):
+ subj = '/'
+ san = f'DNS:{DOMAIN},DNS:*.{DOMAIN}'
+ assert_success(capsys, csr_args(subj=subj, san=san))
+
+
+def test_fail_weak_account_key(csr_args, keys):
+ subj = f'/CN={DOMAIN}'
+ args = {'--account-key': keys['weak_account_key']}
+ assert_assertion(csr_args(subj, args=args))
-def test_success(capsys, casemap):
- for name in ('single', 'wildcard', 'sanonly', 'san', 'wildcardsan'):
- print(f'test_success case: {name}', file=sys.stderr)
- acme_dns_tiny.main(casemap[name])
- captured = capsys.readouterr()
- assert_certificate_chain(captured)
+def test_fail_weak_domain_key(csr_args):
+ subj = f'/CN={DOMAIN}'
+ assert_assertion(csr_args(subj, key_name='weak_domain_key'))
-def test_assert(casemap):
- for name in ('weakaccountkey', 'weakdomainkey', 'csrbyaccount'):
- print(f'test_assert case: {name}', file=sys.stderr)
- with pytest.raises(ValueError):
- acme_dns_tiny.main(casemap[name])
+def test_fail_csr_by_account(csr_args):
+ subj = f'/CN={DOMAIN}'
+ # single, csr wrongly signed by account key
+ assert_assertion(csr_args(subj, key_name='account_key'))