~launchpad-pqm/launchpad/devel

11728.2.8 by Robert Collins
Permit (when specified) unique db names for PgTest.
1
# Copyright 2009-2010 Canonical Ltd.  This software is licensed under the
8687.15.18 by Karl Fogel
Add the copyright header block to files under lib/canonical/.
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
11728.2.8 by Robert Collins
Permit (when specified) unique db names for PgTest.
4
import os
5
11728.3.1 by Robert Collins
Set LP_TEST_INSTANCE during BaseLayer, if we're not using persistent test helpers.
6
from fixtures import (
7
    EnvironmentVariableFixture,
8
    TestWithFixtures,
9
    )
11728.2.8 by Robert Collins
Permit (when specified) unique db names for PgTest.
10
import testtools
11
12413.1.2 by Jonathan Lange
Move canonical.ftests.pgsql into lp.testing.
12
from canonical.config import dbconfig
11737.2.3 by Robert Collins
Isolated test db's sufficient to run parallel tests of the db layer.
13
from canonical.config.fixture import ConfigUseFixture
12413.1.2 by Jonathan Lange
Move canonical.ftests.pgsql into lp.testing.
14
from canonical.testing.layers import BaseLayer
15
16
from lp.testing.pgsql import (
11728.2.8 by Robert Collins
Permit (when specified) unique db names for PgTest.
17
    ConnectionWrapper,
18
    PgTestSetup,
19
    )
20
21
11728.3.1 by Robert Collins
Set LP_TEST_INSTANCE during BaseLayer, if we're not using persistent test helpers.
22
class TestPgTestSetup(testtools.TestCase, TestWithFixtures):
11728.2.8 by Robert Collins
Permit (when specified) unique db names for PgTest.
23
11728.3.1 by Robert Collins
Set LP_TEST_INSTANCE during BaseLayer, if we're not using persistent test helpers.
24
    def assertDBName(self, expected_name, fixture):
25
        """Check that fixture uses expected_name as its dbname."""
11728.2.8 by Robert Collins
Permit (when specified) unique db names for PgTest.
26
        self.assertEqual(expected_name, fixture.dbname)
27
        fixture.setUp()
11728.2.10 by Robert Collins
Don't leak a DB when testing db naming.
28
        self.addCleanup(fixture.dropDb)
11728.2.8 by Robert Collins
Permit (when specified) unique db names for PgTest.
29
        self.addCleanup(fixture.tearDown)
30
        cur = fixture.connect().cursor()
31
        cur.execute('SELECT current_database()')
32
        where = cur.fetchone()[0]
33
        self.assertEqual(expected_name, where)
11728.2.6 by Robert Collins
Remove many hardcoded uses of launchpad_ftest.
34
11728.3.1 by Robert Collins
Set LP_TEST_INSTANCE during BaseLayer, if we're not using persistent test helpers.
35
    def test_db_naming_LP_TEST_INSTANCE_set(self):
36
        # when LP_TEST_INSTANCE is set, it is used for dynamic db naming.
11737.2.27 by William Grant
PgTestSetup needs BaseLayer now, so set up BaseLayer and use the PID when checking that it respects LP_TEST_INSTANCE.
37
        BaseLayer.setUp()
38
        self.addCleanup(BaseLayer.tearDown)
11728.3.1 by Robert Collins
Set LP_TEST_INSTANCE during BaseLayer, if we're not using persistent test helpers.
39
        fixture = PgTestSetup(dbname=PgTestSetup.dynamic)
11737.2.27 by William Grant
PgTestSetup needs BaseLayer now, so set up BaseLayer and use the PID when checking that it respects LP_TEST_INSTANCE.
40
        expected_name = "%s_%d" % (PgTestSetup.dbname, os.getpid())
11728.3.1 by Robert Collins
Set LP_TEST_INSTANCE during BaseLayer, if we're not using persistent test helpers.
41
        self.assertDBName(expected_name, fixture)
42
43
    def test_db_naming_without_LP_TEST_INSTANCE_is_static(self):
44
        self.useFixture(EnvironmentVariableFixture('LP_TEST_INSTANCE'))
45
        fixture = PgTestSetup(dbname=PgTestSetup.dynamic)
46
        expected_name = PgTestSetup.dbname
47
        self.assertDBName(expected_name, fixture)
48
11737.2.3 by Robert Collins
Isolated test db's sufficient to run parallel tests of the db layer.
49
    def test_db_naming_stored_in_BaseLayer_configs(self):
50
        BaseLayer.setUp()
51
        self.addCleanup(BaseLayer.tearDown)
52
        fixture = PgTestSetup(dbname=PgTestSetup.dynamic)
53
        fixture.setUp()
54
        self.addCleanup(fixture.dropDb)
55
        self.addCleanup(fixture.tearDown)
13813.1.6 by Stuart Bishop
Revert reversion in launchpad/devel r13865
56
        expected_value = 'dbname=%s host=localhost' % fixture.dbname
11737.2.3 by Robert Collins
Isolated test db's sufficient to run parallel tests of the db layer.
57
        self.assertEqual(expected_value, dbconfig.rw_main_master)
58
        self.assertEqual(expected_value, dbconfig.rw_main_slave)
59
        with ConfigUseFixture(BaseLayer.appserver_config_name):
60
            self.assertEqual(expected_value, dbconfig.rw_main_master)
61
            self.assertEqual(expected_value, dbconfig.rw_main_slave)
62
63
64
class TestPgTestSetupTuning(testtools.TestCase, TestWithFixtures):
65
66
    layer = BaseLayer
67
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
68
    def testOptimization(self):
69
        # Test to ensure that the database is destroyed only when necessary
70
71
        # Make a change to a database
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
72
        fixture = PgTestSetup()
73
        fixture.setUp()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
74
        try:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
75
            con = fixture.connect()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
76
            cur = con.cursor()
77
            cur.execute('CREATE TABLE foo (x int)')
78
            con.commit()
79
            # Fake it so the harness doesn't know a change has been made
80
            ConnectionWrapper.committed = False
81
        finally:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
82
            fixture.tearDown()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
83
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
84
        # Now check to ensure that the table we just created is still there if
85
        # we reuse the fixture.
86
        fixture.setUp()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
87
        try:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
88
            con = fixture.connect()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
89
            cur = con.cursor()
90
            # This tests that the table still exists, as well as modifying the
4785.3.7 by Jeroen Vermeulen
Removed whitespace at ends of lines
91
            # db
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
92
            cur.execute('INSERT INTO foo VALUES (1)')
93
            con.commit()
94
        finally:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
95
            fixture.tearDown()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
96
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
97
        # Now ensure that the table is gone - the commit must have been rolled
98
        # back.
99
        fixture.setUp()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
100
        try:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
101
            con = fixture.connect()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
102
            cur = con.cursor()
103
            cur.execute('CREATE TABLE foo (x int)')
104
            con.commit()
105
            ConnectionWrapper.committed = False # Leave the table
106
        finally:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
107
            fixture.tearDown()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
108
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
109
        # The database should *always* be recreated if a new template had been
110
        # chosen.
111
        PgTestSetup._last_db = ('different-template', fixture.dbname)
112
        fixture.setUp()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
113
        try:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
114
            con = fixture.connect()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
115
            cur = con.cursor()
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
116
            # If this fails, TABLE foo still existed and the DB wasn't rebuilt
11728.2.6 by Robert Collins
Remove many hardcoded uses of launchpad_ftest.
117
            # correctly.
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
118
            cur.execute('CREATE TABLE foo (x int)')
119
            con.commit()
120
        finally:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
121
            fixture.tearDown()
1617 by Canonical.com Patch Queue Manager
Refactor PostgreSQL harnesses to avoid bug found by ddaa. Add more tests
122
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
123
    def test_sequences(self):
124
        # Sequences may be affected by connections even if the connection
125
        # is rolled back. So ensure the database is reset fully, in the
126
        # cases where we just rollback the changes we also need to reset all
127
        # the sequences.
128
129
        # Setup a table that uses a sequence
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
130
        fixture = PgTestSetup()
131
        fixture.setUp()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
132
        try:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
133
            con = fixture.connect()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
134
            cur = con.cursor()
135
            cur.execute('CREATE TABLE foo (x serial, y integer)')
136
            con.commit()
137
            con.close()
138
            # Fake it so the harness doesn't know a change has been made
139
            ConnectionWrapper.committed = False
140
        finally:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
141
            fixture.tearDown()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
142
143
        sequence_values = []
144
        # Insert a row into it and roll back the changes. Each time, we
145
        # should end up with the same sequence value
146
        for i in range(3):
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
147
            fixture.setUp()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
148
            try:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
149
                con = fixture.connect()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
150
                cur = con.cursor()
151
                cur.execute('INSERT INTO foo (y) VALUES (1)')
152
                cur.execute("SELECT currval('foo_x_seq')")
153
                sequence_values.append(cur.fetchone()[0])
154
                con.rollback()
155
                con.close()
156
            finally:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
157
                fixture.tearDown()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
158
159
        # Fail if we got a diffent sequence value at some point
160
        for v in sequence_values:
161
            self.failUnlessEqual(v, sequence_values[0])
162
163
        # Repeat the test, but this time with some data already in the
164
        # table
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
165
        fixture.setUp()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
166
        try:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
167
            con = fixture.connect()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
168
            cur = con.cursor()
169
            cur.execute('INSERT INTO foo (y) VALUES (1)')
170
            con.commit()
171
            con.close()
172
            # Fake it so the harness doesn't know a change has been made
173
            ConnectionWrapper.committed = False
174
        finally:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
175
            fixture.tearDown()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
176
177
        sequence_values = []
178
        # Insert a row into it and roll back the changes. Each time, we
179
        # should end up with the same sequence value
180
        for i in range(1,3):
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
181
            fixture.setUp()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
182
            try:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
183
                con = fixture.connect()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
184
                cur = con.cursor()
185
                cur.execute('INSERT INTO foo (y) VALUES (1)')
186
                cur.execute("SELECT currval('foo_x_seq')")
187
                sequence_values.append(cur.fetchone()[0])
188
                con.rollback()
189
                con.close()
190
            finally:
11728.2.7 by Robert Collins
Overhaul use of PgTestSetup to use instances, discard unused PgTestCase.
191
                fixture.tearDown()
1717 by Canonical.com Patch Queue Manager
[r=spiv] Misc pending changes, including ProductSeries.name changing for bazaar imports, wiring up Daf's sampledata sorting script, enhancing the PostgreSQL test harness to ensure better test isolation (solves the issue of not resetting sequence values between tests, a possible case of occasional test failures).
192
193
        # Fail if we got a diffent sequence value at some point
194
        for v in sequence_values:
195
            self.failUnlessEqual(v, sequence_values[0])