Fix up the test framework

When trying to test a bug the cinder test framework was
running all the tests when I just wanted one to run.

Instead of fixing this problem in nose I tried to move cinder to
testr. I copied a fair bit of code from nova to get this to work.
This way at least if some one makes an improvement to the nova
test framework cinder can improve here also.

Note that now all the tests a thread safe. Added a concurrency argument
to run_tests.sh that defaults to 1. You can specify your own level then
and take the risk of intermittent failures. Tell jenkins to use a
concurrency level of 1 to avoid failing gate jobs.

Note One of these tests is broken and I have disabled for now. There
is a bug for this here: https://bugs.launchpad.net/cinder/+bug/1173266

Note: cinder.api.openstack.FaultWrapper is deprecated and is causing
a circular import when I try and import cinder.tests.test_wsgi. This
is fixed by only importing the openstack.FaultWrapper during the
__init__ phase of the wsgi middleware.

Fixes: bug 1183434
Fixes: bug 1177924

Change-Id: I5e10b55c5b236eb81a6a3e0e9ea56af8ca4ef8e1
This commit is contained in:
Michael Kerrin
2013-05-16 08:10:27 +00:00
parent 0a26b70c98
commit 930f5891b0
16 changed files with 632 additions and 196 deletions

View File

@@ -25,6 +25,7 @@ inline callbacks.
import functools
import os
import shutil
import uuid
import fixtures
@@ -33,11 +34,12 @@ from oslo.config import cfg
import stubout
import testtools
from cinder.db import migration
from cinder import flags
from cinder.openstack.common.db.sqlalchemy import session
from cinder.openstack.common import log as logging
from cinder.openstack.common import timeutils
from cinder import service
from cinder import tests
from cinder.tests import fake_flags
test_opts = [
@@ -53,11 +55,54 @@ FLAGS.register_opts(test_opts)
LOG = logging.getLogger(__name__)
_DB_CACHE = None
class TestingException(Exception):
pass
class Database(fixtures.Fixture):
def __init__(self, db_session, db_migrate, sql_connection,
sqlite_db, sqlite_clean_db):
self.sql_connection = sql_connection
self.sqlite_db = sqlite_db
self.sqlite_clean_db = sqlite_clean_db
self.engine = db_session.get_engine()
self.engine.dispose()
conn = self.engine.connect()
if sql_connection == "sqlite://":
if db_migrate.db_version() > db_migrate.INIT_VERSION:
return
else:
testdb = os.path.join(FLAGS.state_path, sqlite_db)
if os.path.exists(testdb):
return
db_migrate.db_sync()
# self.post_migrations()
if sql_connection == "sqlite://":
conn = self.engine.connect()
self._DB = "".join(line for line in conn.connection.iterdump())
self.engine.dispose()
else:
cleandb = os.path.join(FLAGS.state_path, sqlite_clean_db)
shutil.copyfile(testdb, cleandb)
def setUp(self):
super(Database, self).setUp()
if self.sql_connection == "sqlite://":
conn = self.engine.connect()
conn.connection.executescript(self._DB)
self.addCleanup(self.engine.dispose)
else:
shutil.copyfile(
os.path.join(FLAGS.state_path, self.sqlite_clean_db),
os.path.join(FLAGS.state_path, self.sqlite_db))
class TestCase(testtools.TestCase):
"""Test case base class for all unit tests."""
@@ -94,7 +139,19 @@ class TestCase(testtools.TestCase):
# now that we have some required db setup for the system
# to work properly.
self.start = timeutils.utcnow()
tests.reset_db()
FLAGS.set_default('connection', 'sqlite://', 'database')
FLAGS.set_default('sqlite_synchronous', False)
self.log_fixture = self.useFixture(fixtures.FakeLogger())
global _DB_CACHE
if not _DB_CACHE:
_DB_CACHE = Database(session, migration,
sql_connection=FLAGS.database.connection,
sqlite_db=FLAGS.sqlite_db,
sqlite_clean_db=FLAGS.sqlite_clean_db)
self.useFixture(_DB_CACHE)
# emulate some of the mox stuff, we can't use the metaclass
# because it screws with our generators
@@ -107,6 +164,7 @@ class TestCase(testtools.TestCase):
self.addCleanup(self.mox.VerifyAll)
self.injected = []
self._services = []
FLAGS.set_override('fatal_exception_format_errors', True)
def tearDown(self):