From 7d02e129f9e0fd9abed850621d78e91dd7684ff8 Mon Sep 17 00:00:00 2001 From: Yen Chi Hsuan Date: Sat, 25 Feb 2017 10:21:21 +0800 Subject: [PATCH] Fix certbot-apache tests on Python 3 (#4172) --- certbot-apache/certbot_apache/obj.py | 10 ++++++++++ certbot-apache/certbot_apache/parser.py | 14 +++++++++---- .../certbot_apache/tests/configurator_test.py | 20 ++++++++++--------- .../certbot_apache/tests/display_ops_test.py | 2 +- .../certbot_apache/tests/tls_sni_01_test.py | 2 +- certbot-apache/certbot_apache/tls_sni_01.py | 2 +- tox.ini | 8 ++++++++ 7 files changed, 42 insertions(+), 16 deletions(-) diff --git a/certbot-apache/certbot_apache/obj.py b/certbot-apache/certbot_apache/obj.py index b29b0e0ee..30cb24844 100644 --- a/certbot-apache/certbot_apache/obj.py +++ b/certbot-apache/certbot_apache/obj.py @@ -25,6 +25,11 @@ class Addr(common.Addr): def __repr__(self): return "certbot_apache.obj.Addr(" + repr(self.tup) + ")" + def __hash__(self): + # Python 3 requires explicit overridden for __hash__ if __eq__ or + # __cmp__ is overridden. See https://bugs.python.org/issue2235 + return super(Addr, self).__hash__() + def _addr_less_specific(self, addr): """Returns if addr.get_addr() is more specific than self.get_addr().""" # pylint: disable=protected-access @@ -174,6 +179,11 @@ class VirtualHost(object): # pylint: disable=too-few-public-methods def __ne__(self, other): return not self.__eq__(other) + def __hash__(self): + return hash((self.filep, self.path, + tuple(self.addrs), tuple(self.get_names()), + self.ssl, self.enabled, self.modmacro)) + def conflicts(self, addrs): """See if vhost conflicts with any of the addrs. diff --git a/certbot-apache/certbot_apache/parser.py b/certbot-apache/certbot_apache/parser.py index 6bb6ff170..275a01e7f 100644 --- a/certbot-apache/certbot_apache/parser.py +++ b/certbot-apache/certbot_apache/parser.py @@ -1,10 +1,12 @@ """ApacheParser is a member object of the ApacheConfigurator class.""" import fnmatch -import itertools import logging import os import re import subprocess +import sys + +import six from certbot import errors @@ -87,7 +89,7 @@ class ApacheParser(object): while len(self.modules) != prev_size: prev_size = len(self.modules) - for match_name, match_filename in itertools.izip( + for match_name, match_filename in six.moves.zip( iterator, iterator): self.modules.add(self.get_arg(match_name)) self.modules.add( @@ -460,8 +462,12 @@ class ApacheParser(object): :rtype: str """ - # This strips off final /Z(?ms) - return fnmatch.translate(clean_fn_match)[:-7] + if sys.version_info < (3, 6): + # This strips off final /Z(?ms) + return fnmatch.translate(clean_fn_match)[:-7] + else: # pragma: no cover + # Since Python 3.6, it returns a different pattern like (?s:.*\.load)\Z + return fnmatch.translate(clean_fn_match)[4:-3] def _parse_file(self, filepath): """Parse file with Augeas diff --git a/certbot-apache/certbot_apache/tests/configurator_test.py b/certbot-apache/certbot_apache/tests/configurator_test.py index 01361c8f0..937694267 100644 --- a/certbot-apache/certbot_apache/tests/configurator_test.py +++ b/certbot-apache/certbot_apache/tests/configurator_test.py @@ -6,6 +6,8 @@ import socket import unittest import mock +# six is used in mock.patch() +import six # pylint: disable=unused-import from acme import challenges @@ -517,12 +519,12 @@ class MultipleVhostsTest(util.ApacheTest): # Test self.config.prepare_server_https("8080", temp=True) self.assertEqual(mock_add_dir.call_count, 3) - self.assertEqual(mock_add_dir.call_args_list[0][0][2], - ["1.2.3.4:8080", "https"]) - self.assertEqual(mock_add_dir.call_args_list[1][0][2], - ["[::1]:8080", "https"]) - self.assertEqual(mock_add_dir.call_args_list[2][0][2], - ["1.1.1.1:8080", "https"]) + call_args_list = [mock_add_dir.call_args_list[i][0][2] for i in range(3)] + self.assertEqual( + sorted(call_args_list), + sorted([["1.2.3.4:8080", "https"], + ["[::1]:8080", "https"], + ["1.1.1.1:8080", "https"]])) # mock_get.side_effect = ["1.2.3.4:80", "[::1]:80"] # mock_find.return_value = ["test1", "test2", "test3"] @@ -662,7 +664,7 @@ class MultipleVhostsTest(util.ApacheTest): # This calls open self.config.reverter.register_file_creation = mock.Mock() mock_open.side_effect = IOError - with mock.patch("__builtin__.open", mock_open): + with mock.patch("six.moves.builtins.open", mock_open): self.assertRaises( errors.PluginError, self.config.make_vhost_ssl, self.vh_truth[0]) @@ -1208,13 +1210,13 @@ class MultipleVhostsTest(util.ApacheTest): achall1 = achallenges.KeyAuthorizationAnnotatedChallenge( challb=acme_util.chall_to_challb( challenges.TLSSNI01( - token="jIq_Xy1mXGN37tb4L6Xj_es58fW571ZNyXekdZzhh7Q"), + token=b"jIq_Xy1mXGN37tb4L6Xj_es58fW571ZNyXekdZzhh7Q"), "pending"), domain="encryption-example.demo", account_key=account_key) achall2 = achallenges.KeyAuthorizationAnnotatedChallenge( challb=acme_util.chall_to_challb( challenges.TLSSNI01( - token="uqnaPzxtrndteOqtrXb0Asl5gOJfWAnnx6QJyvcmlDU"), + token=b"uqnaPzxtrndteOqtrXb0Asl5gOJfWAnnx6QJyvcmlDU"), "pending"), domain="certbot.demo", account_key=account_key) diff --git a/certbot-apache/certbot_apache/tests/display_ops_test.py b/certbot-apache/certbot_apache/tests/display_ops_test.py index ec6eee3f2..f8b75022e 100644 --- a/certbot-apache/certbot_apache/tests/display_ops_test.py +++ b/certbot-apache/certbot_apache/tests/display_ops_test.py @@ -38,7 +38,7 @@ class SelectVhostTest(unittest.TestCase): try: self._call(self.vhosts) except errors.MissingCommandlineFlag as e: - self.assertTrue("vhost ambiguity" in e.message) + self.assertTrue("vhost ambiguity" in str(e)) @certbot_util.patch_get_utility() def test_more_info_cancel(self, mock_util): diff --git a/certbot-apache/certbot_apache/tests/tls_sni_01_test.py b/certbot-apache/certbot_apache/tests/tls_sni_01_test.py index 5e369e3db..62464d5d0 100644 --- a/certbot-apache/certbot_apache/tests/tls_sni_01_test.py +++ b/certbot-apache/certbot_apache/tests/tls_sni_01_test.py @@ -105,7 +105,7 @@ class TlsSniPerformTest(util.ApacheTest): for achall in self.achalls: self.sni.add_chall(achall) z_domain = achall.response(self.auth_key).z_domain - z_domains.append(set([z_domain])) + z_domains.append(set([z_domain.decode('ascii')])) self.sni._mod_config() # pylint: disable=protected-access self.sni.configurator.save() diff --git a/certbot-apache/certbot_apache/tls_sni_01.py b/certbot-apache/certbot_apache/tls_sni_01.py index d9e294119..65a66d2fd 100644 --- a/certbot-apache/certbot_apache/tls_sni_01.py +++ b/certbot-apache/certbot_apache/tls_sni_01.py @@ -184,7 +184,7 @@ class ApacheTlsSni01(common.TLSSNI01): # https://docs.python.org/2.7/reference/lexical_analysis.html return self.VHOST_TEMPLATE.format( vhost=ips, - server_name=achall.response(achall.account_key).z_domain, + server_name=achall.response(achall.account_key).z_domain.decode('ascii'), ssl_options_conf_path=self.configurator.mod_ssl_conf, cert_path=self.get_cert_path(achall), key_path=self.get_key_path(achall), diff --git a/tox.ini b/tox.ini index e6317e665..232010d40 100644 --- a/tox.ini +++ b/tox.ini @@ -46,6 +46,8 @@ commands = nosetests -v acme --processes=-1 pip install -e .[dev] nosetests -v certbot --processes=-1 --process-timeout=100 + pip install -e certbot-apache + nosetests -v certbot_apache --processes=-1 --process-timeout=80 [testenv:py34] commands = @@ -53,6 +55,8 @@ commands = nosetests -v acme --processes=-1 pip install -e .[dev] nosetests -v certbot --processes=-1 --process-timeout=100 + pip install -e certbot-apache + nosetests -v certbot_apache --processes=-1 --process-timeout=80 [testenv:py35] commands = @@ -60,6 +64,8 @@ commands = nosetests -v acme --processes=-1 pip install -e .[dev] nosetests -v certbot --processes=-1 --process-timeout=100 + pip install -e certbot-apache + nosetests -v certbot_apache --processes=-1 --process-timeout=80 [testenv:py36] commands = @@ -67,6 +73,8 @@ commands = nosetests -v acme --processes=-1 pip install -e .[dev] nosetests -v certbot --processes=-1 --process-timeout=100 + pip install -e certbot-apache + nosetests -v certbot_apache --processes=-1 --process-timeout=80 [testenv:py27_install] basepython = python2.7