]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Switch to in-memory sqlite for unit tests; 1500% speed improvement.
authorSteve Baker <sbaker@redhat.com>
Mon, 24 Sep 2012 03:26:56 +0000 (15:26 +1200)
committerSteve Baker <sbaker@redhat.com>
Mon, 24 Sep 2012 03:28:37 +0000 (15:28 +1200)
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

heat/db/api.py
heat/db/sqlalchemy/session.py
heat/tests/test_user.py
heat/tests/test_volume.py

index 3c3ca44dba416c38f5205588fdb216678e5ff02d..bd6c065f720ce8fd20c0d8111f1e7f9aceeb6aad 100644 (file)
@@ -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',
index f4f783d155d964406ef9e74b9f04b330639e4d17..90fb43614633e880041fb6c3e33fd02c65dd9fa4 100644 (file)
 
 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):
index 508edc5d464acb2ab9a2595deac81346aefbf32b..7e0f46099e6ebb154c21452e11cc82df167f21b3 100644 (file)
@@ -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)
index 0bd1e36233c6bee02b7e5c55e34a132f8069531a..8c60ce3e19d05a152f18e4db204d0e446713ff7f 100644 (file)
@@ -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()