Add tests for src/reactive/barbican_handlers.py
This is a simple set of tests that just ensures that future changes to break the events that the charm is listening on.
This commit is contained in:
parent
1ea4507ced
commit
cdfc3d2e04
|
@ -8,9 +8,9 @@ import charmhelpers.fetch
|
|||
import charmhelpers.core.hookenv as hookenv
|
||||
import charmhelpers.contrib.openstack.utils as ch_utils
|
||||
|
||||
import charm.openstack.charm
|
||||
import charm.openstack.adapters
|
||||
import charm.openstack.ip as os_ip
|
||||
import charmers.openstack.charm
|
||||
import charmers.openstack.adapters
|
||||
import charmers.openstack.ip as os_ip
|
||||
|
||||
PACKAGES = ['barbican-common', 'barbican-api', 'barbican-worker',
|
||||
'python-mysqldb']
|
||||
|
@ -70,7 +70,7 @@ def render_configs(interfaces_list):
|
|||
# Implementation of the Barbican Charm classes
|
||||
|
||||
class BarbicanConfigurationAdapter(
|
||||
charm.openstack.adapters.ConfigurationAdapter):
|
||||
charmers.openstack.adapters.ConfigurationAdapter):
|
||||
|
||||
def __init__(self):
|
||||
super(BarbicanConfigurationAdapter, self).__init__()
|
||||
|
@ -95,7 +95,7 @@ class BarbicanConfigurationAdapter(
|
|||
}[self.keystone_api_version]
|
||||
|
||||
|
||||
class BarbicanAdapters(charm.openstack.adapters.OpenStackRelationAdapters):
|
||||
class BarbicanAdapters(charmers.openstack.adapters.OpenStackRelationAdapters):
|
||||
"""
|
||||
Adapters class for the Barbican charm.
|
||||
|
||||
|
@ -107,7 +107,7 @@ class BarbicanAdapters(charm.openstack.adapters.OpenStackRelationAdapters):
|
|||
relations, options=BarbicanConfigurationAdapter)
|
||||
|
||||
|
||||
class BarbicanCharm(charm.openstack.charm.OpenStackCharm):
|
||||
class BarbicanCharm(charmers.openstack.charm.OpenStackCharm):
|
||||
"""BarbicanCharm provides the specialisation of the OpenStackCharm
|
||||
functionality to manage a barbican unit.
|
||||
"""
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
# this is just for the reactive handlers and calls into the charm.
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
sys.path.append('src/lib')
|
||||
|
||||
import charms.reactive as reactive
|
||||
|
||||
print(sys.path)
|
||||
import os
|
||||
print(os.getcwd())
|
||||
print(os.path.dirname(os.path.realpath(__file__)))
|
||||
# This charm's library contains all of the handler code
|
||||
import charm.openstack.barbican as barbican
|
||||
|
||||
|
|
|
@ -11,38 +11,62 @@ sys.path.append('src/lib')
|
|||
import reactive.barbican_handlers as handlers
|
||||
|
||||
|
||||
_hook_args = {}
|
||||
_when_args = {}
|
||||
_when_not_args = {}
|
||||
|
||||
def mock_hook_factory(d):
|
||||
|
||||
def mock_hook(*args, **kwargs):
|
||||
def mock_hook(*args, **kwargs):
|
||||
|
||||
def inner(f):
|
||||
# remember what we were passed. Note that we can't actually determine
|
||||
# the class we're attached to, as the decorator only gets the function.
|
||||
_hook_args[f.__name__] = dict(args=args, kwargs=kwargs)
|
||||
return f
|
||||
return inner
|
||||
def inner(f):
|
||||
# remember what we were passed. Note that we can't actually determine
|
||||
# the class we're attached to, as the decorator only gets the function.
|
||||
try:
|
||||
d[f.__name__].append(dict(args=args, kwargs=kwargs))
|
||||
except KeyError:
|
||||
d[f.__name__] = [dict(args=args, kwargs=kwargs)]
|
||||
return f
|
||||
return inner
|
||||
return mock_hook
|
||||
|
||||
|
||||
class TestBarbicanHandlers(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls._patched_hook = mock.patch('charms.reactive.hook', mock_hook)
|
||||
cls._patched_hook_started = cls._patched_hook.start()
|
||||
cls._patched_when = mock.patch('charms.reactive.when',
|
||||
mock_hook_factory(_when_args))
|
||||
cls._patched_when_started = cls._patched_when.start()
|
||||
cls._patched_when_not = mock.patch('charms.reactive.when_not',
|
||||
mock_hook_factory(_when_not_args))
|
||||
cls._patched_when_not_started = cls._patched_when_not.start()
|
||||
# force requires to rerun the mock_hook decorator:
|
||||
reload(requires)
|
||||
reload(handlers)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls._patched_hook.stop()
|
||||
cls._patched_hook_started = None
|
||||
cls._patched_hook = None
|
||||
cls._patched_when.stop()
|
||||
cls._patched_when_started = None
|
||||
cls._patched_when = None
|
||||
cls._patched_when_not.stop()
|
||||
cls._patched_when_not_started = None
|
||||
cls._patched_when_not = None
|
||||
# and fix any breakage we did to the module
|
||||
reload(requires)
|
||||
reload(handlers)
|
||||
|
||||
def patch(self, attr, return_value=None):
|
||||
mocked = mock.patch.object(self.kr, attr)
|
||||
def setUp(self):
|
||||
self._patches = {}
|
||||
self._patches_start = {}
|
||||
|
||||
def tearDown(self):
|
||||
for k, v in self._patches.items():
|
||||
v.stop()
|
||||
setattr(self, k, None)
|
||||
self._patches = None
|
||||
self._patches_start = None
|
||||
|
||||
def patch(self, obj, attr, return_value=None):
|
||||
mocked = mock.patch.object(obj , attr)
|
||||
self._patches[attr] = mocked
|
||||
started = mocked.start()
|
||||
started.return_value = return_value
|
||||
|
@ -53,11 +77,50 @@ class TestBarbicanHandlers(unittest.TestCase):
|
|||
# test that the hooks actually registered the relation expressions that
|
||||
# are meaningful for this interface: this is to handle regressions.
|
||||
# The keys are the function names that the hook attaches to.
|
||||
hook_patterns = {
|
||||
'joined': ('{requires:keystone}-relation-joined', ),
|
||||
'changed': ('{requires:keystone}-relation-changed', ),
|
||||
'departed': ('{requires:keystone}-relation-{broken,departed}', ),
|
||||
when_patterns = {
|
||||
'setup_amqp_req': ('amqp.connected', ),
|
||||
'setup_database': ('shared-db.connected', ),
|
||||
'setup_endpoint': ('identity-service.connected', ),
|
||||
'render_stuff': ('shared-db.available',
|
||||
'identity-service.available',
|
||||
'amqp.available',),
|
||||
}
|
||||
print(_hook_args)
|
||||
# for k, v in _hook_args.items():
|
||||
# self.assertEqual(hook_patterns[k], v['args'])
|
||||
when_not_patterns = {
|
||||
'install_packages': ('charm.installed', ),
|
||||
}
|
||||
# check the when hooks are attached to the expected functions
|
||||
for t, p in [(_when_args, when_patterns),
|
||||
(_when_not_args, when_not_patterns)]:
|
||||
for f, args in t.items():
|
||||
# check that function is in patterns
|
||||
self.assertTrue(f in p.keys())
|
||||
# check that the lists are equal
|
||||
l = [a['args'][0] for a in args]
|
||||
self.assertEqual(l, sorted(p[f]))
|
||||
|
||||
def test_install_packages(self):
|
||||
self.patch(handlers.barbican, 'install')
|
||||
self.patch(handlers.reactive, 'set_state')
|
||||
handlers.install_packages()
|
||||
self.install.assert_called_once_with()
|
||||
self.set_state.assert_called_once_with('charm.installed')
|
||||
|
||||
def test_setup_amqp_req(self):
|
||||
self.patch(handlers.barbican, 'setup_amqp_req')
|
||||
handlers.setup_amqp_req('amqp_object')
|
||||
self.setup_amqp_req.assert_called_once_with('amqp_object')
|
||||
|
||||
def test_setup_database(self):
|
||||
self.patch(handlers.barbican, 'setup_database')
|
||||
handlers.setup_database('keystone_object')
|
||||
self.setup_database.assert_called_once_with('keystone_object')
|
||||
|
||||
def test_setup_endpoint(self):
|
||||
self.patch(handlers.barbican, 'setup_endpoint')
|
||||
handlers.setup_endpoint('endpoint_object')
|
||||
self.setup_endpoint.assert_called_once_with('endpoint_object')
|
||||
|
||||
def test_render_stuff(self):
|
||||
self.patch(handlers.barbican, 'render_configs')
|
||||
handlers.render_stuff('arg1', 'arg2')
|
||||
self.render_configs.assert_called_once_with(('arg1', 'arg2', ))
|
||||
|
|
Loading…
Reference in New Issue