← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~lifeless/launchpad/databasefixture into lp:launchpad/devel

 

Robert Collins has proposed merging lp:~lifeless/launchpad/databasefixture into lp:launchpad/devel with lp:~lifeless/launchpad/uniqueconfig as a prerequisite.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)


Start doing unique db names by default, permitting parallel testing of layers upto and including DatabaseLayer, as long as the appserver isn't started (because that has statically configured ports)
-- 
https://code.launchpad.net/~lifeless/launchpad/databasefixture/+merge/38694
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~lifeless/launchpad/databasefixture into lp:launchpad/devel.
=== modified file 'lib/canonical/config/fixture.py'
--- lib/canonical/config/fixture.py	2010-10-18 07:06:13 +0000
+++ lib/canonical/config/fixture.py	2010-10-18 07:06:13 +0000
@@ -31,17 +31,21 @@
         self.instance_name = instance_name
         self.copy_from_instance = copy_from_instance
 
+    def add_section(self, sectioncontent):
+        """Add sectioncontent to the lazy config."""
+        with open(self.absroot + '/launchpad-lazr.conf', 'ab') as out:
+            out.write(sectioncontent)
+
     def setUp(self):
         super(ConfigFixture, self).setUp()
         root = 'configs/' + self.instance_name
         os.mkdir(root)
-        absroot = os.path.abspath(root)
-        self.addCleanup(shutil.rmtree, absroot)
+        self.absroot = os.path.abspath(root)
+        self.addCleanup(shutil.rmtree, self.absroot)
         source = 'configs/' + self.copy_from_instance
         for basename in os.listdir(source):
             if basename == 'launchpad-lazr.conf':
-                with open(root + '/launchpad-lazr.conf', 'wb') as out:
-                    out.write("""[meta]
+                self.add_section("""[meta]
 extends: ../%s/launchpad-lazr.conf
 
 """ % self.copy_from_instance)

=== modified file 'lib/canonical/ftests/pgsql.py'
--- lib/canonical/ftests/pgsql.py	2010-10-18 07:06:13 +0000
+++ lib/canonical/ftests/pgsql.py	2010-10-18 07:06:13 +0000
@@ -11,6 +11,8 @@
 import time
 
 import psycopg2
+
+from canonical.config import config
 from canonical.database.postgresql import (
     generateResetSequencesSQL, resetSequences)
 
@@ -159,7 +161,7 @@
     # Class attribute. True if we should destroy the DB because changes made.
     _reset_db = True
 
-    def __init__(self, template=None, dbname=None, dbuser=None,
+    def __init__(self, template=None, dbname=dynamic, dbuser=None,
             host=None, port=None, reset_sequences_sql=None):
         '''Construct the PgTestSetup
 
@@ -168,10 +170,12 @@
         '''
         if template is not None:
             self.template = template
+        self._dynamic_name = False
         if dbname is PgTestSetup.dynamic:
             if os.environ.get('LP_TEST_INSTANCE'):
                 self.dbname = "%s_%s" % (
                     self.__class__.dbname, os.environ.get('LP_TEST_INSTANCE'))
+                self._dynamic_name = True
             else:
                 # Fallback to the class name.
                 self.dbname = self.__class__.dbname
@@ -214,6 +218,23 @@
         '''
         # This is now done globally in test.py
         #installFakeConnect()
+        if self._dynamic_name:
+            # Stash the name we use in the config if a writable config is
+            # available.
+            # Avoid circular imports
+            from canonical.testing.layers import BaseLayer
+            section = """[database]
+rw_main_master: dbname=%s
+rw_main_slave:  dbname=%s
+
+""" % (self.dbname, self.dbname)
+            if BaseLayer.config is not None:
+                BaseLayer.config.add_section(section)
+            if BaseLayer.appserver_config is not None:
+                BaseLayer.appserver_config.add_section(section)
+            if config.instance_name in (
+                BaseLayer.config_name, BaseLayer.appserver_config_name):
+                config.reloadConfig()
         if (self.template, self.dbname) != PgTestSetup._last_db:
             PgTestSetup._reset_db = True
         if not PgTestSetup._reset_db:
@@ -297,6 +318,7 @@
                 con = psycopg2.connect(self._connectionString(self.template))
             except psycopg2.OperationalError, x:
                 if 'does not exist' in x:
+                    print x
                     return
                 raise
             try:

=== modified file 'lib/canonical/ftests/test_pgsql.py'
--- lib/canonical/ftests/test_pgsql.py	2010-10-18 07:06:13 +0000
+++ lib/canonical/ftests/test_pgsql.py	2010-10-18 07:06:13 +0000
@@ -9,10 +9,13 @@
     )
 import testtools
 
+from canonical.config import config, dbconfig
+from canonical.config.fixture import ConfigUseFixture
 from canonical.ftests.pgsql import (
     ConnectionWrapper,
     PgTestSetup,
     )
+from canonical.testing.layers import BaseLayer
 
 
 class TestPgTestSetup(testtools.TestCase, TestWithFixtures):
@@ -41,6 +44,25 @@
         expected_name = PgTestSetup.dbname
         self.assertDBName(expected_name, fixture)
 
+    def test_db_naming_stored_in_BaseLayer_configs(self):
+        BaseLayer.setUp()
+        self.addCleanup(BaseLayer.tearDown)
+        fixture = PgTestSetup(dbname=PgTestSetup.dynamic)
+        fixture.setUp()
+        self.addCleanup(fixture.dropDb)
+        self.addCleanup(fixture.tearDown)
+        expected_value = 'dbname=%s' % fixture.dbname
+        self.assertEqual(expected_value, dbconfig.rw_main_master)
+        self.assertEqual(expected_value, dbconfig.rw_main_slave)
+        with ConfigUseFixture(BaseLayer.appserver_config_name):
+            self.assertEqual(expected_value, dbconfig.rw_main_master)
+            self.assertEqual(expected_value, dbconfig.rw_main_slave)
+
+
+class TestPgTestSetupTuning(testtools.TestCase, TestWithFixtures):
+
+    layer = BaseLayer
+
     def testOptimization(self):
         # Test to ensure that the database is destroyed only when necessary
 

=== modified file 'lib/canonical/testing/ftests/test_layers.py'
--- lib/canonical/testing/ftests/test_layers.py	2010-10-18 07:06:13 +0000
+++ lib/canonical/testing/ftests/test_layers.py	2010-10-18 07:06:13 +0000
@@ -12,6 +12,7 @@
 import os
 import signal
 import smtplib
+from cStringIO import StringIO
 from urllib import urlopen
 
 from fixtures import (
@@ -20,7 +21,6 @@
     )
 import psycopg2
 import testtools
-
 from zope.component import getUtility, ComponentLookupError
 
 from canonical.config import config, dbconfig
@@ -464,6 +464,7 @@
     layer = DatabaseLayer
 
     def tearDown(self):
+        super(LayerProcessControllerTestCase, self).tearDown()
         # Stop both servers.  It's okay if they aren't running.
         LayerProcessController.stopSMTPServer()
         LayerProcessController.stopAppServer()

=== modified file 'lib/canonical/testing/layers.py'
--- lib/canonical/testing/layers.py	2010-10-18 07:06:13 +0000
+++ lib/canonical/testing/layers.py	2010-10-18 07:06:13 +0000
@@ -261,16 +261,24 @@
     # Things we need to cleanup.
     fixture = None
 
-    # The config names that are generated for this layer
+    # ConfigFixtures for the configs generated for this layer. Set to None
+    # if the layer is not setUp, or if persistent tests services are in use.
+    config = None
+    appserver_config = None
+
+    # The config names that are generated for this layer. Set to None when
+    # the layer is not setUp.
     config_name = None
     appserver_config_name = None
 
     @classmethod
-    def make_config(cls, config_name, clone_from):
+    def make_config(cls, config_name, clone_from, attr_name):
         """Create a temporary config and link it into the layer cleanup."""
         cfg_fixture = ConfigFixture(config_name, clone_from)
         cls.fixture.addCleanup(cfg_fixture.cleanUp)
         cfg_fixture.setUp()
+        cls.fixture.addCleanup(setattr, cls, attr_name, None)
+        setattr(cls, attr_name, cfg_fixture)
 
     @classmethod
     @profiled
@@ -294,9 +302,10 @@
             if not BaseLayer.persist_test_services:
                 kill_by_pidfile(MemcachedLayer.getPidFile(), num_polls=0)
             config_name = 'testrunner_%s' % test_instance
-            cls.make_config(config_name, 'testrunner')
+            cls.make_config(config_name, 'testrunner', 'config')
             app_config_name = 'testrunner-appserver_%s' % test_instance
-            cls.make_config(app_config_name, 'testrunner-appserver')
+            cls.make_config(
+                app_config_name, 'testrunner-appserver', 'appserver_config')
         else:
             config_name = 'testrunner'
             app_config_name = 'testrunner-appserver'