11
11
'ZopeViewReplacementFixture',
14
from ConfigParser import SafeConfigParser
14
16
from textwrap import dedent
16
from fixtures import Fixture
18
from fixtures import (
19
EnvironmentVariableFixture,
22
import pgbouncer.fixture
17
23
import rabbitfixture.server
18
24
from zope.component import (
19
25
getGlobalSiteManager,
46
54
""" % self.config.port)
57
class PGBouncerFixture(pgbouncer.fixture.PGBouncerFixture):
58
"""Inserts a controllable pgbouncer instance in front of PostgreSQL.
60
The pgbouncer proxy can be shutdown and restarted at will, simulating
61
database outages and fastdowntime deployments.
65
super(PGBouncerFixture, self).__init__()
68
from canonical.testing.layers import DatabaseLayer
70
DatabaseLayer._db_fixture.dbname,
71
DatabaseLayer._db_template_fixture.dbname,
75
for dbname in dbnames:
76
self.databases[dbname] = 'dbname=%s port=5432 host=localhost' % (
79
# Known users, pulled from security.cfg
80
security_cfg_path = os.path.join(
81
config.root, 'database', 'schema', 'security.cfg')
82
security_cfg_config = SafeConfigParser({})
83
security_cfg_config.read([security_cfg_path])
84
for section_name in security_cfg_config.sections():
85
self.users[section_name] = 'trusted'
86
self.users[section_name + '_ro'] = 'trusted'
87
self.users[os.environ['USER']] = 'trusted'
90
super(PGBouncerFixture, self).setUp()
92
# reconnect_store cleanup added first so it is run last, after
93
# the environment variables have been reset.
94
self.addCleanup(self._maybe_reconnect_stores)
96
# Abuse the PGPORT environment variable to get things connecting
97
# via pgbouncer. Otherwise, we would need to temporarily
98
# overwrite the database connection strings in the config.
99
self.useFixture(EnvironmentVariableFixture('PGPORT', str(self.port)))
101
# Reset database connections so they go through pgbouncer.
102
self._maybe_reconnect_stores()
104
def _maybe_reconnect_stores(self):
105
"""Force Storm Stores to reconnect if they are registered.
107
This is a noop if the Component Architecture is not loaded,
108
as we are using a test layer that doesn't provide database
111
from canonical.testing.layers import (
115
if is_ca_available():
49
119
class ZopeAdapterFixture(Fixture):
50
120
"""A fixture to register and unregister an adapter."""