Add unit tests

This commit is contained in:
Liam Young 2019-03-20 09:20:01 +00:00
parent 48b67f6078
commit acad5c7d95
7 changed files with 224 additions and 60 deletions

13
.gitignore vendored
View File

@ -1,7 +1,8 @@
build/
.local/
.testrepository/
.tox/
func-results.json
test-charm/
build
.tox
layers
interfaces
trusty
.testrepository
__pycache__
.stestr

3
.stestr.conf Normal file
View File

@ -0,0 +1,3 @@
[DEFAULT]
test_path=./unit_tests
top_dir=./

View File

@ -35,7 +35,7 @@ def render_config(*args):
available.
"""
with charm.provide_charm_instance() as charm_class:
# charm_class.upgrade_if_available(args)
charm_class.upgrade_if_available(args)
charm_class.render_with_interfaces(args)
charm_class.assess_status()
reactive.set_state('config.rendered')

72
tox.ini
View File

@ -3,21 +3,9 @@
# within individual charm repos.
[tox]
skipsdist = True
envlist = pep8,py34,py35,py27
envlist = pep8,py34,py35
skip_missing_interpreters = True
[bundleenv]
setenv = VIRTUAL_ENV={envdir}
PYTHONHASHSEED=0
TERM=linux
LAYER_PATH={toxinidir}/layers
INTERFACE_PATH={toxinidir}/interfaces
JUJU_REPOSITORY={toxinidir}/build
install_command =
pip install {opts} {packages}
deps =
-r{toxinidir}/requirements.txt
[testenv]
setenv = VIRTUAL_ENV={envdir}
PYTHONHASHSEED=0
@ -25,7 +13,7 @@ setenv = VIRTUAL_ENV={envdir}
LAYER_PATH={toxinidir}/layers
INTERFACE_PATH={toxinidir}/interfaces
JUJU_REPOSITORY={toxinidir}/build
passenv = http_proxy https_proxy CHARM_TEMPLATE_LOCAL_BRANCH
passenv = http_proxy https_proxy
install_command =
pip install {opts} {packages}
deps =
@ -36,36 +24,66 @@ basepython = python2.7
commands =
charm-build --log-level DEBUG -o {toxinidir}/build src {posargs}
[testenv:py27]
basepython = python2.7
# Reactive source charms are Python3-only, but a py27 unit test target
# is required by OpenStack Governance. Remove this shim as soon as
# permitted. https://governance.openstack.org/tc/reference/cti/python_cti.html
whitelist_externals = true
commands = true
[testenv:py34]
basepython = python3.4
deps = -r{toxinidir}/test-requirements.txt
commands = ostestr {posargs}
commands = stestr run {posargs}
[testenv:py35]
basepython = python3.5
deps = -r{toxinidir}/test-requirements.txt
commands = ostestr {posargs}
commands = stestr run {posargs}
[testenv:py36]
basepython = python3.6
deps = -r{toxinidir}/test-requirements.txt
commands = stestr run {posargs}
[testenv:pep8]
basepython = python2.7
basepython = python3
deps = -r{toxinidir}/test-requirements.txt
commands = flake8 {posargs} src unit_tests
[testenv:test_create]
# This tox target is used for template generation testing and can be removed
# from a generated source charm or built charm
basepython = python2.7
deps = -r{toxinidir}/test-generate-requirements.txt
[testenv:cover]
# Technique based heavily upon
# https://github.com/openstack/nova/blob/master/tox.ini
basepython = python3
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
setenv =
CHARM_TEMPLATE_ALT_REPO = {toxinidir}
{[testenv]setenv}
PYTHON=coverage run
commands =
charm-create -t openstack-api -a congress test-charm
/bin/cp test-artifacts/congress.conf.sample {toxinidir}/test-charm/congress/src/templates/congress.conf
# charm-build --log-level DEBUG -o {toxinidir}/test-charm/congress/build {toxinidir}/test-charm/congress/src {posargs}
coverage erase
stestr run {posargs}
coverage combine
coverage html -d cover
coverage xml -o cover/coverage.xml
coverage report
[coverage:run]
branch = True
concurrency = multiprocessing
parallel = True
source =
.
omit =
.tox/*
*/charmhelpers/*
unit_tests/*
[testenv:venv]
basepython = python3
commands = {posargs}
[flake8]
# E402 ignore necessary for path append before sys module import in actions
ignore = E402
ignore = E402

View File

@ -13,34 +13,10 @@
# limitations under the License.
import sys
import mock
sys.path.append('src')
sys.path.append('src/lib')
# Mock out charmhelpers so that we can test without it.
# also stops sideeffects from occuring.
charmhelpers = mock.MagicMock()
apt_pkg = mock.MagicMock()
sys.modules['apt_pkg'] = apt_pkg
sys.modules['charmhelpers'] = charmhelpers
sys.modules['charmhelpers.core'] = charmhelpers.core
sys.modules['charmhelpers.core.decorators'] = charmhelpers.core.decorators
sys.modules['charmhelpers.core.hookenv'] = charmhelpers.core.hookenv
sys.modules['charmhelpers.core.host'] = charmhelpers.core.host
sys.modules['charmhelpers.core.unitdata'] = charmhelpers.core.unitdata
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)
import charms_openstack.test_mocks # noqa
charms_openstack.test_mocks.mock_charmhelpers()

View File

@ -0,0 +1,86 @@
# Copyright 2019 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from __future__ import print_function
import mock
import charmhelpers
import charm.openstack.masakari as masakari
import charms_openstack.test_utils as test_utils
import charms_openstack.charm
class Helper(test_utils.PatchHelper):
def setUp(self):
super().setUp()
self.patch_release(masakari.MasakariCharm.release)
class TestMasakariCharm(Helper):
def _patch_config_and_charm(self, config):
self.patch_object(charmhelpers.core.hookenv, 'config')
def cf(key=None):
if key is not None:
return config[key]
return config
self.config.side_effect = cf
c = masakari.MasakariCharm()
return c
def test_get_amqp_credentials(self):
c = self._patch_config_and_charm({})
self.assertEqual(
c.get_amqp_credentials(),
('masakari', 'masakari'))
def test_get_database_setup(self):
c = self._patch_config_and_charm({})
self.assertEqual(
c.get_database_setup(),
[{'database': 'masakari', 'username': 'masakari'}])
def test_public_url(self):
self.patch_object(charms_openstack.charm.HAOpenStackCharm,
'public_url', new_callable=mock.PropertyMock)
c = self._patch_config_and_charm({})
self.public_url.return_value = 'http://masakari-public'
self.assertEqual(
c.public_url,
'http://masakari-public/v1/%(tenant_id)s')
def test_admin_url(self):
self.patch_object(charms_openstack.charm.HAOpenStackCharm,
'admin_url', new_callable=mock.PropertyMock)
c = self._patch_config_and_charm({})
self.admin_url.return_value = 'http://masakari-admin'
self.assertEqual(
c.admin_url,
'http://masakari-admin/v1/%(tenant_id)s')
def test_internal_url(self):
self.patch_object(charms_openstack.charm.HAOpenStackCharm,
'internal_url', new_callable=mock.PropertyMock)
c = self._patch_config_and_charm({})
self.internal_url.return_value = 'http://masakari-internal'
self.assertEqual(
c.internal_url,
'http://masakari-internal/v1/%(tenant_id)s')

View File

@ -0,0 +1,80 @@
# Copyright 2019 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from __future__ import print_function
import mock
import reactive.masakari_handlers as handlers
import charms_openstack.test_utils as test_utils
class TestRegisteredHooks(test_utils.TestRegisteredHooks):
def test_hooks(self):
defaults = [
'charm.installed',
'amqp.connected',
'shared-db.connected',
'identity-service.connected',
'identity-service.available', # enables SSL support
'config.changed',
'update-status']
hook_set = {
'when': {
'render_config': (
'shared-db.available',
'identity-service.available',
'amqp.available', ),
'init_db': ('config.rendered', ),
'cluster_connected': ('ha.connected', )}
}
self.registered_hooks_test_helper(handlers, hook_set, defaults)
class TestRenderStuff(test_utils.PatchHelper):
def _patch_provide_charm_instance(self):
masakari_charm = mock.MagicMock()
self.patch('charms_openstack.charm.provide_charm_instance',
name='provide_charm_instance',
new=mock.MagicMock())
self.provide_charm_instance().__enter__.return_value = masakari_charm
self.provide_charm_instance().__exit__.return_value = None
return masakari_charm
def test_render_config(self):
self.patch('charms.reactive.set_state', name='set_state')
masakari_charm = self._patch_provide_charm_instance()
handlers.render_config('keystone', 'shared-db', 'amqp')
masakari_charm.upgrade_if_available.assert_called_once_with(
('keystone', 'shared-db', 'amqp'))
masakari_charm.render_with_interfaces.assert_called_once_with(
('keystone', 'shared-db', 'amqp'))
masakari_charm.assess_status.assert_called_once_with()
self.set_state.assert_called_once_with('config.rendered')
def test_init_db(self):
masakari_charm = self._patch_provide_charm_instance()
handlers.init_db()
masakari_charm.db_sync.assert_called_once_with()
def test_cluster_connected(self):
masakari_charm = self._patch_provide_charm_instance()
handlers.cluster_connected('hacluster')
masakari_charm.configure_ha_resources.assert_called_once_with(
'hacluster')
masakari_charm.assess_status.assert_called_once_with()