It was found that the modules test_actions_openstack_upgrade and test_actions_package_upgrade were mocking different classes and functions right before importing the modules under test (openstack_upgrade and package_upgrade respectively), although these mocks weren't being reset making tests executions coming after them to get benefitted (or impacted) by the mocks in memory. This patch takes advantage of mock.patch() decorator at the class level and importlib.reload() to make sure the mocks don't outsurvive the module. When the teardown was in place it was found a different set of functions that were relying on that mocking, so they were patched to allow the tests run in the expected (mock'ed) environment. Summary of changes: - Move get_availability_zone() to contexts module, nova_compute_utils depends on nova_compute_context, the latter shouldn't be importing code from the former since it breaks the layering, even when the import is being done within a function's body. - Mock env variable JUJU_UNIT_NAME per test case, the tests defined in the test_nova_compute_utils and test_nova_compute_contexts were relying on the leakage of mocks set by other test modules, this makes them run in an isolated fashion. - Move update_nrpe_config testing to its own class, the main class NovaComputeRelationsTests mocks the function update_nrpe_config() making it difficult to test it in a test method, hence making the test part of its own class it's posible to not mock the function and correctly runs its implementation. - Teardown mocks made at import level. Func-Test-Pr: https://github.com/openstack-charmers/zaza-openstack-tests/pull/997 Change-Id: I4468ef1a0619befc75c6af2bad8df316125a7cf5
111 lines
3.9 KiB
Python
111 lines
3.9 KiB
Python
# 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 importlib
|
|
import sys
|
|
|
|
from unittest.mock import patch
|
|
|
|
import nova_compute_utils as utils # noqa
|
|
|
|
|
|
from test_utils import (
|
|
CharmTestCase
|
|
)
|
|
|
|
|
|
openstack_upgrade = None # placeholder for module loaded in setUpModule
|
|
TO_PATCH = [
|
|
'config_changed',
|
|
'do_openstack_upgrade'
|
|
]
|
|
|
|
|
|
def setUpModule():
|
|
# to make sure python loads a mocked version of the module we unload it
|
|
# first.
|
|
if 'openstack_upgrade' in sys.modules:
|
|
del sys.modules['openstack_upgrade']
|
|
|
|
with patch('nova_compute_utils.restart_map'):
|
|
with patch('nova_compute_utils.register_configs'):
|
|
global openstack_upgrade
|
|
openstack_upgrade = importlib.import_module('openstack_upgrade')
|
|
|
|
|
|
def tearDownModule():
|
|
# we unload the module since it was mocked, this prevents side effects.
|
|
if 'openstack_upgrade' in sys.modules:
|
|
del sys.modules['openstack_upgrade']
|
|
|
|
|
|
@patch('nova_compute_utils.register_configs')
|
|
@patch('nova_compute_utils.restart_map')
|
|
@patch('charmhelpers.core.hookenv.config')
|
|
@patch('charmhelpers.contrib.openstack.context.HostInfoContext')
|
|
class TestNovaComputeUpgradeActions(CharmTestCase):
|
|
|
|
def setUp(self):
|
|
super(TestNovaComputeUpgradeActions, self).setUp(openstack_upgrade,
|
|
TO_PATCH)
|
|
|
|
@patch('openstack_upgrade.nova_vgpu_joined')
|
|
@patch('openstack_upgrade.nova_ceilometer_joined')
|
|
@patch('openstack_upgrade.neutron_plugin_joined')
|
|
@patch('openstack_upgrade.relation_ids')
|
|
@patch('charmhelpers.contrib.openstack.utils.config')
|
|
@patch('charmhelpers.contrib.openstack.utils.action_set')
|
|
@patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available')
|
|
@patch('charmhelpers.contrib.openstack.utils.juju_log')
|
|
def test_openstack_upgrade_true(self, log, upgrade_avail,
|
|
action_set, config, relation_ids,
|
|
neutron_plugin_joined,
|
|
nova_ceilometer_joined, nova_vgpu_joined,
|
|
*args):
|
|
|
|
upgrade_avail.return_value = True
|
|
config.return_value = True
|
|
|
|
def fake_relation_ids(thing):
|
|
return {'neutron-plugin': ['1'],
|
|
'nova-ceilometer': ['2'],
|
|
'nova-vgpu': ['3']}[thing]
|
|
|
|
relation_ids.side_effect = fake_relation_ids
|
|
|
|
openstack_upgrade.openstack_upgrade()
|
|
|
|
self.assertTrue(self.do_openstack_upgrade.called)
|
|
self.assertTrue(self.config_changed.called)
|
|
neutron_plugin_joined.assert_called_once_with("1", remote_restart=True)
|
|
nova_ceilometer_joined.assert_called_once_with(
|
|
"2", remote_restart=True)
|
|
nova_vgpu_joined.assert_called_once_with(
|
|
"3", remote_restart=True)
|
|
|
|
@patch('charmhelpers.contrib.openstack.utils.config')
|
|
@patch('charmhelpers.contrib.openstack.utils.action_set')
|
|
@patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available')
|
|
@patch('charmhelpers.contrib.openstack.utils.juju_log')
|
|
def test_openstack_upgrade_false(self, log, upgrade_avail,
|
|
action_set, config, *args):
|
|
|
|
upgrade_avail.return_value = True
|
|
config.return_value = False
|
|
|
|
openstack_upgrade.openstack_upgrade()
|
|
|
|
self.assertFalse(self.do_openstack_upgrade.called)
|
|
self.assertFalse(self.config_changed.called)
|