Merge branch 'master' into acme-v2

This commit is contained in:
Jacob Hoffman-Andrews 2017-12-05 14:58:56 -08:00
commit 6a8906509f
8 changed files with 59 additions and 28 deletions

View file

@ -325,8 +325,9 @@ class ChallengeBody(ResourceBody):
"""
__slots__ = ('chall',)
# ACMEv1 has a "uri" field in challenges. ACMEv2 has a "url" field. This
# challenge object supports either one. In Client.answer_challenge,
# whichever one is set will be used.
# challenge object supports either one, but should be accessed through the
# name "uri". In Client.answer_challenge, whichever one is set will be
# used.
_uri = jose.Field('uri', omitempty=True, default=None)
_url = jose.Field('url', omitempty=True, default=None)
status = jose.Field('status', decoder=Status.from_json,
@ -335,6 +336,14 @@ class ChallengeBody(ResourceBody):
error = jose.Field('error', decoder=Error.from_json,
omitempty=True, default=None)
def __init__(self, **kwargs):
kwargs = dict((self._internal_name(k), v) for k, v in kwargs.items())
# pylint: disable=star-args
super(ChallengeBody, self).__init__(**kwargs)
def encode(self, name):
return super(ChallengeBody, self).encode(self._internal_name(name))
def to_partial_json(self):
jobj = super(ChallengeBody, self).to_partial_json()
jobj.update(self.chall.to_partial_json())
@ -346,9 +355,23 @@ class ChallengeBody(ResourceBody):
jobj_fields['chall'] = challenges.Challenge.from_json(jobj)
return jobj_fields
@property
def uri(self):
"""The URL of this challenge."""
return self._url or self._uri
def __getattr__(self, name):
return getattr(self.chall, name)
def __iter__(self):
# When iterating over fields, use the external name 'uri' instead of
# the internal '_uri'.
for name in super(ChallengeBody, self).__iter__():
yield name[1:] if name == '_uri' else name
def _internal_name(self, name):
return '_' + name if name == 'uri' else name
class ChallengeResource(Resource):
"""Challenge Resource.
@ -361,10 +384,10 @@ class ChallengeResource(Resource):
authzr_uri = jose.Field('authzr_uri')
@property
def uri(self): # pylint: disable=missing-docstring,no-self-argument
# bug? 'method already defined line None'
# pylint: disable=function-redefined
return self.body._url or self.body._uri # pylint: disable=no-member
def uri(self):
"""The URL of the challenge body."""
# pylint: disable=function-redefined,no-member
return self.body.uri
class Authorization(ResourceBody):

View file

@ -283,6 +283,9 @@ class ChallengeBodyTest(unittest.TestCase):
'detail': 'Unable to communicate with DNS server',
}
def test_encode(self):
self.assertEqual(self.challb.encode('uri'), self.challb.uri)
def test_to_partial_json(self):
self.assertEqual(self.jobj_to, self.challb.to_partial_json())

View file

@ -131,7 +131,7 @@ class DigitalOceanClientTest(unittest.TestCase):
self.digitalocean_client.del_txt_record(DOMAIN, self.record_name, self.record_content)
correct_record_mock.destroy.assert_called()
self.assertTrue(correct_record_mock.destroy.called)
self.assertFalse(first_record_mock.destroy.call_args_list)
self.assertFalse(last_record_mock.destroy.call_args_list)

View file

@ -31,7 +31,7 @@ class AuthenticatorTest(unittest.TestCase, dns_test_common.BaseAuthenticatorTest
self.auth._change_txt_record.assert_called_once_with("UPSERT",
'_acme-challenge.' + DOMAIN,
mock.ANY)
self.auth._wait_for_change.assert_called_once()
self.assertEqual(self.auth._wait_for_change.call_count, 1)
def test_perform_no_credentials_error(self):
self.auth._change_txt_record = mock.MagicMock(side_effect=NoCredentialsError)
@ -183,7 +183,8 @@ class ClientTest(unittest.TestCase):
self.client._change_txt_record("FOO", DOMAIN, "foo")
self.client.r53.change_resource_record_sets.assert_called_once()
call_count = self.client.r53.change_resource_record_sets.call_count
self.assertEqual(call_count, 1)
def test_wait_for_change(self):
self.client.r53.get_change = mock.MagicMock(
@ -192,7 +193,7 @@ class ClientTest(unittest.TestCase):
self.client._wait_for_change(1)
self.client.r53.get_change.assert_called()
self.assertTrue(self.client.r53.get_change.called)
if __name__ == "__main__":

View file

@ -356,7 +356,7 @@ class DeleteIfAppropriateTest(unittest.TestCase):
mock_cert_path_for_cert_name.return_value = "/some/reasonable/path"
mock_overlapping_archive_dirs.return_value = False
self._call(config)
mock_delete.assert_called_once()
self.assertEqual(mock_delete.call_count, 1)
# pylint: disable=too-many-arguments
@mock.patch('certbot.storage.renewal_file_for_certname')
@ -375,7 +375,7 @@ class DeleteIfAppropriateTest(unittest.TestCase):
mock_cert_path_to_lineage.return_value = "example.com"
mock_overlapping_archive_dirs.return_value = False
self._call(config)
mock_delete.assert_called_once()
self.assertEqual(mock_delete.call_count, 1)
# pylint: disable=too-many-arguments
@mock.patch('certbot.storage.renewal_file_for_certname')
@ -396,7 +396,7 @@ class DeleteIfAppropriateTest(unittest.TestCase):
mock_full_archive_dir.return_value = ""
mock_match_and_check_overlaps.return_value = ""
self._call(config)
mock_delete.assert_called_once()
self.assertEqual(mock_delete.call_count, 1)
# pylint: disable=too-many-arguments
@mock.patch('certbot.storage.renewal_file_for_certname')
@ -415,7 +415,7 @@ class DeleteIfAppropriateTest(unittest.TestCase):
mock_cert_path_to_lineage.return_value = config.certname
mock_overlapping_archive_dirs.return_value = False
self._call(config)
mock_delete.assert_called_once()
self.assertEqual(mock_delete.call_count, 1)
# pylint: disable=too-many-arguments
@mock.patch('certbot.cert_manager.match_and_check_overlaps')
@ -442,7 +442,7 @@ class DeleteIfAppropriateTest(unittest.TestCase):
util_mock = mock_get_utility()
util_mock.menu.return_value = (display_util.OK, 0)
self._call(config)
mock_delete.assert_called_once()
self.assertEqual(mock_delete.call_count, 1)
# pylint: disable=too-many-arguments
@mock.patch('certbot.cert_manager.match_and_check_overlaps')

View file

@ -1062,9 +1062,10 @@ zope.interface==4.1.3 \
--hash=sha256:928138365245a0e8869a5999fbcc2a45475a0a6ed52a494d60dbdc540335fedd \
--hash=sha256:0d841ba1bb840eea0e6489dc5ecafa6125554971f53b5acb87764441e61bceba \
--hash=sha256:b09c8c1d47b3531c400e0195697f1414a63221de6ef478598a4f1460f7d9a392
mock==2.0.0 \
--hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
--hash=sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba
# Using an older version of mock here prevents regressions of #5276.
mock==1.3.0 \
--hash=sha256:3f573a18be94de886d1191f27c168427ef693e8dcfcecf95b170577b2eb69cbb \
--hash=sha256:1e247dbecc6ce057299eb7ee019ad68314bb93152e81d9a6110d35f4d5eca0f6
# Contains the requirements for the letsencrypt package.
#

View file

@ -184,6 +184,7 @@ zope.interface==4.1.3 \
--hash=sha256:928138365245a0e8869a5999fbcc2a45475a0a6ed52a494d60dbdc540335fedd \
--hash=sha256:0d841ba1bb840eea0e6489dc5ecafa6125554971f53b5acb87764441e61bceba \
--hash=sha256:b09c8c1d47b3531c400e0195697f1414a63221de6ef478598a4f1460f7d9a392
mock==2.0.0 \
--hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
--hash=sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba
# Using an older version of mock here prevents regressions of #5276.
mock==1.3.0 \
--hash=sha256:3f573a18be94de886d1191f27c168427ef693e8dcfcecf95b170577b2eb69cbb \
--hash=sha256:1e247dbecc6ce057299eb7ee019ad68314bb93152e81d9a6110d35f4d5eca0f6

View file

@ -16,7 +16,7 @@ fi
cover () {
if [ "$1" = "certbot" ]; then
min=97
min=98
elif [ "$1" = "acme" ]; then
min=100
elif [ "$1" = "certbot_apache" ]; then
@ -24,23 +24,23 @@ cover () {
elif [ "$1" = "certbot_dns_cloudflare" ]; then
min=98
elif [ "$1" = "certbot_dns_cloudxns" ]; then
min=98
min=99
elif [ "$1" = "certbot_dns_digitalocean" ]; then
min=98
elif [ "$1" = "certbot_dns_dnsimple" ]; then
min=98
elif [ "$1" = "certbot_dns_dnsmadeeasy" ]; then
min=98
min=99
elif [ "$1" = "certbot_dns_google" ]; then
min=99
elif [ "$1" = "certbot_dns_luadns" ]; then
min=98
elif [ "$1" = "certbot_dns_nsone" ]; then
min=98
min=99
elif [ "$1" = "certbot_dns_rfc2136" ]; then
min=99
elif [ "$1" = "certbot_dns_route53" ]; then
min=91
min=92
elif [ "$1" = "certbot_nginx" ]; then
min=97
elif [ "$1" = "letshelp_certbot" ]; then
@ -50,10 +50,12 @@ cover () {
exit 1
fi
pytest --cov "$1" --cov-report term-missing \
--cov-fail-under "$min" --numprocesses auto --pyargs "$1"
pkg_dir=$(echo "$1" | tr _ -)
pytest --cov "$pkg_dir" --cov-append --cov-report= --numprocesses auto --pyargs "$1"
coverage report --fail-under="$min" --include="$pkg_dir/*" --show-missing
}
rm -f .coverage # --cov-append is on, make sure stats are correct
for pkg in $pkgs
do
cover $pkg