summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMonty Taylor <mordred@inaugust.com>2012-11-09 15:49:51 +0100
committerMonty Taylor <mordred@inaugust.com>2012-12-07 23:14:58 -0800
commit70965c3ec5a562200fa414aa25a0a8bc99d20d90 (patch)
tree59cab6958f2f328d7c35475c9d499d356e806c5e
parent86cc905734f81c5363c1dc86ea2bba662bb18892 (diff)
downloadnova-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-xbin/nova-dhcpbridge2
-rw-r--r--nova/test.py248
-rw-r--r--nova/tests/compute/test_rpcapi.py2
-rw-r--r--nova/tests/conf_fixture.py66
-rw-r--r--nova/tests/fake_flags.py49
-rw-r--r--nova/tests/integrated/integrated_helpers.py2
-rw-r--r--nova/tests/network/test_manager.py5
-rw-r--r--nova/tests/test_imagecache.py2
-rw-r--r--nova/tests/test_test.py2
-rw-r--r--nova/tests/xenapi/stubs.py2
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()