Add unit_tests

This commit is contained in:
Marius 2021-03-11 10:25:34 +02:00
parent 67c0d7489b
commit 639fb975f9
4 changed files with 214 additions and 1 deletions

3
.stestr.conf Normal file
View File

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

View File

@ -28,6 +28,7 @@ charm.use_defaults(
@reactive.when('shared-db.available')
@reactive.when('identity-service.available')
@reactive.when('amqp.available')
@reactive.when_not('is-update-status-hook')
def render_config(*interfaces):
with charm.provide_charm_instance() as magnum_charm:
magnum_charm.render_with_interfaces(interfaces)
@ -39,21 +40,26 @@ def render_config(*interfaces):
@reactive.when('shared-db.available')
@reactive.when('identity-service.available')
@reactive.when('amqp.available')
@reactive.when_not('is-update-status-hook')
def render_config_with_certs(amqp, keystone, shared_db, certs):
with charm.provide_charm_instance() as magnum_charm:
magnum_charm.configure_tls(certs)
magnum_charm.render_with_interfaces(
[amqp, keystone, shared_db, certs])
magnum_charm.assess_status()
reactive.set_state('config.complete')
@reactive.when('identity-service.connected')
@reactive.when_not('is-update-status-hook')
def setup_endpoint(keystone):
magnum.setup_endpoint(keystone)
magnum.assess_status()
@reactive.when_not('leadership.set.magnum_password')
@reactive.when('leadership.is_leader')
@reactive.when_not('leadership.set.magnum_password')
@reactive.when_not('is-update-status-hook')
def generate_magnum_password():
passwd = binascii.b2a_hex(os.urandom(32)).decode()
leadership.leader_set({'magnum_password': passwd})
@ -62,6 +68,7 @@ def generate_magnum_password():
@reactive.when('leadership.set.magnum_password')
@reactive.when('leadership.is_leader')
@reactive.when('identity-service.available')
@reactive.when_not('is-update-status-hook')
def write_openrc():
config = hookenv.config()
ctx = context.IdentityServiceContext()()
@ -73,6 +80,7 @@ def write_openrc():
@reactive.when('config.complete')
@reactive.when_not('db.synced')
@reactive.when_not('is-update-status-hook')
def run_db_migration():
with charm.provide_charm_instance() as magnum_charm:
magnum_charm.db_sync()
@ -83,6 +91,7 @@ def run_db_migration():
@reactive.when('ha.connected')
@reactive.when_not('ha.available')
@reactive.when_not('is-update-status-hook')
def connect_cluster(hacluster):
with charm.provide_charm_instance() as magnum_charm:
magnum_charm.configure_ha_resources(hacluster)

View File

@ -0,0 +1,72 @@
# Copyright 2021 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()
import mock
class _fake_decorator(object):
def __init__(self, *args):
pass
def __call__(self, f):
return f
charms = mock.MagicMock()
sys.modules['charms'] = charms
charms.leadership = mock.MagicMock()
sys.modules['charms.leadership'] = charms.leadership
charms.reactive = mock.MagicMock()
charms.reactive.when = _fake_decorator
charms.reactive.when_all = _fake_decorator
charms.reactive.when_any = _fake_decorator
charms.reactive.when_not = _fake_decorator
charms.reactive.when_none = _fake_decorator
charms.reactive.when_not_all = _fake_decorator
charms.reactive.not_unless = _fake_decorator
charms.reactive.when_file_changed = _fake_decorator
charms.reactive.collect_metrics = _fake_decorator
charms.reactive.meter_status_changed = _fake_decorator
charms.reactive.only_once = _fake_decorator
charms.reactive.hook = _fake_decorator
charms.reactive.bus = mock.MagicMock()
charms.reactive.flags = mock.MagicMock()
charms.reactive.relations = mock.MagicMock()
sys.modules['charms.reactive'] = charms.reactive
sys.modules['charms.reactive.bus'] = charms.reactive.bus
sys.modules['charms.reactive.bus'] = charms.reactive.decorators
sys.modules['charms.reactive.flags'] = charms.reactive.flags
sys.modules['charms.reactive.relations'] = charms.reactive.relations
keystoneauth1 = mock.MagicMock()
sys.modules['keystoneauth1'] = keystoneauth1
netaddr = mock.MagicMock()
sys.modules['netaddr'] = netaddr
novaclient = mock.MagicMock()
sys.modules['novaclient'] = novaclient
neutron_lib = mock.MagicMock()
sys.modules['neutron_lib'] = neutron_lib
sys.modules['neutron_lib.constants'] = neutron_lib.constants
neutronclient = mock.MagicMock()
sys.modules['neutronclient'] = neutronclient
sys.modules['neutronclient.v2_0'] = neutronclient.v2_0

View File

@ -0,0 +1,129 @@
# Copyright 2021 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 mock
import charm.openstack.magnum.magnum as magnum
import reactive.magnum_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',
'config.changed',
'update-status',
'upgrade-charm',
'certificates.available',
]
hook_set = {
'when': {
'render_config': (
'shared-db.available',
'identity-service.available',
'amqp.available',),
'render_config_with_certs': (
'certificates.available',
'shared-db.available',
'identity-service.available',
'amqp.available',),
'run_db_migration': ('config.complete',),
'connect_cluster': ('ha.connected',),
'generate_magnum_password': ('leadership.is_leader',),
'generate_heartbeat_key': ('leadership.is_leader',),
'setup_endpoint': ('identity-service.connected',),
'write_openrc': (
'leadership.set.magnum_password',
'leadership.is_leader',
'identity-service.available',),
},
'when_not': {
'run_db_migration': ('db.synced', 'is-update-status-hook'),
'connect_cluster': ('ha.available', 'is-update-status-hook'),
'generate_heartbeat_key': ('leadership.set.heartbeat-key',
'is-update-status-hook'),
'generate_magnum_password': ('leadership.set.magnum_password',
'is-update-status-hook'),
'setup_endpoint': ('is-update-status-hook',),
'render_config': ('is-update-status-hook',),
'render_config_with_certs': ('is-update-status-hook',),
'write_openrc': ('is-update-status-hook',),
},
}
# test that the hooks were registered via the
# reactive.magnum_handlers
self.registered_hooks_test_helper(handlers, hook_set, defaults)
class TestMagnumHandlers(test_utils.PatchHelper):
def setUp(self):
super().setUp()
self.patch_release(magnum.MagnumCharm.release)
self.magnum_charm = mock.MagicMock()
self.patch_object(handlers.charm, 'provide_charm_instance',
new=mock.MagicMock())
self.provide_charm_instance().__enter__.return_value = \
self.magnum_charm
self.provide_charm_instance().__exit__.return_value = None
def test_setup_endpoint(self):
keystone = mock.MagicMock()
charm = magnum.MagnumCharm.singleton
handlers.setup_endpoint(keystone)
keystone.register_endpoints.assert_called_once_with(
charm.service_type,
charm.region,
'{}/v1'.format(charm.public_url),
'{}/v1'.format(charm.internal_url),
'{}/v1'.format(charm.admin_url)
)
def test_render_config(self):
self.patch('charms.reactive.set_state', 'set_state')
handlers.render_config('arg1', 'arg2')
self.magnum_charm.render_with_interfaces.assert_called_once_with(
('arg1', 'arg2'))
self.magnum_charm.assess_status.assert_called_once_with()
self.set_state.assert_called_once_with('config.complete')
def test_render_config_with_certs(self):
self.patch('charms.reactive.set_state', 'set_state')
handlers.render_config_with_certs('arg1', 'arg2', 'arg3', 'arg4')
self.magnum_charm.configure_tls.assert_called_once_with('arg4')
self.magnum_charm.render_with_interfaces.assert_called_once_with(
['arg1', 'arg2', 'arg3', 'arg4'])
self.magnum_charm.assess_status.assert_called_once_with()
self.set_state.assert_called_once_with('config.complete')
def test_run_db_migration(self):
self.patch('charms.reactive.set_state', 'set_state')
handlers.run_db_migration()
self.magnum_charm.db_sync.assert_called_once_with()
self.magnum_charm.restart_all.assert_called_once_with()
self.set_state.assert_called_once_with('db.synced')
self.magnum_charm.assess_status.assert_called_once_with()
def test_connect_cluster(self):
hacluster = mock.MagicMock()
handlers.connect_cluster(hacluster)
self.magnum_charm.configure_ha_resources.assert_called_once_with(
hacluster)
self.magnum_charm.assess_status.assert_called_once_with()