Reimplement zope interfaces into abc in compatibility tests (#8971)

* Reimplement zope interfaces into abc in compatibility tests

* Refactor to fix lint and mypy warnings

* Fix inheritance
This commit is contained in:
Adrien Ferrand
2021-08-13 11:00:33 +10:00
committed by GitHub
parent b4c49cf781
commit 6943cea6b7
5 changed files with 86 additions and 47 deletions
@@ -4,18 +4,14 @@ import shutil
import subprocess
from unittest import mock
import zope.interface
from certbot import errors as le_errors, configuration
from certbot import util as certbot_util
from certbot_apache._internal import entrypoint
from certbot_compatibility_test import errors
from certbot_compatibility_test import interfaces
from certbot_compatibility_test import util
from certbot_compatibility_test.configurators import common as configurators_common
@zope.interface.implementer(interfaces.IConfiguratorProxy)
class Proxy(configurators_common.Proxy):
"""A common base for Apache test configurators"""
@@ -1,17 +1,19 @@
"""Provides a common base for configurator proxies"""
from abc import abstractmethod
import logging
import os
import shutil
import tempfile
from certbot._internal import constants
from certbot_compatibility_test import interfaces
from certbot_compatibility_test import errors
from certbot_compatibility_test import util
logger = logging.getLogger(__name__)
class Proxy:
class Proxy(interfaces.ConfiguratorProxy):
"""A common base for compatibility test configurators"""
@classmethod
@@ -20,6 +22,7 @@ class Proxy:
def __init__(self, args):
"""Initializes the plugin with the given command line args"""
super().__init__(args)
self._temp_dir = tempfile.mkdtemp()
# tempfile.mkdtemp() creates folders with too restrictive permissions to be accessible
# to an Apache worker, leading to HTTP challenge failures. Let's fix that.
@@ -33,24 +36,15 @@ class Proxy:
self.args = args
self.http_port = 80
self.https_port = 443
self._configurator = None
self._configurator: interfaces.Configurator
self._all_names = None
self._test_names = None
def __getattr__(self, name):
"""Wraps the configurator methods"""
if self._configurator is None:
raise AttributeError()
method = getattr(self._configurator, name, None)
if callable(method):
return method
raise AttributeError()
def has_more_configs(self):
"""Returns true if there are more configs to test"""
return bool(self._configs)
@abstractmethod
def cleanup_from_tests(self):
"""Performs any necessary cleanup from running plugin tests"""
@@ -99,3 +93,47 @@ class Proxy:
raise ValueError("Configurator plugin is not set.")
self._configurator.deploy_cert(
domain, cert_path, key_path, chain_path, fullchain_path)
def cleanup(self, achalls):
self._configurator.cleanup(achalls)
def config_test(self):
self._configurator.config_test()
def enhance(self, domain, enhancement, options = None):
self._configurator.enhance(domain, enhancement, options)
def get_all_names(self):
return self._configurator.get_all_names()
def get_chall_pref(self, domain):
return self._configurator.get_chall_pref(domain)
@classmethod
def inject_parser_options(cls, parser, name):
pass
def more_info(self):
return self._configurator.more_info()
def perform(self, achalls):
return self._configurator.perform(achalls)
def prepare(self):
self._configurator.prepare()
def recovery_routine(self):
self._configurator.recovery_routine()
def restart(self):
self._configurator.restart()
def rollback_checkpoints(self, rollback = 1):
self._configurator.rollback_checkpoints(rollback)
def save(self, title = None, temporary = False):
self._configurator.save(title, temporary)
def supported_enhancements(self):
return self._configurator.supported_enhancements()
@@ -2,10 +2,9 @@
import os
import shutil
import subprocess
from typing import cast
from typing import Set
import zope.interface
from certbot import configuration
from certbot_compatibility_test import errors
from certbot_compatibility_test import interfaces
@@ -15,7 +14,6 @@ from certbot_nginx._internal import configurator
from certbot_nginx._internal import constants
@zope.interface.implementer(interfaces.IConfiguratorProxy)
class Proxy(configurators_common.Proxy):
"""A common base for Nginx test configurators"""
@@ -48,10 +46,13 @@ class Proxy(configurators_common.Proxy):
setattr(self.le_config, "nginx_" + k, constants.os_constant(k))
conf = configuration.NamespaceConfig(self.le_config)
self._configurator = configurator.NginxConfigurator(
config=conf, name="nginx")
self._configurator = cast(interfaces.Configurator, configurator.NginxConfigurator(
config=conf, name="nginx"))
self._configurator.prepare()
def cleanup_from_tests(self):
"""Performs any necessary cleanup from running plugin tests"""
def _get_server_root(config):
"""Returns the server root directory in config"""
@@ -1,53 +1,65 @@
"""Certbot compatibility test interfaces"""
import zope.interface
from abc import ABCMeta
from abc import abstractmethod
import certbot.interfaces
# pylint: disable=no-self-argument,no-method-argument
from certbot import interfaces
class IPluginProxy(zope.interface.Interface): # pylint: disable=inherit-non-class
class PluginProxy(interfaces.Plugin, metaclass=ABCMeta):
"""Wraps a Certbot plugin"""
http_port = zope.interface.Attribute(
"The port to connect to on localhost for HTTP traffic")
http_port: int = NotImplemented
"""The port to connect to on localhost for HTTP traffic"""
https_port = zope.interface.Attribute(
"The port to connect to on localhost for HTTPS traffic")
https_port: int = NotImplemented
"""The port to connect to on localhost for HTTPS traffic"""
@classmethod
@abstractmethod
def add_parser_arguments(cls, parser):
"""Adds command line arguments needed by the parser"""
def __init__(args): # pylint: disable=super-init-not-called
@abstractmethod
def __init__(self, args):
"""Initializes the plugin with the given command line args"""
super().__init__(args, 'proxy')
def cleanup_from_tests(): # type: ignore
@abstractmethod
def cleanup_from_tests(self): # type: ignore
"""Performs any necessary cleanup from running plugin tests.
This is guaranteed to be called before the program exits.
"""
def has_more_configs(): # type: ignore
@abstractmethod
def has_more_configs(self): # type: ignore
"""Returns True if there are more configs to test"""
def load_config(): # type: ignore
@abstractmethod
def load_config(self): # type: ignore
"""Loads the next config and returns its name"""
def get_testable_domain_names(): # type: ignore
@abstractmethod
def get_testable_domain_names(self): # type: ignore
"""Returns the domain names that can be used in testing"""
class IAuthenticatorProxy(IPluginProxy, certbot.interfaces.IAuthenticator):
class AuthenticatorProxy(PluginProxy, interfaces.Authenticator, metaclass=ABCMeta):
"""Wraps a Certbot authenticator"""
class IInstallerProxy(IPluginProxy, certbot.interfaces.IInstaller):
class InstallerProxy(PluginProxy, interfaces.Installer, metaclass=ABCMeta):
"""Wraps a Certbot installer"""
def get_all_names_answer(): # type: ignore
@abstractmethod
def get_all_names_answer(self): # type: ignore
"""Returns all names that should be found by the installer"""
class IConfiguratorProxy(IAuthenticatorProxy, IInstallerProxy):
class ConfiguratorProxy(AuthenticatorProxy, InstallerProxy, metaclass=ABCMeta):
"""Wraps a Certbot configurator"""
class Configurator(interfaces.Installer, interfaces.Authenticator, metaclass=ABCMeta):
"""Represents a plugin that has both Installer and Authenticator capabilities"""
-8
View File
@@ -1,5 +1,3 @@
import sys
from setuptools import find_packages
from setuptools import setup
@@ -9,14 +7,8 @@ install_requires = [
'certbot',
'certbot-apache',
'requests',
'zope.interface',
]
if sys.version_info < (2, 7, 9):
# For secure SSL connexion with Python 2.7 (InsecurePlatformWarning)
install_requires.append('ndg-httpsclient')
install_requires.append('pyasn1')
setup(
name='certbot-compatibility-test',