mirror of
https://github.com/certbot/certbot.git
synced 2026-06-07 07:42:08 -04:00
More coverage for plugins.disco
This commit is contained in:
parent
b600e2d270
commit
1878db3416
2 changed files with 100 additions and 40 deletions
|
|
@ -30,6 +30,11 @@ class PluginEntryPoint(object):
|
|||
return entry_point.name
|
||||
return entry_point.dist.key + ":" + entry_point.name
|
||||
|
||||
@property
|
||||
def name_with_description(self):
|
||||
"""Name with description. Handy for UI."""
|
||||
return "{0} ({1})".format(self.name, self.plugin_cls.description)
|
||||
|
||||
@property
|
||||
def initialized(self):
|
||||
"""Has the plugin been initialized already?"""
|
||||
|
|
@ -42,6 +47,20 @@ class PluginEntryPoint(object):
|
|||
self._initialized = self.plugin_cls(config, self.name)
|
||||
return self._initialized
|
||||
|
||||
def verify(self, ifaces):
|
||||
"""Verify that the plugin conforms to the specified interfaces."""
|
||||
assert self.initialized
|
||||
for iface in ifaces: # zope.interface.providedBy(plugin)
|
||||
try:
|
||||
zope.interface.verify.verifyObject(iface, self.init())
|
||||
except zope.interface.exceptions.BrokenImplementation:
|
||||
if iface.implementedBy(self.plugin_cls):
|
||||
logging.debug(
|
||||
"%s implements %s but object does "
|
||||
"not verify", self.plugin_cls, iface.__name__)
|
||||
return False
|
||||
return True
|
||||
|
||||
@property
|
||||
def prepared(self):
|
||||
"""Has the plugin been prepared already?"""
|
||||
|
|
@ -68,7 +87,8 @@ class PluginEntryPoint(object):
|
|||
@property
|
||||
def misconfigured(self):
|
||||
"""Is plugin misconfigured?"""
|
||||
return isinstance(self._prepared, errors.LetsEncryptMisconfigurationError)
|
||||
return isinstance(
|
||||
self._prepared, errors.LetsEncryptMisconfigurationError)
|
||||
|
||||
@property
|
||||
def available(self):
|
||||
|
|
@ -78,24 +98,6 @@ class PluginEntryPoint(object):
|
|||
def __repr__(self):
|
||||
return "PluginEntryPoint#{0}".format(self.name)
|
||||
|
||||
@property
|
||||
def name_with_description(self):
|
||||
"""Name with description. Handy for UI."""
|
||||
return "{0} ({1})".format(self.name, self.plugin_cls.description)
|
||||
|
||||
def verify(self, ifaces):
|
||||
assert self.initialized
|
||||
for iface in ifaces: # zope.interface.providedBy(plugin)
|
||||
try:
|
||||
zope.interface.verify.verifyObject(iface, self.init())
|
||||
except zope.interface.exceptions.BrokenImplementation:
|
||||
if iface.implementedBy(self.plugin_cls):
|
||||
logging.debug(
|
||||
"%s implements %s but object does "
|
||||
"not verify", self.plugin_cls, iface.__name__)
|
||||
return False
|
||||
return True
|
||||
|
||||
def __str__(self):
|
||||
lines = [
|
||||
"* {0}".format(self.name),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ import pkg_resources
|
|||
import unittest
|
||||
|
||||
import mock
|
||||
import zope.interface
|
||||
|
||||
from letsencrypt.client import errors
|
||||
from letsencrypt.client.plugins.standalone import authenticator
|
||||
|
||||
|
||||
|
|
@ -21,7 +23,8 @@ class PluginEntryPointTest(unittest.TestCase):
|
|||
# project name != top-level package name
|
||||
self.ep3 = pkg_resources.EntryPoint(
|
||||
"ep3", "a.ep3", dist=mock.MagicMock(key="p3"))
|
||||
# something we can load()/require()
|
||||
|
||||
# something we can load()/require(), TODO: use mock
|
||||
self.ep_sa = pkg_resources.EntryPoint(
|
||||
"sa", "letsencrypt.client.plugins.standalone.authenticator",
|
||||
attrs=('StandaloneAuthenticator',),
|
||||
|
|
@ -30,26 +33,6 @@ class PluginEntryPointTest(unittest.TestCase):
|
|||
from letsencrypt.client.plugins.disco import PluginEntryPoint
|
||||
self.plugin_ep = PluginEntryPoint(self.ep_sa)
|
||||
|
||||
def test__init__(self):
|
||||
self.assertFalse(self.plugin_ep.initialized)
|
||||
self.assertTrue(self.plugin_ep.entry_point is self.ep_sa)
|
||||
self.assertEqual("sa", self.plugin_ep.name)
|
||||
|
||||
self.assertTrue(
|
||||
self.plugin_ep.plugin_cls is authenticator.StandaloneAuthenticator)
|
||||
|
||||
def test_init(self):
|
||||
config = mock.MagicMock()
|
||||
plugin = self.plugin_ep.init(config=config)
|
||||
self.assertTrue(self.plugin_ep.initialized)
|
||||
self.assertTrue(plugin.config is config)
|
||||
# memoize!
|
||||
self.assertTrue(self.plugin_ep.init() is plugin)
|
||||
self.assertTrue(plugin.config is config)
|
||||
# try to give different config
|
||||
self.assertTrue(self.plugin_ep.init(123) is plugin)
|
||||
self.assertTrue(plugin.config is config)
|
||||
|
||||
def test_entry_point_to_plugin_name(self):
|
||||
from letsencrypt.client.plugins.disco import PluginEntryPoint
|
||||
|
||||
|
|
@ -69,6 +52,81 @@ class PluginEntryPointTest(unittest.TestCase):
|
|||
self.assertTrue(
|
||||
self.plugin_ep.name_with_description.startswith("sa ("))
|
||||
|
||||
def test__init__(self):
|
||||
self.assertFalse(self.plugin_ep.initialized)
|
||||
self.assertFalse(self.plugin_ep.prepared)
|
||||
self.assertFalse(self.plugin_ep.misconfigured)
|
||||
self.assertFalse(self.plugin_ep.available)
|
||||
self.assertTrue(self.plugin_ep.entry_point is self.ep_sa)
|
||||
self.assertEqual("sa", self.plugin_ep.name)
|
||||
|
||||
self.assertTrue(
|
||||
self.plugin_ep.plugin_cls is authenticator.StandaloneAuthenticator)
|
||||
|
||||
def test_init(self):
|
||||
config = mock.MagicMock()
|
||||
plugin = self.plugin_ep.init(config=config)
|
||||
self.assertTrue(self.plugin_ep.initialized)
|
||||
self.assertTrue(plugin.config is config)
|
||||
# memoize!
|
||||
self.assertTrue(self.plugin_ep.init() is plugin)
|
||||
self.assertTrue(plugin.config is config)
|
||||
# try to give different config
|
||||
self.assertTrue(self.plugin_ep.init(123) is plugin)
|
||||
self.assertTrue(plugin.config is config)
|
||||
|
||||
self.assertFalse(self.plugin_ep.prepared)
|
||||
self.assertFalse(self.plugin_ep.misconfigured)
|
||||
self.assertFalse(self.plugin_ep.available)
|
||||
|
||||
def test_verify(self):
|
||||
i1 = mock.MagicMock(__name__="i1")
|
||||
i2 = mock.MagicMock(__name__="i2")
|
||||
i3 = mock.MagicMock(__name__="i3")
|
||||
self.plugin_ep._initialized = plugin = mock.MagicMock()
|
||||
|
||||
exceptions = zope.interface.exceptions
|
||||
with mock.patch("letsencrypt.client.plugins.disco.zope.interface") as mock_zope:
|
||||
mock_zope.exceptions = exceptions
|
||||
def verify_object(iface, obj):
|
||||
assert obj is plugin
|
||||
assert iface is i1 or iface is i2 or iface is i3
|
||||
if iface is i3:
|
||||
raise mock_zope.exceptions.BrokenImplementation(None, None)
|
||||
mock_zope.verify.verifyObject.side_effect = verify_object
|
||||
self.assertTrue(self.plugin_ep.verify((i1,)))
|
||||
self.assertTrue(self.plugin_ep.verify((i1, i2)))
|
||||
self.assertFalse(self.plugin_ep.verify((i3,)))
|
||||
self.assertFalse(self.plugin_ep.verify((i1, i3)))
|
||||
|
||||
def test_prepare(self):
|
||||
config = mock.MagicMock()
|
||||
self.plugin_ep.init(config=config)
|
||||
self.plugin_ep.prepare()
|
||||
self.assertTrue(self.plugin_ep.prepared)
|
||||
self.assertFalse(self.plugin_ep.misconfigured)
|
||||
str(self.plugin_ep) # output doesn't matter that much, just jest if it runs
|
||||
|
||||
def test_prepare_misconfigured(self):
|
||||
plugin = mock.MagicMock()
|
||||
plugin.prepare.side_effect = errors.LetsEncryptMisconfigurationError
|
||||
self.plugin_ep._initialized = plugin
|
||||
self.assertTrue(isinstance(self.plugin_ep.prepare(),
|
||||
errors.LetsEncryptMisconfigurationError))
|
||||
self.assertTrue(self.plugin_ep.prepared)
|
||||
self.assertTrue(self.plugin_ep.misconfigured)
|
||||
self.assertTrue(self.plugin_ep.available)
|
||||
|
||||
def test_prepare_no_installation(self):
|
||||
plugin = mock.MagicMock()
|
||||
plugin.prepare.side_effect = errors.LetsEncryptNoInstallationError
|
||||
self.plugin_ep._initialized = plugin
|
||||
self.assertTrue(isinstance(self.plugin_ep.prepare(),
|
||||
errors.LetsEncryptNoInstallationError))
|
||||
self.assertTrue(self.plugin_ep.prepared)
|
||||
self.assertFalse(self.plugin_ep.misconfigured)
|
||||
self.assertFalse(self.plugin_ep.available)
|
||||
|
||||
def test_repr(self):
|
||||
self.assertEqual("PluginEntryPoint#sa", repr(self.plugin_ep))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue