10197.5.13
by Michael Hudson
misc. fixes |
1 |
# Copyright 2009, 2010 Canonical Ltd. This software is licensed under the
|
8687.15.22
by Karl Fogel
Add the copyright header block to the remaining .py files. |
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
3 |
||
11731.1.1
by Robert Collins
Rationalise our fixture test support - delete unused stuff, consolidate on the external fixtures API. |
4 |
"""Launchpad test fixtures that have no better home."""
|
7960.4.30
by Jonathan Lange
Basic fixture support. |
5 |
|
6 |
__metaclass__ = type |
|
7960.4.32
by Jonathan Lange
Add a fixture that has addCleanup support. |
7 |
__all__ = [ |
13333.6.50
by Gavin Panella
Set the service_config in a new RabbitServer fixture. |
8 |
'RabbitServer', |
13333.6.35
by Gavin Panella
Move AdapterFixture to lp.testing.fixture.ZopeAdapterFixture. |
9 |
'ZopeAdapterFixture', |
11731.1.1
by Robert Collins
Rationalise our fixture test support - delete unused stuff, consolidate on the external fixtures API. |
10 |
'ZopeEventHandlerFixture', |
13333.6.35
by Gavin Panella
Move AdapterFixture to lp.testing.fixture.ZopeAdapterFixture. |
11 |
'ZopeViewReplacementFixture', |
7960.4.32
by Jonathan Lange
Add a fixture that has addCleanup support. |
12 |
]
|
7960.4.30
by Jonathan Lange
Basic fixture support. |
13 |
|
13813.1.6
by Stuart Bishop
Revert reversion in launchpad/devel r13865 |
14 |
from ConfigParser import SafeConfigParser |
15 |
import os.path |
|
13333.6.50
by Gavin Panella
Set the service_config in a new RabbitServer fixture. |
16 |
from textwrap import dedent |
17 |
||
13813.1.6
by Stuart Bishop
Revert reversion in launchpad/devel r13865 |
18 |
from fixtures import ( |
19 |
EnvironmentVariableFixture, |
|
20 |
Fixture, |
|
21 |
)
|
|
22 |
import pgbouncer.fixture |
|
13333.6.50
by Gavin Panella
Set the service_config in a new RabbitServer fixture. |
23 |
import rabbitfixture.server |
11403.1.4
by Henning Eggers
Reformatted imports using format-imports script r32. |
24 |
from zope.component import ( |
25 |
getGlobalSiteManager, |
|
26 |
provideHandler, |
|
27 |
)
|
|
13195.1.1
by Gary Poster
openid discovery failure should not record an OOPS. Add a new Zope view replacement test fixture to help. |
28 |
from zope.interface import Interface |
29 |
from zope.publisher.interfaces.browser import IDefaultBrowserLayer |
|
30 |
from zope.security.checker import ( |
|
31 |
defineChecker, |
|
32 |
getCheckerForInstancesOf, |
|
33 |
undefineChecker, |
|
34 |
)
|
|
11731.1.1
by Robert Collins
Rationalise our fixture test support - delete unused stuff, consolidate on the external fixtures API. |
35 |
|
13813.1.6
by Stuart Bishop
Revert reversion in launchpad/devel r13865 |
36 |
from canonical.config import config |
37 |
||
11731.1.1
by Robert Collins
Rationalise our fixture test support - delete unused stuff, consolidate on the external fixtures API. |
38 |
|
13333.6.50
by Gavin Panella
Set the service_config in a new RabbitServer fixture. |
39 |
class RabbitServer(rabbitfixture.server.RabbitServer): |
40 |
"""A RabbitMQ server fixture with Launchpad-specific config.
|
|
41 |
||
42 |
:ivar service_config: A snippet of .ini that describes the `rabbitmq`
|
|
43 |
configuration.
|
|
44 |
"""
|
|
45 |
||
46 |
def setUp(self): |
|
47 |
super(RabbitServer, self).setUp() |
|
48 |
self.config.service_config = dedent("""\ |
|
49 |
[rabbitmq]
|
|
50 |
host: localhost:%d |
|
51 |
userid: guest
|
|
52 |
password: guest
|
|
53 |
virtual_host: /
|
|
54 |
""" % self.config.port) |
|
55 |
||
56 |
||
13813.1.6
by Stuart Bishop
Revert reversion in launchpad/devel r13865 |
57 |
class PGBouncerFixture(pgbouncer.fixture.PGBouncerFixture): |
58 |
"""Inserts a controllable pgbouncer instance in front of PostgreSQL.
|
|
59 |
||
60 |
The pgbouncer proxy can be shutdown and restarted at will, simulating
|
|
61 |
database outages and fastdowntime deployments.
|
|
62 |
"""
|
|
63 |
||
64 |
def __init__(self): |
|
65 |
super(PGBouncerFixture, self).__init__() |
|
66 |
||
67 |
# Known databases
|
|
68 |
from canonical.testing.layers import DatabaseLayer |
|
69 |
dbnames = [ |
|
70 |
DatabaseLayer._db_fixture.dbname, |
|
71 |
DatabaseLayer._db_template_fixture.dbname, |
|
72 |
'session_ftest', |
|
73 |
'launchpad_empty', |
|
74 |
]
|
|
75 |
for dbname in dbnames: |
|
76 |
self.databases[dbname] = 'dbname=%s port=5432 host=localhost' % ( |
|
77 |
dbname,) |
|
78 |
||
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' |
|
88 |
||
89 |
def setUp(self): |
|
90 |
super(PGBouncerFixture, self).setUp() |
|
91 |
||
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) |
|
95 |
||
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))) |
|
100 |
||
101 |
# Reset database connections so they go through pgbouncer.
|
|
102 |
self._maybe_reconnect_stores() |
|
103 |
||
104 |
def _maybe_reconnect_stores(self): |
|
105 |
"""Force Storm Stores to reconnect if they are registered.
|
|
106 |
||
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
|
|
109 |
connections.
|
|
110 |
"""
|
|
111 |
from canonical.testing.layers import ( |
|
112 |
reconnect_stores, |
|
113 |
is_ca_available, |
|
114 |
)
|
|
115 |
if is_ca_available(): |
|
116 |
reconnect_stores() |
|
117 |
||
118 |
||
13333.6.35
by Gavin Panella
Move AdapterFixture to lp.testing.fixture.ZopeAdapterFixture. |
119 |
class ZopeAdapterFixture(Fixture): |
120 |
"""A fixture to register and unregister an adapter."""
|
|
121 |
||
122 |
def __init__(self, *args, **kwargs): |
|
123 |
self._args, self._kwargs = args, kwargs |
|
124 |
||
125 |
def setUp(self): |
|
126 |
super(ZopeAdapterFixture, self).setUp() |
|
127 |
site_manager = getGlobalSiteManager() |
|
128 |
site_manager.registerAdapter( |
|
129 |
*self._args, **self._kwargs) |
|
130 |
self.addCleanup( |
|
131 |
site_manager.unregisterAdapter, |
|
132 |
*self._args, **self._kwargs) |
|
133 |
||
134 |
||
11731.1.1
by Robert Collins
Rationalise our fixture test support - delete unused stuff, consolidate on the external fixtures API. |
135 |
class ZopeEventHandlerFixture(Fixture): |
7960.4.39
by Jonathan Lange
Move the zope code to the fixture module. |
136 |
"""A fixture that provides and then unprovides a Zope event handler."""
|
137 |
||
138 |
def __init__(self, handler): |
|
11731.1.1
by Robert Collins
Rationalise our fixture test support - delete unused stuff, consolidate on the external fixtures API. |
139 |
super(ZopeEventHandlerFixture, self).__init__() |
7960.4.39
by Jonathan Lange
Move the zope code to the fixture module. |
140 |
self._handler = handler |
141 |
||
142 |
def setUp(self): |
|
143 |
super(ZopeEventHandlerFixture, self).setUp() |
|
144 |
gsm = getGlobalSiteManager() |
|
145 |
provideHandler(self._handler) |
|
146 |
self.addCleanup(gsm.unregisterHandler, self._handler) |
|
13195.1.1
by Gary Poster
openid discovery failure should not record an OOPS. Add a new Zope view replacement test fixture to help. |
147 |
|
148 |
||
149 |
class ZopeViewReplacementFixture(Fixture): |
|
150 |
"""A fixture that allows you to temporarily replace one view with another.
|
|
13195.1.2
by Gary Poster
fix lint |
151 |
|
13195.1.1
by Gary Poster
openid discovery failure should not record an OOPS. Add a new Zope view replacement test fixture to help. |
152 |
This will not work with the AppServerLayer.
|
153 |
"""
|
|
154 |
||
155 |
def __init__(self, name, context_interface, |
|
156 |
request_interface=IDefaultBrowserLayer, |
|
157 |
replacement=None): |
|
158 |
super(ZopeViewReplacementFixture, self).__init__() |
|
159 |
self.name = name |
|
160 |
self.context_interface = context_interface |
|
161 |
self.request_interface = request_interface |
|
162 |
self.gsm = getGlobalSiteManager() |
|
163 |
# It can be convenient--bordering on necessary--to use this original
|
|
164 |
# class as a base for the replacement.
|
|
165 |
self.original = self.gsm.adapters.registered( |
|
166 |
(context_interface, request_interface), Interface, name) |
|
167 |
self.checker = getCheckerForInstancesOf(self.original) |
|
168 |
if self.original is None: |
|
169 |
# The adapter registry does not provide good methods to introspect
|
|
170 |
# it. If it did, we might try harder here.
|
|
171 |
raise ValueError( |
|
172 |
'No existing view to replace. Wrong request interface? '
|
|
173 |
'Try a layer.') |
|
174 |
self.replacement = replacement |
|
175 |
||
176 |
def setUp(self): |
|
177 |
super(ZopeViewReplacementFixture, self).setUp() |
|
178 |
if self.replacement is None: |
|
179 |
raise ValueError('replacement is not set') |
|
180 |
self.gsm.adapters.register( |
|
181 |
(self.context_interface, self.request_interface), Interface, |
|
182 |
self.name, self.replacement) |
|
183 |
# The same checker should be sufficient. If it ever isn't, we
|
|
184 |
# can add more flexibility then.
|
|
185 |
defineChecker(self.replacement, self.checker) |
|
186 |
||
187 |
def tearDown(self): |
|
188 |
super(ZopeViewReplacementFixture, self).tearDown() |
|
189 |
undefineChecker(self.replacement) |
|
190 |
self.gsm.adapters.register( |
|
191 |
(self.context_interface, self.request_interface), Interface, |
|
192 |
self.name, self.original) |