Files
charm-nova-compute/unit_tests/test_actions_openstack_upgrade.py
Felipe Reyes 75a3dbd0ef Refactor unit tests to avoid leaks of mocks.
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
2023-02-20 11:37:01 -03:00

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)