From: Steve Baker Date: Mon, 24 Sep 2012 03:26:56 +0000 (+1200) Subject: Switch to in-memory sqlite for unit tests; 1500% speed improvement. X-Git-Tag: 2014.1~1357 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=54d53d307d5378a15c627b642fae6246fe33a13d;p=openstack-build%2Fheat-build.git Switch to in-memory sqlite for unit tests; 1500% speed improvement. All unit tests now run in 4 seconds, instead of 64 seconds on a HDD. _ENGINE global setting had to be moved into get_engine() so that migration works, otherwise get_engine() creates a new isolated in-memory database for every call. Other unit test speedups in this change are to stub out some eventlet sleeps which saves about 5 seconds. Change-Id: I3643b73dd9bd86c414934b7c78db67402587f570 --- diff --git a/heat/db/api.py b/heat/db/api.py index 3c3ca44d..bd6c065f 100644 --- a/heat/db/api.py +++ b/heat/db/api.py @@ -30,7 +30,7 @@ from heat.openstack.common import utils from heat.openstack.common import cfg import heat.utils -SQL_CONNECTION = 'sqlite:///heat-test.db/' +SQL_CONNECTION = 'sqlite://' SQL_IDLE_TIMEOUT = 3600 db_opts = [ cfg.StrOpt('db_backend', diff --git a/heat/db/sqlalchemy/session.py b/heat/db/sqlalchemy/session.py index f4f783d1..90fb4361 100644 --- a/heat/db/sqlalchemy/session.py +++ b/heat/db/sqlalchemy/session.py @@ -16,12 +16,12 @@ import sqlalchemy.interfaces import sqlalchemy.orm +import sqlalchemy.engine from sqlalchemy.exc import DisconnectionError from heat.openstack.common import log as logging from heat.db import api as db_api -from heat.openstack.common import cfg logger = logging.getLogger('heat.db.sqlalchemy.session') _ENGINE = None @@ -30,11 +30,10 @@ _MAKER = None def get_session(autocommit=True, expire_on_commit=False): """Return a SQLAlchemy session.""" - global _ENGINE, _MAKER + global _MAKER - if _MAKER is None or _ENGINE is None: - _ENGINE = get_engine() - _MAKER = get_maker(_ENGINE, autocommit, expire_on_commit) + if _MAKER is None: + _MAKER = get_maker(get_engine(), autocommit, expire_on_commit) return _MAKER() @@ -69,17 +68,21 @@ class MySQLPingListener(object): def get_engine(): """Return a SQLAlchemy engine.""" - connection_dict = sqlalchemy.engine.url.make_url(_get_sql_connection()) - engine_args = { - "pool_recycle": _get_sql_idle_timeout(), - "echo": False, - 'convert_unicode': True, - } - - if 'mysql' in connection_dict.drivername: - engine_args['listeners'] = [MySQLPingListener()] - - return sqlalchemy.create_engine(_get_sql_connection(), **engine_args) + global _ENGINE + if _ENGINE is None: + connection_dict = sqlalchemy.engine.url.make_url(_get_sql_connection()) + engine_args = { + "pool_recycle": _get_sql_idle_timeout(), + "echo": False, + 'convert_unicode': True + } + + if 'mysql' in connection_dict.drivername: + engine_args['listeners'] = [MySQLPingListener()] + + _ENGINE = sqlalchemy.create_engine(_get_sql_connection(), + **engine_args) + return _ENGINE def get_maker(engine, autocommit=True, expire_on_commit=False): diff --git a/heat/tests/test_user.py b/heat/tests/test_user.py index 508edc5d..7e0f4609 100644 --- a/heat/tests/test_user.py +++ b/heat/tests/test_user.py @@ -16,6 +16,7 @@ import sys import os +import eventlet import json import nose import mox @@ -48,6 +49,7 @@ class UserTest(unittest.TestCase): self.m.StubOutWithMock(self.fc.ec2, 'create') self.m.StubOutWithMock(self.fc.ec2, 'get') self.m.StubOutWithMock(self.fc.ec2, 'delete') + self.m.StubOutWithMock(eventlet, 'sleep') def tearDown(self): self.m.UnsetStubs() @@ -108,6 +110,7 @@ class UserTest(unittest.TestCase): # delete script user.User.keystone().AndReturn(self.fc) self.fc.users.get(user.DummyId('1')).AndRaise(Exception('not found')) + eventlet.sleep(1).AndReturn(None) user.User.keystone().AndReturn(self.fc) self.fc.users.get(user.DummyId('1')).AndReturn(fake_user) diff --git a/heat/tests/test_volume.py b/heat/tests/test_volume.py index 0bd1e362..8c60ce3e 100644 --- a/heat/tests/test_volume.py +++ b/heat/tests/test_volume.py @@ -16,6 +16,7 @@ import sys import os +import eventlet import json import nose import mox @@ -41,6 +42,7 @@ class VolumeTest(unittest.TestCase): self.m.StubOutWithMock(self.fc.volumes, 'delete') self.m.StubOutWithMock(self.fc.volumes, 'create_server_volume') self.m.StubOutWithMock(self.fc.volumes, 'delete_server_volume') + self.m.StubOutWithMock(eventlet, 'sleep') def tearDown(self): self.m.UnsetStubs() @@ -98,6 +100,7 @@ class VolumeTest(unittest.TestCase): # delete script vol.Volume.nova('volume').AndReturn(self.fc) self.fc.volumes.get('vol-123').AndReturn(fv) + eventlet.sleep(1).AndReturn(None) vol.Volume.nova('volume').AndReturn(self.fc) self.fc.volumes.get('vol-123').AndReturn(fv) @@ -132,6 +135,8 @@ class VolumeTest(unittest.TestCase): display_description='test_stack.DataVolume', display_name='test_stack.DataVolume').AndReturn(fv) + eventlet.sleep(1).AndReturn(None) + self.m.ReplayAll() t = self.load_template() @@ -156,6 +161,7 @@ class VolumeTest(unittest.TestCase): vol.VolumeAttachment.nova('volume').AndReturn(self.fc) self.fc.volumes.get('vol-123').AndReturn(fv) + eventlet.sleep(1).AndReturn(None) self.m.ReplayAll() @@ -181,6 +187,7 @@ class VolumeTest(unittest.TestCase): vol.VolumeAttachment.nova('volume').AndReturn(self.fc) self.fc.volumes.get('vol-123').AndReturn(fv) + eventlet.sleep(1).AndReturn(None) # delete script @@ -190,6 +197,7 @@ class VolumeTest(unittest.TestCase): 'vol-123').AndReturn(None) vol.VolumeAttachment.nova('volume').AndReturn(self.fc) self.fc.volumes.get('vol-123').AndReturn(fv) + eventlet.sleep(1).AndReturn(None) self.m.ReplayAll()