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:
Alex Kavanagh 2016-05-20 12:30:00 +00:00
parent 1ea4507ced
commit cdfc3d2e04
3 changed files with 93 additions and 38 deletions

View File

@ -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.
"""

View File

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

View File

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