Example #1
0
class SampleDataTestCase(TestCase):
    layer = DatabaseLayer

    def setUp(self):
        super(SampleDataTestCase, self).setUp()
        self.pg_fixture = PgTestSetup(template='template1')
        self.pg_fixture.setUp()

    def tearDown(self):
        self.pg_fixture.tearDown()
        super(SampleDataTestCase, self).tearDown()

    def test_testSampledata(self):
        """Test the sample data used by the test suite."""
        self.dump_and_restore('launchpad_ftest_template')

    # XXX bug 365385
    def disabled_test_devSampledata(self):
        """Test the sample data used by developers for manual testing."""
        self.dump_and_restore('launchpad_dev_template')

    def dump_and_restore(self, source_dbname):
        cmd = ("pg_dump --format=c --compress=0 --no-privileges --no-owner"
               " %s | pg_restore "
               " --exit-on-error --dbname=%s" %
               (source_dbname, self.pg_fixture.dbname))
        proc = subprocess.Popen(cmd,
                                shell=True,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT,
                                stdin=subprocess.PIPE)
        (stdout, stderr) = proc.communicate()
        rv = proc.wait()
        self.failUnlessEqual(rv, 0, "Dump/Restore failed: %s" % stdout)
Example #2
0
 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)
Example #3
0
 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 host=localhost' % 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)
Example #4
0
 def test_db_naming_LP_TEST_INSTANCE_set(self):
     # when LP_TEST_INSTANCE is set, it is used for dynamic db naming.
     BaseLayer.setUp()
     self.addCleanup(BaseLayer.tearDown)
     fixture = PgTestSetup(dbname=PgTestSetup.dynamic)
     expected_name = "%s_%d" % (PgTestSetup.dbname, os.getpid())
     self.assertDBName(expected_name, fixture)
Example #5
0
 def test_db_naming_LP_TEST_INSTANCE_set(self):
     # when LP_TEST_INSTANCE is set, it is used for dynamic db naming.
     BaseLayer.setUp()
     self.addCleanup(BaseLayer.tearDown)
     fixture = PgTestSetup(dbname=PgTestSetup.dynamic)
     raw_uuid = os.environ['LP_TEST_INSTANCE'].split('_', 1)[1]
     instance_uuid = uuid.UUID(raw_uuid)
     self.assertEqual(uuid.RFC_4122, instance_uuid.variant)
     self.assertEqual(1, instance_uuid.version)
     expected_name = "%s_%d_%s" % (
         PgTestSetup.dbname, os.getpid(), instance_uuid.hex)
     self.assertDBName(expected_name, fixture)
Example #6
0
def setUp(test):

    # Build a fresh, empty database and connect
    test._db_fixture = PgTestSetup()
    test._db_fixture.setUp()
    con = test._db_fixture.connect()

    # Create a test schema demonstrating the edge cases
    cur = con.cursor()
    cur.execute("""
        CREATE TABLE A (
            aid     serial PRIMARY KEY,
            selfref integer CONSTRAINT a_selfref_fk REFERENCES A(aid)
            )
        """)
    cur.execute("""
        CREATE TABLE B (
            bid integer PRIMARY KEY,
            aid integer UNIQUE CONSTRAINT b_aid_fk REFERENCES A(aid)
                ON DELETE CASCADE ON UPDATE CASCADE
            )
        """)
    cur.execute("""
        CREATE TABLE C (
            cid integer PRIMARY KEY,
            aid integer CONSTRAINT c_aid_fk REFERENCES B(aid),
            bid integer CONSTRAINT c_bid_fk REFERENCES B(bid),
            CONSTRAINT c_aid_bid_key UNIQUE (aid, bid)
            )
        """)
    cur.execute("""
        CREATE TABLE D (
            did integer PRIMARY KEY,
            aid integer UNIQUE CONSTRAINT d_aid_fk REFERENCES B(aid),
            bid integer CONSTRAINT d_bid_fk REFERENCES B(bid),
            CONSTRAINT d_aid_bid_key UNIQUE (aid, bid)
            )
        """)
    cur.execute("CREATE SEQUENCE standalone")
    con.commit()

    # Store the connection and a cursor for the tests to use
    cur = con.cursor()
    test.globs['con'] = con
    test.globs['cur'] = cur
Example #7
0
 def setUp(self):
     super(SampleDataTestCase, self).setUp()
     self.pg_fixture = PgTestSetup(template='template1')
     self.pg_fixture.setUp()
Example #8
0
    def testOptimization(self):
        # Test to ensure that the database is destroyed only when necessary

        # Make a change to a database
        fixture = PgTestSetup()
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            cur.execute('CREATE TABLE foo (x int)')
            con.commit()
            # Fake it so the harness doesn't know a change has been made
            ConnectionWrapper.committed = False
        finally:
            fixture.tearDown()

        # Now check to ensure that the table we just created is still there if
        # we reuse the fixture.
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            # This tests that the table still exists, as well as modifying the
            # db
            cur.execute('INSERT INTO foo VALUES (1)')
            con.commit()
        finally:
            fixture.tearDown()

        # Now ensure that the table is gone - the commit must have been rolled
        # back.
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            cur.execute('CREATE TABLE foo (x int)')
            con.commit()
            # Leave the table.
            ConnectionWrapper.committed = False
        finally:
            fixture.tearDown()

        # The database should *always* be recreated if a new template had been
        # chosen.
        PgTestSetup._last_db = ('different-template', fixture.dbname)
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            # If this fails, TABLE foo still existed and the DB wasn't rebuilt
            # correctly.
            cur.execute('CREATE TABLE foo (x int)')
            con.commit()
        finally:
            fixture.tearDown()
Example #9
0
    def test_sequences(self):
        # Sequences may be affected by connections even if the connection
        # is rolled back. So ensure the database is reset fully, in the
        # cases where we just rollback the changes we also need to reset all
        # the sequences.

        # Setup a table that uses a sequence
        fixture = PgTestSetup()
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            cur.execute('CREATE TABLE foo (x serial, y integer)')
            con.commit()
            con.close()
            # Fake it so the harness doesn't know a change has been made
            ConnectionWrapper.committed = False
        finally:
            fixture.tearDown()

        sequence_values = []
        # Insert a row into it and roll back the changes. Each time, we
        # should end up with the same sequence value
        for i in range(3):
            fixture.setUp()
            try:
                con = fixture.connect()
                cur = con.cursor()
                cur.execute('INSERT INTO foo (y) VALUES (1)')
                cur.execute("SELECT currval('foo_x_seq')")
                sequence_values.append(cur.fetchone()[0])
                con.rollback()
                con.close()
            finally:
                fixture.tearDown()

        # Fail if we got a diffent sequence value at some point
        for v in sequence_values:
            self.failUnlessEqual(v, sequence_values[0])

        # Repeat the test, but this time with some data already in the
        # table
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            cur.execute('INSERT INTO foo (y) VALUES (1)')
            con.commit()
            con.close()
            # Fake it so the harness doesn't know a change has been made
            ConnectionWrapper.committed = False
        finally:
            fixture.tearDown()

        sequence_values = []
        # Insert a row into it and roll back the changes. Each time, we
        # should end up with the same sequence value
        for i in range(1, 3):
            fixture.setUp()
            try:
                con = fixture.connect()
                cur = con.cursor()
                cur.execute('INSERT INTO foo (y) VALUES (1)')
                cur.execute("SELECT currval('foo_x_seq')")
                sequence_values.append(cur.fetchone()[0])
                con.rollback()
                con.close()
            finally:
                fixture.tearDown()

        # Fail if we got a diffent sequence value at some point
        for v in sequence_values:
            self.failUnlessEqual(v, sequence_values[0])

        # The database still exists because, after the last commit,
        # ConnectionWrapper.committed was set to False.
        # Drop the database here to avoid test ordering issues.
        fixture.dropDb()
Example #10
0
    def testOptimization(self):
        # Test to ensure that the database is destroyed only when necessary

        # Make a change to a database
        fixture = PgTestSetup()
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            cur.execute('CREATE TABLE foo (x int)')
            con.commit()
            # Fake it so the harness doesn't know a change has been made
            ConnectionWrapper.committed = False
        finally:
            fixture.tearDown()

        # Now check to ensure that the table we just created is still there if
        # we reuse the fixture.
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            # This tests that the table still exists, as well as modifying the
            # db
            cur.execute('INSERT INTO foo VALUES (1)')
            con.commit()
        finally:
            fixture.tearDown()

        # Now ensure that the table is gone - the commit must have been rolled
        # back.
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            cur.execute('CREATE TABLE foo (x int)')
            con.commit()
            # Leave the table.
            ConnectionWrapper.committed = False
        finally:
            fixture.tearDown()

        # The database should *always* be recreated if a new template had been
        # chosen.
        PgTestSetup._last_db = ('different-template', fixture.dbname)
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            # If this fails, TABLE foo still existed and the DB wasn't rebuilt
            # correctly.
            cur.execute('CREATE TABLE foo (x int)')
            con.commit()
        finally:
            fixture.tearDown()
Example #11
0
 def test_db_naming_without_LP_TEST_INSTANCE_is_static(self):
     self.useFixture(EnvironmentVariableFixture('LP_TEST_INSTANCE'))
     fixture = PgTestSetup(dbname=PgTestSetup.dynamic)
     expected_name = PgTestSetup.dbname
     self.assertDBName(expected_name, fixture)
Example #12
0
    def test_sequences(self):
        # Sequences may be affected by connections even if the connection
        # is rolled back. So ensure the database is reset fully, in the
        # cases where we just rollback the changes we also need to reset all
        # the sequences.

        # Setup a table that uses a sequence
        fixture = PgTestSetup()
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            cur.execute('CREATE TABLE foo (x serial, y integer)')
            con.commit()
            con.close()
            # Fake it so the harness doesn't know a change has been made
            ConnectionWrapper.committed = False
        finally:
            fixture.tearDown()

        sequence_values = []
        # Insert a row into it and roll back the changes. Each time, we
        # should end up with the same sequence value
        for i in range(3):
            fixture.setUp()
            try:
                con = fixture.connect()
                cur = con.cursor()
                cur.execute('INSERT INTO foo (y) VALUES (1)')
                cur.execute("SELECT currval('foo_x_seq')")
                sequence_values.append(cur.fetchone()[0])
                con.rollback()
                con.close()
            finally:
                fixture.tearDown()

        # Fail if we got a diffent sequence value at some point
        for v in sequence_values:
            self.failUnlessEqual(v, sequence_values[0])

        # Repeat the test, but this time with some data already in the
        # table
        fixture.setUp()
        try:
            con = fixture.connect()
            cur = con.cursor()
            cur.execute('INSERT INTO foo (y) VALUES (1)')
            con.commit()
            con.close()
            # Fake it so the harness doesn't know a change has been made
            ConnectionWrapper.committed = False
        finally:
            fixture.tearDown()

        sequence_values = []
        # Insert a row into it and roll back the changes. Each time, we
        # should end up with the same sequence value
        for i in range(1, 3):
            fixture.setUp()
            try:
                con = fixture.connect()
                cur = con.cursor()
                cur.execute('INSERT INTO foo (y) VALUES (1)')
                cur.execute("SELECT currval('foo_x_seq')")
                sequence_values.append(cur.fetchone()[0])
                con.rollback()
                con.close()
            finally:
                fixture.tearDown()

        # Fail if we got a diffent sequence value at some point
        for v in sequence_values:
            self.failUnlessEqual(v, sequence_values[0])

        # The database still exists because, after the last commit,
        # ConnectionWrapper.committed was set to False.
        # Drop the database here to avoid test ordering issues.
        fixture.dropDb()