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): class EC2ServiceTest(unittest.TestCase):
def setUp(self): def setUp(self):
CONF.set_override('retry_count_interval', 0)
self._service = ec2service.EC2Service() self._service = ec2service.EC2Service()
@mock.patch('cloudbaseinit.utils.network.check_metadata_ip_route') @mock.patch('cloudbaseinit.utils.network.check_metadata_ip_route')

View File

@ -31,7 +31,6 @@ CONF = cfg.CONF
class HttpServiceTest(unittest.TestCase): class HttpServiceTest(unittest.TestCase):
def setUp(self): def setUp(self):
CONF.set_override('retry_count_interval', 0)
self._httpservice = httpservice.HttpService() self._httpservice = httpservice.HttpService()
@mock.patch('cloudbaseinit.utils.network.check_metadata_ip_route') @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 six.moves.urllib import error
from cloudbaseinit.metadata.services import base from cloudbaseinit.metadata.services import base
from cloudbaseinit.tests import testutils
from cloudbaseinit.utils import x509constants from cloudbaseinit.utils import x509constants
if sys.version_info < (3, 0): if sys.version_info < (3, 0):
@ -47,7 +48,7 @@ class MaaSHttpServiceTest(unittest.TestCase):
@mock.patch("cloudbaseinit.metadata.services.maasservice.MaaSHttpService" @mock.patch("cloudbaseinit.metadata.services.maasservice.MaaSHttpService"
"._get_data") "._get_data")
def _test_load(self, mock_get_data, ip): def _test_load(self, mock_get_data, ip):
CONF.set_override('maas_metadata_url', ip) with testutils.ConfPatcher('maas_metadata_url', ip):
response = self._maasservice.load() response = self._maasservice.load()
if ip is not None: if ip is not None:
mock_get_data.assert_called_once_with( mock_get_data.assert_called_once_with(
@ -124,7 +125,7 @@ class MaaSHttpServiceTest(unittest.TestCase):
"._get_response") "._get_response")
def test_get_data(self, mock_get_response, mock_Request, def test_get_data(self, mock_get_response, mock_Request,
mock_get_oauth_headers): mock_get_oauth_headers):
CONF.set_override('maas_metadata_url', '196.254.196.254') with testutils.ConfPatcher('maas_metadata_url', '196.254.196.254'):
fake_path = os.path.join('fake', 'path') fake_path = os.path.join('fake', 'path')
mock_get_oauth_headers.return_value = 'fake headers' mock_get_oauth_headers.return_value = 'fake headers'
response = self._maasservice._get_data(path=fake_path) response = self._maasservice._get_data(path=fake_path)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -13,18 +13,24 @@
# under the License. # under the License.
import contextlib import contextlib
import functools
import logging as base_logging import logging as base_logging
import os import os
import shutil import shutil
import tempfile import tempfile
from oslo.config import cfg
from cloudbaseinit.openstack.common import log as logging from cloudbaseinit.openstack.common import log as logging
CONF = cfg.CONF
__all__ = ( __all__ = (
'create_tempfile', 'create_tempfile',
'create_tempdir', 'create_tempdir',
'LogSnatcher', 'LogSnatcher',
'ConfPatcher',
) )
@ -108,3 +114,34 @@ class LogSnatcher(object):
def __exit__(self, *args): def __exit__(self, *args):
self._logger.handlers.remove(self._snatch_handler) self._logger.handlers.remove(self._snatch_handler)
self._logger.logger.setLevel(self._previous_level) 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.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") CONF.set_override('logging_serial_port_settings', "COM1,115200,N,8")
self._serial_port_handler = self.log.SerialPortHandler() self._serial_port_handler = self.log.SerialPortHandler()
self._unicode_stream = self._serial_port_handler._UnicodeToBytesStream( self._unicode_stream = self._serial_port_handler._UnicodeToBytesStream(
@ -46,6 +47,7 @@ class SerialPortHandlerTests(unittest.TestCase):
def tearDown(self): def tearDown(self):
self._module_patcher.stop() self._module_patcher.stop()
CONF.set_override('logging_serial_port_settings', self._old_value)
def test_init(self): def test_init(self):
mock_Serial = self._serial.Serial mock_Serial = self._serial.Serial