Add unit tests

This commit is contained in:
Liam Young 2019-03-20 09:56:19 +00:00
parent 483b4eb81c
commit f2900159a6
9 changed files with 218 additions and 35 deletions

12
.gitignore vendored
View File

@ -1,8 +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=./

22
__init__.py Normal file
View File

@ -0,0 +1,22 @@
# Copyright 2016 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.
import sys
sys.path.append('src')
sys.path.append('src/lib')
# Mock out charmhelpers so that we can test without it.
import charms_openstack.test_mocks # noqa
charms_openstack.test_mocks.mock_charmhelpers()

View File

@ -1,6 +1,5 @@
import collections
import socket
import subprocess
import charmhelpers.fetch
import charms_openstack.adapters

View File

@ -35,7 +35,6 @@ def render_config(*args):
"""Render the configuration for charm when all the interfaces are
available.
"""
print("Rendering ...")
with charm.provide_charm_instance() as charm_class:
charm_class.render_with_interfaces(args)
charm_class.assess_status()

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

22
unit_tests/__init__.py Normal file
View File

@ -0,0 +1,22 @@
# Copyright 2016 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.
import sys
sys.path.append('src')
sys.path.append('src/lib')
# Mock out charmhelpers so that we can test without it.
import charms_openstack.test_mocks # noqa
charms_openstack.test_mocks.mock_charmhelpers()

View File

@ -0,0 +1,56 @@
# 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_monitors as masakari_monitors
import charms_openstack.test_utils as test_utils
class Helper(test_utils.PatchHelper):
def setUp(self):
super().setUp()
self.patch_release(masakari_monitors.MasakariMonitorsCharm.release)
class TestMasakariMonitorsCharm(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_monitors.MasakariMonitorsCharm()
return c
def test_request_credentials(self):
keystone_relation = mock.MagicMock()
self.patch('charms.reactive.relations.endpoint_from_flag',
name='endpoint_from_flag',
return_value=keystone_relation)
c = self._patch_config_and_charm({})
c.request_credentials()
keystone_relation.request_credentials.assert_called_once_with(
'masakari-monitors', project='services')

View File

@ -0,0 +1,64 @@
# 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_monitors_handlers as handlers
import charms_openstack.test_utils as test_utils
class TestRegisteredHooks(test_utils.TestRegisteredHooks):
def test_hooks(self):
defaults = [
'charm.installed',
'config.changed',
'update-status']
hook_set = {
'when': {
'render_config': ('identity-credentials.available.auth', ),
'request_credentials': ('identity-credentials.connected', )}
}
self.registered_hooks_test_helper(handlers, hook_set, defaults)
class TestHandlers(test_utils.PatchHelper):
def _patch_provide_charm_instance(self):
masakari_monitors_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_monitors_charm
self.provide_charm_instance().__exit__.return_value = None
return masakari_monitors_charm
def test_request_credentials(self):
masakari_charm = self._patch_provide_charm_instance()
handlers.request_credentials()
masakari_charm.request_credentials.assert_called_once_with()
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')
masakari_charm.render_with_interfaces.assert_called_once_with(
('keystone',))
masakari_charm.assess_status.assert_called_once_with()
self.set_state.assert_called_once_with('config.rendered')