Initial unit_tests added - NOT FUNCTIONAL at this stage
This adds in the unit_test framework but there is a name collision between charm.openstack as a module, and charm.openstack here which the package loader can't resolve. Therefore, going to change the charm.openstack package to charms.openstack to avoid the collision.
This commit is contained in:
parent
c7fc7ba5e0
commit
1ea4507ced
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ build
|
||||
layers
|
||||
interfaces
|
||||
trusty
|
||||
.testrepository
|
||||
|
8
.testr.conf
Normal file
8
.testr.conf
Normal file
@ -0,0 +1,8 @@
|
||||
[DEFAULT]
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ ./unit_tests $LISTOPT $IDOPTION
|
||||
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
9
Makefile
9
Makefile
@ -2,7 +2,14 @@
|
||||
LAYER_PATH := layers
|
||||
|
||||
clean:
|
||||
rm -Rf build .tox
|
||||
rm -Rf build .tox .testrepository
|
||||
|
||||
generate: clean
|
||||
LAYER_PATH=$(LAYER_PATH) tox -e generate
|
||||
|
||||
lint:
|
||||
@tox -e lint
|
||||
|
||||
test:
|
||||
@echo Starting unit tests...
|
||||
@tox -e py27
|
||||
|
0
src/lib/__init__.py
Normal file
0
src/lib/__init__.py
Normal file
0
src/lib/charm/__init__.py
Normal file
0
src/lib/charm/__init__.py
Normal file
0
src/lib/charm/openstack/__init__.py
Normal file
0
src/lib/charm/openstack/__init__.py
Normal file
@ -4,9 +4,13 @@
|
||||
# needed on the class.
|
||||
from __future__ import absolute_import
|
||||
|
||||
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 charmhelpers.fetch
|
||||
import charm.openstack.ip as os_ip
|
||||
|
||||
PACKAGES = ['barbican-common', 'barbican-api', 'barbican-worker',
|
||||
'python-mysqldb']
|
||||
@ -30,16 +34,17 @@ def setup_amqp_req(amqp):
|
||||
"""Use the amqp interface to request access to the amqp broker using our
|
||||
local configuration.
|
||||
"""
|
||||
amqp.request_access(username=config('rabbit-user'),
|
||||
vhost=config('rabbit-vhost'))
|
||||
amqp.request_access(username=hookenv.config('rabbit-user'),
|
||||
vhost=hookenv.config('rabbit-vhost'))
|
||||
|
||||
|
||||
def setup_database(database):
|
||||
"""On receiving database credentials, configure the database on the
|
||||
interface.
|
||||
"""
|
||||
database.configure(config('database'), config('database-user'),
|
||||
unit_private_ip())
|
||||
database.configure(hookenv.config('database'),
|
||||
hookenv.config('database-user'),
|
||||
hookenv.unit_private_ip())
|
||||
|
||||
|
||||
def setup_endpoint(keystone):
|
||||
@ -64,11 +69,11 @@ def render_configs(interfaces_list):
|
||||
###
|
||||
# Implementation of the Barbican Charm classes
|
||||
|
||||
class BarbicanConfigurationAdapater(
|
||||
class BarbicanConfigurationAdapter(
|
||||
charm.openstack.adapters.ConfigurationAdapter):
|
||||
|
||||
def __init__(self):
|
||||
super(BarbicanConfigurationAdapater, self).__init__()
|
||||
super(BarbicanConfigurationAdapter, self).__init__()
|
||||
if self.keystone_api_version not in ['2', '3', 'none']:
|
||||
raise ValueError(
|
||||
"Unsupported keystone-api-version ({}). It should be 2 or 3"
|
||||
@ -107,17 +112,15 @@ class BarbicanCharm(charm.openstack.charm.OpenStackCharm):
|
||||
functionality to manage a barbican unit.
|
||||
"""
|
||||
|
||||
releases = {
|
||||
'liberty': BarbicanCharm
|
||||
}
|
||||
# don't set releases here (as we need to self refer - see below)
|
||||
first_release = 'liberty'
|
||||
name = 'barbican'
|
||||
packages = PACKAGES
|
||||
api_ports = {
|
||||
'barbican-api': {
|
||||
PUBLIC: 9311,
|
||||
ADMIN: 9312,
|
||||
INTERNAL: 9313,
|
||||
os_ip.PUBLIC: 9311,
|
||||
os_ip.ADMIN: 9312,
|
||||
os_ip.INTERNAL: 9313,
|
||||
}
|
||||
}
|
||||
service_type = 'secretstore'
|
||||
@ -136,14 +139,13 @@ class BarbicanCharm(charm.openstack.charm.OpenStackCharm):
|
||||
"""Custom initialiser for class
|
||||
|
||||
If no release is passed, then the charm determines the release from the
|
||||
os_release() function.
|
||||
ch_utils.os_release() function.
|
||||
"""
|
||||
if release is None:
|
||||
#release = os_release('barbican-common')
|
||||
release = os_release('python-keystonemiddleware')
|
||||
# release = ch_utils.os_release('barbican-common')
|
||||
release = ch_utils.os_release('python-keystonemiddleware')
|
||||
super(BarbicanCharm, self).__init__(release=release, **kwargs)
|
||||
|
||||
|
||||
def install(self):
|
||||
"""Customise the installation, configure the source and then call the
|
||||
parent install() method to install the packages
|
||||
@ -152,3 +154,11 @@ class BarbicanCharm(charm.openstack.charm.OpenStackCharm):
|
||||
self.configure_source()
|
||||
# and do the actual install
|
||||
super(BarbicanCharm, self).install()
|
||||
|
||||
|
||||
# Set Barbican releases here because we need it to refer to itself. For derived
|
||||
# classes of BarbicanCharm for different series we would still set the releases
|
||||
# here.
|
||||
BarbicanCharm.releases = {
|
||||
'liberty': BarbicanCharm,
|
||||
}
|
||||
|
0
src/reactive/__init__.py
Normal file
0
src/reactive/__init__.py
Normal file
@ -3,14 +3,18 @@ from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
sys.path.append('lib')
|
||||
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
|
||||
|
||||
|
||||
# use a synthetic state to ensure that it get it to be installed independent of
|
||||
# the install hook.
|
||||
@reactive.when_not('charm.installed')
|
||||
|
7
test-requirements.txt
Normal file
7
test-requirements.txt
Normal file
@ -0,0 +1,7 @@
|
||||
flake8>=2.2.4,<=2.4.1
|
||||
os-testr>=0.4.1
|
||||
charm-tools>=2.0.0
|
||||
charms.reactive
|
||||
mock>=1.2
|
||||
coverage>=3.6
|
||||
https://github.com/ajkavanagh/charm.openstack/zipball/master
|
15
tox.ini
15
tox.ini
@ -18,7 +18,20 @@ deps =
|
||||
[testenv:generate]
|
||||
basepython = python2.7
|
||||
commands =
|
||||
charm build --log-level DEBUG -o {toxinidir}/build charm
|
||||
charm build --log-level DEBUG -o {toxinidir}/build src
|
||||
|
||||
[testenv:py27]
|
||||
basepython = python2.7
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = ostestr {posargs}
|
||||
|
||||
[testenv:lint]
|
||||
basepython = python2.7
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = flake8 {posargs} src unit_tests
|
||||
|
||||
[testenv:venv]
|
||||
commands = {posargs}
|
||||
|
||||
[flake8]
|
||||
ignore = E402,E226
|
||||
|
24
unit_tests/__init__.py
Normal file
24
unit_tests/__init__.py
Normal file
@ -0,0 +1,24 @@
|
||||
import sys
|
||||
import mock
|
||||
|
||||
|
||||
charmhelpers = mock.MagicMock()
|
||||
sys.modules['charmhelpers'] = charmhelpers
|
||||
sys.modules['charmhelpers.core'] = charmhelpers.core
|
||||
sys.modules['charmhelpers.core.hookenv'] = charmhelpers.core.hookenv
|
||||
sys.modules['charmhelpers.core.host'] = charmhelpers.core.host
|
||||
sys.modules['charmhelpers.core.templating'] = charmhelpers.core.templating
|
||||
sys.modules['charmhelpers.contrib'] = charmhelpers.contrib
|
||||
sys.modules['charmhelpers.contrib.openstack'] = charmhelpers.contrib.openstack
|
||||
sys.modules['charmhelpers.contrib.openstack.utils'] = (
|
||||
charmhelpers.contrib.openstack.utils)
|
||||
sys.modules['charmhelpers.contrib.openstack.templating'] = (
|
||||
charmhelpers.contrib.openstack.templating)
|
||||
sys.modules['charmhelpers.contrib.network'] = charmhelpers.contrib.network
|
||||
sys.modules['charmhelpers.contrib.network.ip'] = (
|
||||
charmhelpers.contrib.network.ip)
|
||||
sys.modules['charmhelpers.fetch'] = charmhelpers.fetch
|
||||
sys.modules['charmhelpers.cli'] = charmhelpers.cli
|
||||
sys.modules['charmhelpers.contrib.hahelpers'] = charmhelpers.contrib.hahelpers
|
||||
sys.modules['charmhelpers.contrib.hahelpers.cluster'] = (
|
||||
charmhelpers.contrib.hahelpers.cluster)
|
63
unit_tests/test_barbican_handlers.py
Normal file
63
unit_tests/test_barbican_handlers.py
Normal file
@ -0,0 +1,63 @@
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
|
||||
sys.path.append('src')
|
||||
sys.path.append('src/lib')
|
||||
import reactive.barbican_handlers as handlers
|
||||
|
||||
|
||||
_hook_args = {}
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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()
|
||||
# force requires to rerun the mock_hook decorator:
|
||||
reload(requires)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls._patched_hook.stop()
|
||||
cls._patched_hook_started = None
|
||||
cls._patched_hook = None
|
||||
# and fix any breakage we did to the module
|
||||
reload(requires)
|
||||
|
||||
def patch(self, attr, return_value=None):
|
||||
mocked = mock.patch.object(self.kr, attr)
|
||||
self._patches[attr] = mocked
|
||||
started = mocked.start()
|
||||
started.return_value = return_value
|
||||
self._patches_start[attr] = started
|
||||
setattr(self, attr, started)
|
||||
|
||||
def test_registered_hooks(self):
|
||||
# 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}', ),
|
||||
}
|
||||
print(_hook_args)
|
||||
# for k, v in _hook_args.items():
|
||||
# self.assertEqual(hook_patterns[k], v['args'])
|
Loading…
x
Reference in New Issue
Block a user