Add testutils.ConfPatcher and use it in tests

The tests were modifying a global ConfigOpts object, without
resetting the old value, which could affect other tests as well.
The new ConfPatcher class can be used both as a context manager
and as a decorator, making sure that the old value of configuration
option is set back after exiting from the decorated function or from
the context manager.

Change-Id: If23bf225207977e0e313dc806d53bca8a40215d6
This commit is contained in:
Claudiu Popa 2014-11-20 00:31:09 +02:00
parent d32dacd12e
commit fbce2bad36
13 changed files with 88 additions and 55 deletions

View File

@ -31,7 +31,6 @@ CONF = cfg.CONF
class EC2ServiceTest(unittest.TestCase):
def setUp(self):
CONF.set_override('retry_count_interval', 0)
self._service = ec2service.EC2Service()
@mock.patch('cloudbaseinit.utils.network.check_metadata_ip_route')

View File

@ -31,7 +31,6 @@ CONF = cfg.CONF
class HttpServiceTest(unittest.TestCase):
def setUp(self):
CONF.set_override('retry_count_interval', 0)
self._httpservice = httpservice.HttpService()
@mock.patch('cloudbaseinit.utils.network.check_metadata_ip_route')

View File

@ -25,6 +25,7 @@ from oslo.config import cfg
from six.moves.urllib import error
from cloudbaseinit.metadata.services import base
from cloudbaseinit.tests import testutils
from cloudbaseinit.utils import x509constants
if sys.version_info < (3, 0):
@ -47,14 +48,14 @@ class MaaSHttpServiceTest(unittest.TestCase):
@mock.patch("cloudbaseinit.metadata.services.maasservice.MaaSHttpService"
"._get_data")
def _test_load(self, mock_get_data, ip):
CONF.set_override('maas_metadata_url', ip)
response = self._maasservice.load()
if ip is not None:
mock_get_data.assert_called_once_with(
'%s/meta-data/' % self._maasservice._metadata_version)
self.assertTrue(response)
else:
self.assertFalse(response)
with testutils.ConfPatcher('maas_metadata_url', ip):
response = self._maasservice.load()
if ip is not None:
mock_get_data.assert_called_once_with(
'%s/meta-data/' % self._maasservice._metadata_version)
self.assertTrue(response)
else:
self.assertFalse(response)
def test_load(self):
self._test_load(ip='196.254.196.254')
@ -124,17 +125,17 @@ class MaaSHttpServiceTest(unittest.TestCase):
"._get_response")
def test_get_data(self, mock_get_response, mock_Request,
mock_get_oauth_headers):
CONF.set_override('maas_metadata_url', '196.254.196.254')
fake_path = os.path.join('fake', 'path')
mock_get_oauth_headers.return_value = 'fake headers'
response = self._maasservice._get_data(path=fake_path)
norm_path = posixpath.join(CONF.maas_metadata_url, fake_path)
mock_get_oauth_headers.assert_called_once_with(norm_path)
mock_Request.assert_called_once_with(norm_path,
headers='fake headers')
mock_get_response.assert_called_once_with(mock_Request())
self.assertEqual(mock_get_response.return_value.read.return_value,
response)
with testutils.ConfPatcher('maas_metadata_url', '196.254.196.254'):
fake_path = os.path.join('fake', 'path')
mock_get_oauth_headers.return_value = 'fake headers'
response = self._maasservice._get_data(path=fake_path)
norm_path = posixpath.join(CONF.maas_metadata_url, fake_path)
mock_get_oauth_headers.assert_called_once_with(norm_path)
mock_Request.assert_called_once_with(norm_path,
headers='fake headers')
mock_get_response.assert_called_once_with(mock_Request())
self.assertEqual(mock_get_response.return_value.read.return_value,
response)
@mock.patch("cloudbaseinit.metadata.services.maasservice.MaaSHttpService"
"._get_cache_data")

View File

@ -22,6 +22,7 @@ from oslo.config import cfg
from cloudbaseinit.plugins import base
from cloudbaseinit.plugins.windows import createuser
from cloudbaseinit.tests import testutils
CONF = cfg.CONF
@ -38,12 +39,12 @@ class CreateUserPluginTests(unittest.TestCase):
mock_osutils.generate_random_password.assert_called_once_with(14)
self.assertEqual('fake password', response)
@testutils.ConfPatcher('groups', ['Admins'])
@mock.patch('cloudbaseinit.osutils.factory.get_os_utils')
@mock.patch('cloudbaseinit.plugins.windows.createuser.CreateUserPlugin'
'._get_password')
def _test_execute(self, mock_get_password, mock_get_os_utils,
user_exists=True):
CONF.set_override('groups', ['Admins'])
shared_data = {}
mock_token = mock.MagicMock()
mock_osutils = mock.MagicMock()

View File

@ -20,9 +20,8 @@ try:
import unittest.mock as mock
except ImportError:
import mock
from oslo.config import cfg
CONF = cfg.CONF
from cloudbaseinit.tests import testutils
class ExtendVolumesPluginTests(unittest.TestCase):
@ -187,9 +186,9 @@ class ExtendVolumesPluginTests(unittest.TestCase):
self.assertEqual(['fake packs'], response)
def test_get_volumes_to_extend(self):
CONF.set_override('volumes_to_extend', '1')
response = self._extend_volumes._get_volumes_to_extend()
self.assertEqual([1], response)
with testutils.ConfPatcher('volumes_to_extend', '1'):
response = self._extend_volumes._get_volumes_to_extend()
self.assertEqual([1], response)
@mock.patch('cloudbaseinit.utils.windows.vds.load_vds_service')
@mock.patch('cloudbaseinit.plugins.windows.extendvolumes.'
@ -200,7 +199,6 @@ class ExtendVolumesPluginTests(unittest.TestCase):
'ExtendVolumesPlugin._extend_volumes')
def test_execute(self, mock_extend_volumes, mock_query_packs,
mock_query_providers, mock_load_vds_service):
CONF.set_override('volumes_to_extend', '1')
mock_svc = mock.MagicMock()
fake_providers = ['fake providers']
fake_packs = ['fake packs']
@ -210,7 +208,8 @@ class ExtendVolumesPluginTests(unittest.TestCase):
mock_query_providers.return_value = fake_providers
mock_query_packs.return_value = fake_packs
self._extend_volumes.execute(mock_service, fake_data)
with testutils.ConfPatcher('volumes_to_extend', '1'):
self._extend_volumes.execute(mock_service, fake_data)
mock_query_providers.assert_called_once_with(mock_svc)
mock_query_packs.assert_called_once_with('fake providers')

View File

@ -19,13 +19,11 @@ try:
import unittest.mock as mock
except ImportError:
import mock
from oslo.config import cfg
from cloudbaseinit import exception
from cloudbaseinit.plugins import base
from cloudbaseinit.plugins.windows import licensing
CONF = cfg.CONF
from cloudbaseinit.tests import testutils
class WindowsLicensingPluginTests(unittest.TestCase):
@ -86,10 +84,10 @@ class WindowsLicensingPluginTests(unittest.TestCase):
activate_windows):
mock_osutils = mock.MagicMock()
run_slmgr_calls = [mock.call(mock_osutils, ['/dlv'])]
CONF.set_override('activate_windows', activate_windows)
mock_get_os_utils.return_value = mock_osutils
response = self._licensing.execute(service=None, shared_data=None)
with testutils.ConfPatcher('activate_windows', activate_windows):
response = self._licensing.execute(service=None, shared_data=None)
mock_get_os_utils.assert_called_once_with()
if activate_windows:

View File

@ -22,9 +22,7 @@ except ImportError:
from cloudbaseinit.plugins import base
from cloudbaseinit.plugins.windows import localscripts
from oslo.config import cfg
CONF = cfg.CONF
from cloudbaseinit.tests import testutils
class LocalScriptsPluginTests(unittest.TestCase):
@ -45,18 +43,20 @@ class LocalScriptsPluginTests(unittest.TestCase):
sorted(os.path.join(fake_path, f) for f in fake_file_list),
response)
@testutils.ConfPatcher('local_scripts_path',
mock.sentinel.mock_local_scripts_path)
@mock.patch('cloudbaseinit.plugins.windows.localscripts'
'.LocalScriptsPlugin._get_files_in_dir')
@mock.patch('cloudbaseinit.plugins.windows.fileexecutils.exec_file')
def test_execute(self, mock_exec_file, mock_get_files_in_dir):
mock_service = mock.MagicMock()
fake_path = os.path.join('fake', 'path')
CONF.set_override('local_scripts_path', True)
mock_get_files_in_dir.return_value = [fake_path]
response = self._localscripts.execute(mock_service, shared_data=None)
mock_get_files_in_dir.assert_called_once_with(CONF.local_scripts_path)
mock_get_files_in_dir.assert_called_once_with(
mock.sentinel.mock_local_scripts_path)
mock_exec_file.assert_called_once_with(fake_path)
self.assertEqual((base.PLUGIN_EXECUTION_DONE, False), response)

View File

@ -18,15 +18,13 @@ try:
import unittest.mock as mock
except ImportError:
import mock
from oslo.config import cfg
from cloudbaseinit import exception
from cloudbaseinit.plugins import base
from cloudbaseinit.plugins.windows import ntpclient
from cloudbaseinit.tests import testutils
from cloudbaseinit.utils import dhcp
CONF = cfg.CONF
class NTPClientPluginTests(unittest.TestCase):
@ -105,6 +103,7 @@ class NTPClientPluginTests(unittest.TestCase):
fail_service_start=False,
patch_check_os_version=False)
@testutils.ConfPatcher('ntp_use_dhcp_config', True)
@mock.patch('cloudbaseinit.osutils.factory.get_os_utils')
@mock.patch('cloudbaseinit.utils.dhcp.get_dhcp_options')
@mock.patch('cloudbaseinit.plugins.windows.ntpclient.NTPClientPlugin.'
@ -119,7 +118,6 @@ class NTPClientPluginTests(unittest.TestCase):
# see the expected result.
mock_unpack_ntp_hosts.side_effect = original_unpack_hosts
CONF.set_override('ntp_use_dhcp_config', True)
mock_service = mock.MagicMock()
mock_osutils = mock.MagicMock()
mock_options_data = mock.MagicMock()

View File

@ -18,13 +18,11 @@ try:
import unittest.mock as mock
except ImportError:
import mock
from oslo.config import cfg
from cloudbaseinit.plugins import base
from cloudbaseinit.plugins.windows import sethostname
from cloudbaseinit.tests.metadata import fake_json_response
CONF = cfg.CONF
from cloudbaseinit.tests import testutils
class SetHostNamePluginPluginTests(unittest.TestCase):
@ -34,6 +32,7 @@ class SetHostNamePluginPluginTests(unittest.TestCase):
self.fake_data = fake_json_response.get_fake_metadata_json(
'2013-04-04')
@testutils.ConfPatcher('netbios_host_name_compatibility', True)
@mock.patch('platform.node')
@mock.patch('cloudbaseinit.osutils.factory.get_os_utils')
def _test_execute(self, mock_get_os_utils, mock_node, hostname_exists=True,
@ -52,7 +51,6 @@ class SetHostNamePluginPluginTests(unittest.TestCase):
else:
mock_service.get_host_name.return_value = None
CONF.set_override('netbios_host_name_compatibility', True)
mock_get_os_utils.return_value = mock_osutils
if hostname_exists is True:

View File

@ -23,6 +23,7 @@ from oslo.config import cfg
from cloudbaseinit.plugins import constants
from cloudbaseinit.plugins.windows import setuserpassword
from cloudbaseinit.tests.metadata import fake_json_response
from cloudbaseinit.tests import testutils
CONF = cfg.CONF
@ -74,7 +75,6 @@ class SetUserPasswordPluginTests(unittest.TestCase):
mock_service = mock.MagicMock()
mock_osutils = mock.MagicMock()
mock_service.get_admin_password.return_value = 'Passw0rd'
CONF.set_override('inject_user_password', inject_password)
mock_osutils.generate_random_password.return_value = 'Passw0rd'
response = self._setpassword_plugin._get_password(mock_service,
mock_osutils)
@ -85,10 +85,12 @@ class SetUserPasswordPluginTests(unittest.TestCase):
self.assertEqual('Passw0rd', response)
def test_get_password_inject_true(self):
self._test_get_password(inject_password=True)
with testutils.ConfPatcher('inject_user_password', True):
self._test_get_password(inject_password=True)
def test_get_password_inject_false(self):
self._test_get_password(inject_password=False)
with testutils.ConfPatcher('inject_user_password', False):
self._test_get_password(inject_password=False)
@mock.patch('cloudbaseinit.plugins.windows.setuserpassword.'
'SetUserPasswordPlugin._get_ssh_public_key')

View File

@ -19,14 +19,12 @@ try:
import unittest.mock as mock
except ImportError:
import mock
from oslo.config import cfg
from cloudbaseinit import exception
from cloudbaseinit.plugins import base
from cloudbaseinit.plugins.windows import sshpublickeys
from cloudbaseinit.tests.metadata import fake_json_response
CONF = cfg.CONF
from cloudbaseinit.tests import testutils
class SetUserSSHPublicKeysPluginTests(unittest.TestCase):
@ -36,6 +34,7 @@ class SetUserSSHPublicKeysPluginTests(unittest.TestCase):
self.fake_data = fake_json_response.get_fake_metadata_json(
'2013-04-04')
@testutils.ConfPatcher('username', mock.sentinel.username)
@mock.patch('cloudbaseinit.osutils.factory.get_os_utils')
@mock.patch('os.path')
@mock.patch('os.makedirs')
@ -45,7 +44,6 @@ class SetUserSSHPublicKeysPluginTests(unittest.TestCase):
mock_osutils = mock.MagicMock()
fake_shared_data = 'fake data'
mock_service.get_public_keys.return_value = self.fake_data
CONF.set_override('username', 'fake user')
mock_get_os_utils.return_value = mock_osutils
mock_osutils.get_user_home.return_value = user_home
mock_os_path.exists.return_value = False
@ -61,7 +59,8 @@ class SetUserSSHPublicKeysPluginTests(unittest.TestCase):
response = self._set_ssh_keys_plugin.execute(mock_service,
fake_shared_data)
mock_service.get_public_keys.assert_called_with()
mock_osutils.get_user_home.assert_called_with('fake user')
mock_osutils.get_user_home.assert_called_with(
mock.sentinel.username)
self.assertEqual(2, mock_os_path.join.call_count)
mock_os_makedirs.assert_called_once_with(mock_os_path.join())

View File

@ -13,18 +13,24 @@
# under the License.
import contextlib
import functools
import logging as base_logging
import os
import shutil
import tempfile
from oslo.config import cfg
from cloudbaseinit.openstack.common import log as logging
CONF = cfg.CONF
__all__ = (
'create_tempfile',
'create_tempdir',
'LogSnatcher',
'ConfPatcher',
)
@ -108,3 +114,34 @@ class LogSnatcher(object):
def __exit__(self, *args):
self._logger.handlers.remove(self._snatch_handler)
self._logger.logger.setLevel(self._previous_level)
class ConfPatcher(object):
"""Override the configuration for the given key, with the given value.
This class can be used both as a context manager and as a decorator.
"""
# TODO(cpopa): mock.patch.dict would have been a better solution
# but oslo.config.cfg doesn't support item
# assignment.
def __init__(self, key, value, conf=CONF):
self._original_value = conf.get(key)
self._key = key
self._value = value
self._conf = conf
def __call__(self, func, *args, **kwargs):
def _wrapped_f(*args, **kwargs):
with self:
return func(*args, **kwargs)
functools.update_wrapper(_wrapped_f, func)
return _wrapped_f
def __enter__(self):
self._conf.set_override(self._key, self._value)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self._conf.set_override(self._key, self._original_value)

View File

@ -38,6 +38,7 @@ class SerialPortHandlerTests(unittest.TestCase):
self.log = importlib.import_module("cloudbaseinit.utils.log")
self._old_value = CONF.get('logging_serial_port_settings')
CONF.set_override('logging_serial_port_settings', "COM1,115200,N,8")
self._serial_port_handler = self.log.SerialPortHandler()
self._unicode_stream = self._serial_port_handler._UnicodeToBytesStream(
@ -46,6 +47,7 @@ class SerialPortHandlerTests(unittest.TestCase):
def tearDown(self):
self._module_patcher.stop()
CONF.set_override('logging_serial_port_settings', self._old_value)
def test_init(self):
mock_Serial = self._serial.Serial