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
|
layers
|
||||||
interfaces
|
interfaces
|
||||||
trusty
|
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
|
LAYER_PATH := layers
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -Rf build .tox
|
rm -Rf build .tox .testrepository
|
||||||
|
|
||||||
generate: clean
|
generate: clean
|
||||||
LAYER_PATH=$(LAYER_PATH) tox -e generate
|
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.
|
# needed on the class.
|
||||||
from __future__ import absolute_import
|
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.charm
|
||||||
import charm.openstack.adapters
|
import charm.openstack.adapters
|
||||||
import charmhelpers.fetch
|
import charm.openstack.ip as os_ip
|
||||||
|
|
||||||
PACKAGES = ['barbican-common', 'barbican-api', 'barbican-worker',
|
PACKAGES = ['barbican-common', 'barbican-api', 'barbican-worker',
|
||||||
'python-mysqldb']
|
'python-mysqldb']
|
||||||
@ -30,16 +34,17 @@ def setup_amqp_req(amqp):
|
|||||||
"""Use the amqp interface to request access to the amqp broker using our
|
"""Use the amqp interface to request access to the amqp broker using our
|
||||||
local configuration.
|
local configuration.
|
||||||
"""
|
"""
|
||||||
amqp.request_access(username=config('rabbit-user'),
|
amqp.request_access(username=hookenv.config('rabbit-user'),
|
||||||
vhost=config('rabbit-vhost'))
|
vhost=hookenv.config('rabbit-vhost'))
|
||||||
|
|
||||||
|
|
||||||
def setup_database(database):
|
def setup_database(database):
|
||||||
"""On receiving database credentials, configure the database on the
|
"""On receiving database credentials, configure the database on the
|
||||||
interface.
|
interface.
|
||||||
"""
|
"""
|
||||||
database.configure(config('database'), config('database-user'),
|
database.configure(hookenv.config('database'),
|
||||||
unit_private_ip())
|
hookenv.config('database-user'),
|
||||||
|
hookenv.unit_private_ip())
|
||||||
|
|
||||||
|
|
||||||
def setup_endpoint(keystone):
|
def setup_endpoint(keystone):
|
||||||
@ -64,11 +69,11 @@ def render_configs(interfaces_list):
|
|||||||
###
|
###
|
||||||
# Implementation of the Barbican Charm classes
|
# Implementation of the Barbican Charm classes
|
||||||
|
|
||||||
class BarbicanConfigurationAdapater(
|
class BarbicanConfigurationAdapter(
|
||||||
charm.openstack.adapters.ConfigurationAdapter):
|
charm.openstack.adapters.ConfigurationAdapter):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(BarbicanConfigurationAdapater, self).__init__()
|
super(BarbicanConfigurationAdapter, self).__init__()
|
||||||
if self.keystone_api_version not in ['2', '3', 'none']:
|
if self.keystone_api_version not in ['2', '3', 'none']:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Unsupported keystone-api-version ({}). It should be 2 or 3"
|
"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.
|
functionality to manage a barbican unit.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
releases = {
|
# don't set releases here (as we need to self refer - see below)
|
||||||
'liberty': BarbicanCharm
|
|
||||||
}
|
|
||||||
first_release = 'liberty'
|
first_release = 'liberty'
|
||||||
name = 'barbican'
|
name = 'barbican'
|
||||||
packages = PACKAGES
|
packages = PACKAGES
|
||||||
api_ports = {
|
api_ports = {
|
||||||
'barbican-api': {
|
'barbican-api': {
|
||||||
PUBLIC: 9311,
|
os_ip.PUBLIC: 9311,
|
||||||
ADMIN: 9312,
|
os_ip.ADMIN: 9312,
|
||||||
INTERNAL: 9313,
|
os_ip.INTERNAL: 9313,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
service_type = 'secretstore'
|
service_type = 'secretstore'
|
||||||
@ -136,14 +139,13 @@ class BarbicanCharm(charm.openstack.charm.OpenStackCharm):
|
|||||||
"""Custom initialiser for class
|
"""Custom initialiser for class
|
||||||
|
|
||||||
If no release is passed, then the charm determines the release from the
|
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:
|
if release is None:
|
||||||
#release = os_release('barbican-common')
|
# release = ch_utils.os_release('barbican-common')
|
||||||
release = os_release('python-keystonemiddleware')
|
release = ch_utils.os_release('python-keystonemiddleware')
|
||||||
super(BarbicanCharm, self).__init__(release=release, **kwargs)
|
super(BarbicanCharm, self).__init__(release=release, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def install(self):
|
def install(self):
|
||||||
"""Customise the installation, configure the source and then call the
|
"""Customise the installation, configure the source and then call the
|
||||||
parent install() method to install the packages
|
parent install() method to install the packages
|
||||||
@ -152,3 +154,11 @@ class BarbicanCharm(charm.openstack.charm.OpenStackCharm):
|
|||||||
self.configure_source()
|
self.configure_source()
|
||||||
# and do the actual install
|
# and do the actual install
|
||||||
super(BarbicanCharm, self).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
|
from __future__ import print_function
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
sys.path.append('lib')
|
sys.path.append('src/lib')
|
||||||
|
|
||||||
import charms.reactive as reactive
|
import charms.reactive as reactive
|
||||||
|
|
||||||
print(sys.path)
|
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
|
# This charm's library contains all of the handler code
|
||||||
import charm.openstack.barbican as barbican
|
import charm.openstack.barbican as barbican
|
||||||
|
|
||||||
|
|
||||||
# use a synthetic state to ensure that it get it to be installed independent of
|
# use a synthetic state to ensure that it get it to be installed independent of
|
||||||
# the install hook.
|
# the install hook.
|
||||||
@reactive.when_not('charm.installed')
|
@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]
|
[testenv:generate]
|
||||||
basepython = python2.7
|
basepython = python2.7
|
||||||
commands =
|
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]
|
[testenv:venv]
|
||||||
commands = {posargs}
|
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…
Reference in New Issue
Block a user