More coverage for plugins.disco

This commit is contained in:
Jakub Warmuz 2015-05-03 13:21:36 +00:00
parent b600e2d270
commit 1878db3416
No known key found for this signature in database
GPG key ID: 2A7BAD3A489B52EA
2 changed files with 100 additions and 40 deletions

View file

@ -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),

View file

@ -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))