diff options
| author | Monty Taylor <mordred@inaugust.com> | 2012-11-09 15:49:51 +0100 |
|---|---|---|
| committer | Monty Taylor <mordred@inaugust.com> | 2012-12-07 23:14:58 -0800 |
| commit | 70965c3ec5a562200fa414aa25a0a8bc99d20d90 (patch) | |
| tree | 59cab6958f2f328d7c35475c9d499d356e806c5e | |
| parent | 86cc905734f81c5363c1dc86ea2bba662bb18892 (diff) | |
| download | nova-70965c3ec5a562200fa414aa25a0a8bc99d20d90.tar.gz nova-70965c3ec5a562200fa414aa25a0a8bc99d20d90.tar.xz nova-70965c3ec5a562200fa414aa25a0a8bc99d20d90.zip | |
Use fixtures library for nova test fixtures.
Moving the test-case setup and teardown code into managed fixtures
so that we can better interact with them when we start running things
in parallel.
Part of blueprint grizzly-testtools
Change-Id: I406be0a88b14c0dba2d22b4957e26a53442bbae3
| -rwxr-xr-x | bin/nova-dhcpbridge | 2 | ||||
| -rw-r--r-- | nova/test.py | 248 | ||||
| -rw-r--r-- | nova/tests/compute/test_rpcapi.py | 2 | ||||
| -rw-r--r-- | nova/tests/conf_fixture.py | 66 | ||||
| -rw-r--r-- | nova/tests/fake_flags.py | 49 | ||||
| -rw-r--r-- | nova/tests/integrated/integrated_helpers.py | 2 | ||||
| -rw-r--r-- | nova/tests/network/test_manager.py | 5 | ||||
| -rw-r--r-- | nova/tests/test_imagecache.py | 2 | ||||
| -rw-r--r-- | nova/tests/test_test.py | 2 | ||||
| -rw-r--r-- | nova/tests/xenapi/stubs.py | 2 |
10 files changed, 199 insertions, 181 deletions
diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge index 8ff2fac49..0e3d89e65 100755 --- a/bin/nova-dhcpbridge +++ b/bin/nova-dhcpbridge @@ -103,7 +103,7 @@ def main(): logging.setup("nova") if int(os.environ.get('TESTING', '0')): - from nova.tests import fake_flags + from nova.tests import conf_fixture action = argv[1] if action in ['add', 'del', 'old']: diff --git a/nova/test.py b/nova/test.py index 1e9945bbc..9de766b22 100644 --- a/nova/test.py +++ b/nova/test.py @@ -29,12 +29,11 @@ import sys import uuid import eventlet -from fixtures import EnvironmentVariable +import fixtures import mox import stubout import testtools -from nova import config from nova import context from nova import db from nova.db import migration @@ -45,7 +44,7 @@ from nova.openstack.common import log as logging from nova.openstack.common import timeutils from nova import service from nova import tests -from nova.tests import fake_flags +from nova.tests import conf_fixture from nova.tests import policy_fixture from nova.tests import utils @@ -71,63 +70,112 @@ LOG = logging.getLogger(__name__) eventlet.monkey_patch(os=False) -_DB = None +_DB_CACHE = None -def reset_db(): - if CONF.sql_connection == "sqlite://": - engine = get_engine() - engine.dispose() - conn = engine.connect() - if _DB: - conn.connection.executescript(_DB) +class Database(fixtures.Fixture): + + def __init__(self): + self.engine = get_engine() + self.engine.dispose() + conn = self.engine.connect() + if CONF.sql_connection == "sqlite://": + if migration.db_version() > migration.INIT_VERSION: + return + else: + testdb = os.path.join(CONF.state_path, CONF.sqlite_db) + if os.path.exists(testdb): + return + migration.db_sync() + ctxt = context.get_admin_context() + network = network_manager.VlanManager() + bridge_interface = CONF.flat_interface or CONF.vlan_interface + network.create_networks(ctxt, + label='test', + cidr=CONF.fixed_range, + multi_host=CONF.multi_host, + num_networks=CONF.num_networks, + network_size=CONF.network_size, + cidr_v6=CONF.fixed_range_v6, + gateway=CONF.gateway, + gateway_v6=CONF.gateway_v6, + bridge=CONF.flat_network_bridge, + bridge_interface=bridge_interface, + vpn_start=CONF.vpn_start, + vlan_start=CONF.vlan_start, + dns1=CONF.flat_network_dns) + for net in db.network_get_all(ctxt): + network.set_network_host(ctxt, net) + + if CONF.sql_connection == "sqlite://": + conn = self.engine.connect() + self._DB = "".join(line for line in conn.connection.iterdump()) + self.engine.dispose() else: - setup() - else: - shutil.copyfile(os.path.join(CONF.state_path, CONF.sqlite_clean_db), - os.path.join(CONF.state_path, CONF.sqlite_db)) - - -def setup(): - - fake_flags.set_defaults(CONF) - - if CONF.sql_connection == "sqlite://": - if migration.db_version() > migration.INIT_VERSION: - return - else: - testdb = os.path.join(CONF.state_path, CONF.sqlite_db) - if os.path.exists(testdb): - return - migration.db_sync() - ctxt = context.get_admin_context() - network = network_manager.VlanManager() - bridge_interface = CONF.flat_interface or CONF.vlan_interface - network.create_networks(ctxt, - label='test', - cidr=CONF.fixed_range, - multi_host=CONF.multi_host, - num_networks=CONF.num_networks, - network_size=CONF.network_size, - cidr_v6=CONF.fixed_range_v6, - gateway=CONF.gateway, - gateway_v6=CONF.gateway_v6, - bridge=CONF.flat_network_bridge, - bridge_interface=bridge_interface, - vpn_start=CONF.vpn_start, - vlan_start=CONF.vlan_start, - dns1=CONF.flat_network_dns) - for net in db.network_get_all(ctxt): - network.set_network_host(ctxt, net) - - if CONF.sql_connection == "sqlite://": - global _DB - engine = get_engine() - conn = engine.connect() - _DB = "".join(line for line in conn.connection.iterdump()) - else: - cleandb = os.path.join(CONF.state_path, CONF.sqlite_clean_db) - shutil.copyfile(testdb, cleandb) + cleandb = os.path.join(CONF.state_path, CONF.sqlite_clean_db) + shutil.copyfile(testdb, cleandb) + + def setUp(self): + super(Database, self).setUp() + + if CONF.sql_connection == "sqlite://": + conn = self.engine.connect() + conn.connection.executescript(self._DB) + self.addCleanup(self.engine.dispose) + else: + shutil.copyfile(os.path.join(CONF.state_path, + CONF.sqlite_clean_db), + os.path.join(CONF.state_path, + CONF.sqlite_db)) + + +class ReplaceModule(fixtures.Fixture): + """Replace a module with a fake module.""" + + def __init__(self, name, new_value): + self.name = name + self.new_value = new_value + + def _restore(self, old_value): + sys.modules[self.name] = old_value + + def setUp(self): + super(ReplaceModule, self).setUp() + old_value = sys.modules.get(self.name) + sys.modules[self.name] = self.new_value + self.addCleanup(self._restore, old_value) + + +class ServiceFixture(fixtures.Fixture): + """Run a service as a test fixture.""" + + def __init__(self, name, host=None, **kwargs): + name = name + host = host and host or uuid.uuid4().hex + kwargs.setdefault('host', host) + kwargs.setdefault('binary', 'nova-%s' % name) + self.kwargs = kwargs + + def setUp(self): + super(ServiceFixture, self).setUp() + self.service = service.Service.create(**self.kwargs) + self.service.start() + self.addCleanup(self.service.kill) + + +class MoxStubout(fixtures.Fixture): + """Deal with code around mox and stubout as a fixture.""" + + def setUp(self): + super(MoxStubout, self).setUp() + # emulate some of the mox stuff, we can't use the metaclass + # because it screws with our generators + self.mox = mox.Mox() + self.stubs = stubout.StubOutForTesting() + self.addCleanup(self.mox.UnsetStubs) + self.addCleanup(self.stubs.UnsetAll) + self.addCleanup(self.stubs.SmartUnsetAll) + self.addCleanup(self.mox.VerifyAll) class TestingException(Exception): @@ -141,70 +189,27 @@ class TestCase(testtools.TestCase): """Run before each test method to initialize test environment.""" super(TestCase, self).setUp() - fake_flags.set_defaults(CONF) - config.parse_args([], default_config_files=[]) + self.log_fixture = self.useFixture(fixtures.FakeLogger('nova')) + self.useFixture(conf_fixture.ConfFixture(CONF)) - # NOTE(vish): We need a better method for creating fixtures for tests - # now that we have some required db setup for the system - # to work properly. - self.start = timeutils.utcnow() - reset_db() + global _DB_CACHE + if not _DB_CACHE: + _DB_CACHE = Database() + self.useFixture(_DB_CACHE) - # emulate some of the mox stuff, we can't use the metaclass - # because it screws with our generators - self.mox = mox.Mox() - self.stubs = stubout.StubOutForTesting() - self.injected = [] - self._services = [] - self._modules = {} - self.useFixture(EnvironmentVariable('http_proxy')) + mox_fixture = self.useFixture(MoxStubout()) + self.mox = mox_fixture.mox + self.stubs = mox_fixture.stubs + self.addCleanup(self._clear_attrs) + self.useFixture(fixtures.EnvironmentVariable('http_proxy')) self.policy = self.useFixture(policy_fixture.PolicyFixture()) - def tearDown(self): - """Runs after each test method to tear down test environment.""" - try: - utils.cleanup_dns_managers() - self.mox.UnsetStubs() - self.stubs.UnsetAll() - self.stubs.SmartUnsetAll() - self.mox.VerifyAll() - super(TestCase, self).tearDown() - finally: - # Reset any overridden flags - CONF.reset() - - # Unstub modules - for name, mod in self._modules.iteritems(): - if mod is not None: - sys.modules[name] = mod - else: - sys.modules.pop(name) - self._modules = {} - - # Stop any timers - for x in self.injected: - try: - x.stop() - except AssertionError: - pass - - # Kill any services - for x in self._services: - try: - x.kill() - except Exception: - pass - - # Delete attributes that don't start with _ so they don't pin - # memory around unnecessarily for the duration of the test - # suite - for key in [k for k in self.__dict__.keys() if k[0] != '_']: - del self.__dict__[key] - - def stub_module(self, name, mod): - if name not in self._modules: - self._modules[name] = sys.modules.get(name) - sys.modules[name] = mod + def _clear_attrs(self): + # Delete attributes that don't start with _ so they don't pin + # memory around unnecessarily for the duration of the test + # suite + for key in [k for k in self.__dict__.keys() if k[0] != '_']: + del self.__dict__[key] def flags(self, **kw): """Override flag variables for a test.""" @@ -213,10 +218,5 @@ class TestCase(testtools.TestCase): CONF.set_override(k, v, group) def start_service(self, name, host=None, **kwargs): - host = host and host or uuid.uuid4().hex - kwargs.setdefault('host', host) - kwargs.setdefault('binary', 'nova-%s' % name) - svc = service.Service.create(**kwargs) - svc.start() - self._services.append(svc) - return svc + svc = self.useFixture(ServiceFixture(name, host, **kwargs)) + return svc.service diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py index 54d8d47c7..437daaa14 100644 --- a/nova/tests/compute/test_rpcapi.py +++ b/nova/tests/compute/test_rpcapi.py @@ -33,11 +33,11 @@ CONF.import_opt('compute_topic', 'nova.config') class ComputeRpcAPITestCase(test.TestCase): def setUp(self): + super(ComputeRpcAPITestCase, self).setUp() self.context = context.get_admin_context() inst = db.instance_create(self.context, {'host': 'fake_host', 'instance_type_id': 1}) self.fake_instance = jsonutils.to_primitive(inst) - super(ComputeRpcAPITestCase, self).setUp() def test_serialized_instance_has_name(self): self.assertTrue('name' in self.fake_instance) diff --git a/nova/tests/conf_fixture.py b/nova/tests/conf_fixture.py new file mode 100644 index 000000000..c0466447d --- /dev/null +++ b/nova/tests/conf_fixture.py @@ -0,0 +1,66 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# 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 fixtures + +from nova import config +from nova.openstack.common import cfg + +CONF = cfg.CONF +CONF.import_opt('state_path', 'nova.config') +CONF.import_opt('scheduler_driver', 'nova.scheduler.manager') +CONF.import_opt('fake_network', 'nova.network.manager') +CONF.import_opt('network_size', 'nova.network.manager') +CONF.import_opt('num_networks', 'nova.network.manager') +CONF.import_opt('policy_file', 'nova.policy') +CONF.import_opt('compute_driver', 'nova.virt.driver') + + +class ConfFixture(fixtures.Fixture): + """Fixture to manage global conf settings.""" + + def __init__(self, conf): + self.conf = conf + + def setUp(self): + super(ConfFixture, self).setUp() + + self.conf.set_default('api_paste_config', + '$state_path/etc/nova/api-paste.ini') + self.conf.set_default('compute_driver', 'nova.virt.fake.FakeDriver') + self.conf.set_default('fake_network', True) + self.conf.set_default('fake_rabbit', True) + self.conf.set_default('flat_network_bridge', 'br100') + self.conf.set_default('floating_ip_dns_manager', + 'nova.tests.utils.dns_manager') + self.conf.set_default('instance_dns_manager', + 'nova.tests.utils.dns_manager') + self.conf.set_default('lock_path', None) + self.conf.set_default('network_size', 8) + self.conf.set_default('num_networks', 2) + self.conf.set_default('rpc_backend', + 'nova.openstack.common.rpc.impl_fake') + self.conf.set_default('rpc_cast_timeout', 5) + self.conf.set_default('rpc_response_timeout', 5) + self.conf.set_default('sql_connection', "sqlite://") + self.conf.set_default('sqlite_synchronous', False) + self.conf.set_default('use_ipv6', True) + self.conf.set_default('verbose', True) + self.conf.set_default('vlan_interface', 'eth0') + config.parse_args([], default_config_files=[]) + self.addCleanup(self.conf.reset) diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py deleted file mode 100644 index 83ec33cab..000000000 --- a/nova/tests/fake_flags.py +++ /dev/null @@ -1,49 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# 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. - -from nova.openstack.common import cfg - -CONF = cfg.CONF -CONF.import_opt('state_path', 'nova.config') -CONF.import_opt('scheduler_driver', 'nova.scheduler.manager') -CONF.import_opt('fake_network', 'nova.network.manager') -CONF.import_opt('network_size', 'nova.network.manager') -CONF.import_opt('num_networks', 'nova.network.manager') -CONF.import_opt('policy_file', 'nova.policy') -CONF.import_opt('compute_driver', 'nova.virt.driver') - - -def set_defaults(conf): - conf.set_default('api_paste_config', '$state_path/etc/nova/api-paste.ini') - conf.set_default('compute_driver', 'nova.virt.fake.FakeDriver') - conf.set_default('fake_network', True) - conf.set_default('fake_rabbit', True) - conf.set_default('flat_network_bridge', 'br100') - conf.set_default('network_size', 8) - conf.set_default('num_networks', 2) - conf.set_default('vlan_interface', 'eth0') - conf.set_default('rpc_backend', 'nova.openstack.common.rpc.impl_fake') - conf.set_default('sql_connection', "sqlite://") - conf.set_default('sqlite_synchronous', False) - conf.set_default('use_ipv6', True) - conf.set_default('verbose', True) - conf.set_default('rpc_response_timeout', 5) - conf.set_default('rpc_cast_timeout', 5) - conf.set_default('lock_path', None) - conf.set_default('floating_ip_dns_manager', 'nova.tests.utils.dns_manager') - conf.set_default('instance_dns_manager', 'nova.tests.utils.dns_manager') diff --git a/nova/tests/integrated/integrated_helpers.py b/nova/tests/integrated/integrated_helpers.py index 7c316aaa8..1f6a278cf 100644 --- a/nova/tests/integrated/integrated_helpers.py +++ b/nova/tests/integrated/integrated_helpers.py @@ -67,7 +67,7 @@ class _IntegratedTestBase(test.TestCase): self.flags(**f) self.flags(verbose=True) - self.stub_module('crypto', fake_crypto) + self.useFixture(test.ReplaceModule('crypto', fake_crypto)) nova.tests.image.fake.stub_out_image_service(self.stubs) self.flags(scheduler_driver='nova.scheduler.' 'chance.ChanceScheduler') diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py index b12d12167..2c04806b7 100644 --- a/nova/tests/network/test_manager.py +++ b/nova/tests/network/test_manager.py @@ -15,10 +15,11 @@ # 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 mox import shutil import tempfile +import mox + from nova import context from nova import db from nova.db.sqlalchemy import models @@ -1998,7 +1999,7 @@ class LdapDNSTestCase(test.TestCase): def setUp(self): super(LdapDNSTestCase, self).setUp() - self.stub_module('ldap', fake_ldap) + self.useFixture(test.ReplaceModule('ldap', fake_ldap)) dns_class = 'nova.network.ldapdns.LdapDNS' self.driver = importutils.import_object(dns_class) diff --git a/nova/tests/test_imagecache.py b/nova/tests/test_imagecache.py index 2a927b362..bfa948ce5 100644 --- a/nova/tests/test_imagecache.py +++ b/nova/tests/test_imagecache.py @@ -763,7 +763,7 @@ class ImageCacheManagerTestCase(test.TestCase): def listdir(path): # The python coverage tool got angry with my overly broad mocks if not path.startswith('/instance_path'): - return orig_list(path) + return orig_listdir(path) if path == '/instance_path': return ['instance-1', 'instance-2', 'instance-3', '_base'] diff --git a/nova/tests/test_test.py b/nova/tests/test_test.py index f89a5bb94..2e045b2ac 100644 --- a/nova/tests/test_test.py +++ b/nova/tests/test_test.py @@ -30,7 +30,7 @@ class IsolationTestCase(test.TestCase): """ def test_service_isolation(self): - self.start_service('compute') + self.useFixture(test.ServiceFixture('compute')) def test_rpc_consumer_isolation(self): class NeverCalled(object): diff --git a/nova/tests/xenapi/stubs.py b/nova/tests/xenapi/stubs.py index 560e12d70..ca8281295 100644 --- a/nova/tests/xenapi/stubs.py +++ b/nova/tests/xenapi/stubs.py @@ -352,6 +352,6 @@ class XenAPITestBase(test.TestCase): def setUp(self): super(XenAPITestBase, self).setUp() - self.stub_module('XenAPI', fake) + self.useFixture(test.ReplaceModule('XenAPI', fake)) fake.reset() |
