Merge lp:~allenap/launchpad/add-rabbit-service-bug-806160 into lp:launchpad

Proposed by Gavin Panella
Status: Merged
Approved by: Gavin Panella
Approved revision: no longer in the source branch.
Merged at revision: 13969
Proposed branch: lp:~allenap/launchpad/add-rabbit-service-bug-806160
Merge into: lp:launchpad
Diff against target: 423 lines (+133/-66)
11 files modified
Makefile (+2/-2)
configs/development/launchpad-lazr.conf (+7/-0)
configs/testrunner/launchpad-lazr.conf (+7/-0)
lib/canonical/config/schema-lazr.conf (+16/-9)
lib/canonical/launchpad/scripts/runlaunchpad.py (+25/-7)
lib/canonical/launchpad/scripts/tests/test_runlaunchpad.py (+4/-0)
lib/canonical/testing/layers.py (+1/-1)
lib/lp/services/rabbit/server.py (+31/-0)
lib/lp/services/rabbit/tests/test_server.py (+40/-0)
lib/lp/testing/fixture.py (+0/-21)
lib/lp/testing/tests/test_fixture.py (+0/-26)
To merge this branch: bzr merge lp:~allenap/launchpad/add-rabbit-service-bug-806160
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Approve
Review via email: mp+75195@code.launchpad.net

Commit message

[r=jtv][bug=806160] Start up RabbitMQ on a known port when using make run and make run_all.

Description of the change

This starts up a RabbitMQ server when using make run or make
run_all. It also moves the RabbitServer fixture off into its own
package.

A point of controversy: the hostname and port for the RabbitMQ service
is hard-coded into schema-lazr.conf. Rob has said that he wants this
to be dynamically allocated, and indeed rabbitfixture knows how to do
that already if you ask it, but it makes it much harder for other
processes - outside of the appserver started by make run/run_all - to
know where to connect.

I don't know of an existing way to do this so that it just works -
although I'm sure everyone has ideas - and I think it's important not
to increase development friction while we wait for it. Choosing a
fixed port is no worse than the existing hard-coded ports we have for
things like HTTP, and it gets us up and running and *developing*.

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

You write out a unique config fragment and export LPCONFIG before
starting services depending on rabbit. We do this in the test runner
and it works well - is there any reason it won't work here?

Revision history for this message
Gavin Panella (allenap) wrote :

I was thinking of something like:

$ make run_all &
$ make sync_branches

How do the scripts that sync_branches invokes know where Rabbit is?

Revision history for this message
Robert Collins (lifeless) wrote :

$ make run_all &
Assigned LPCONFIG=12345
$ export LPCONFIG=12345
$ make sync_branches

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

In case you want to address Robert's notes in a separate branch, I'm giving you my approval vote for this one—with comments:

41 === modified file 'lib/canonical/launchpad/scripts/runlaunchpad.py'
42 --- lib/canonical/launchpad/scripts/runlaunchpad.py 2011-03-07 16:32:12 +0000
43 +++ lib/canonical/launchpad/scripts/runlaunchpad.py 2011-09-13 15:01:18 +0000

64 @@ -221,6 +223,20 @@
65 process.stdin.close()
66
67
68 +class RabbitService(Service):
69 + """A RabbitMQ service."""
70 +
71 + @property
72 + def should_launch(self):
73 + return config.rabbitmq.launch
74 +
75 + def launch(self):
76 + hostname, port = config.rabbitmq.host.split(":")
77 + self.server = RabbitServer(
78 + RabbitServerResources(hostname=hostname, port=int(port)))
79 + self.useFixture(self.server)

Anything sensible to be done if no port is specified?

168 === added file 'lib/lp/services/rabbit/tests/test_server.py'
169 --- lib/lp/services/rabbit/tests/test_server.py 1970-01-01 00:00:00 +0000
170 +++ lib/lp/services/rabbit/tests/test_server.py 2011-09-13 15:01:18 +0000
171 @@ -0,0 +1,36 @@
172 +# Copyright 2011 Canonical Ltd. This software is licensed under the
173 +# GNU Affero General Public License version 3 (see the file LICENSE).
174 +
175 +"""Tests for lp.testing.fixture."""
176 +
177 +__metaclass__ = type
178 +
179 +from textwrap import dedent
180 +
181 +from fixtures import EnvironmentVariableFixture
182 +
183 +from canonical.testing.layers import BaseLayer
184 +from lp.services.rabbit.server import RabbitServer
185 +from lp.testing import TestCase
186 +
187 +
188 +class TestRabbitServer(TestCase):
189 +
190 + layer = BaseLayer
191 +
192 + def test_service_config(self):
193 + # Rabbit needs to fully isolate itself: an existing per user
194 + # .erlang.cookie has to be ignored, and ditto bogus HOME if other
195 + # tests fail to cleanup.
196 + self.useFixture(EnvironmentVariableFixture('HOME', '/nonsense/value'))
197 +
198 + # RabbitServer pokes some .ini configuration into its config.
199 + fixture = self.useFixture(RabbitServer())
200 + expected = dedent("""\
201 + [rabbitmq]
202 + host: localhost:%d
203 + userid: guest
204 + password: guest
205 + virtual_host: /
206 + """ % fixture.config.port)
207 + self.assertEqual(expected, fixture.config.service_config)

It seems unnecessarily brittle to test for the exact text. Otherwise you're really just repeating what the code does in the test. Plus, what of item ordering? What of whitespace? It's nice to have some room for cosmetic editing etc. without breaking tests.

To me it'd make more sense to parse the config snippet and assert the presence and value of the keys you care about.

Jeroen

review: Approve
Revision history for this message
Gavin Panella (allenap) wrote :

> $ make run_all &
> Assigned LPCONFIG=12345
> $ export LPCONFIG=12345
> $ make sync_branches

To me this would be unacceptable. Development is complicated enough.

Adding an extra step means another thing to remember, or another wiki
page to read, and the "Assigned LPCONFIG=12345" line would be mixed
into other log lines, or disappear off the scrollback.

Perhaps we could do something better:

- config.push() could also write out the fragments its given to
  configs/$LPCONFIG/extra-${sequence}-${name}.conf

- configs.pop() would remove the fragment from the filesystem too.

- canonical.config would automatically know to look for these extra-*
  files and push them in ${sequence} order.

- configs/*/extra-* could be added to .bzrignore

- make clean could remove them

Revision history for this message
Robert Collins (lifeless) wrote :

On Thu, Sep 15, 2011 at 5:07 AM, Gavin Panella
<email address hidden> wrote:

> Perhaps we could do something better:
>
> - config.push() could also write out the fragments its given to
>  configs/$LPCONFIG/extra-${sequence}-${name}.conf

We might want a special verb for this to avoid it happening my mistake
on production servers. Make clean probably would want to delete them
all. The outer most test layer may want to zap them all as it comes up
as well.

Other than that this sounds good.

-Rob

Revision history for this message
Gavin Panella (allenap) wrote :

> In case you want to address Robert's notes in a separate branch, I'm giving
> you my approval vote for this one—with comments:

Thanks Jeroen :)

[...]
> Anything sensible to be done if no port is specified?

I've changed this to use lazr.config.as_host_port(...,
default_host=None, default_port=None). The effect of this is that the
code in rabbitfixture will revert to its defaults if either or both
are not specified: localhost and a dynamically allocated port.

[...]
> It seems unnecessarily brittle to test for the exact text. Otherwise you're
> really just repeating what the code does in the test. Plus, what of item
> ordering? What of whitespace? It's nice to have some room for cosmetic
> editing etc. without breaking tests.
>
> To me it'd make more sense to parse the config snippet and assert the presence
> and value of the keys you care about.

I've followed your advice; the test now parses the snippet and checks
all the sections and keys.

Revision history for this message
Gavin Panella (allenap) wrote :

> On Thu, Sep 15, 2011 at 5:07 AM, Gavin Panella <...> wrote:
>
> > Perhaps we could do something better:
> >
> > - config.push() could also write out the fragments its given to
> >  configs/$LPCONFIG/extra-${sequence}-${name}.conf
>
> We might want a special verb for this to avoid it happening my mistake
> on production servers.

By special verb, do you mean an alternative to .push() and .pop()? If
so, it might instead be worth having the special verb for pushing and
popping outside of dev/test; there are only a few places where these
methods are used outside of test/dev code:

  lib/lp/registry/scripts/distributionmirror_prober.py
  lib/canonical/launchpad/scripts/__init__.py
  lib/canonical/testing/layers.py
  lib/canonical/database/sqlbase.py

(In addition, .push() and .pop() could be disallowed - or warned about
- in non-dev/test environments.)

> Make clean probably would want to delete them all.

Agreed.

> The outer most test layer may want to zap them all as it comes up as
> well.

Agreed, thanks for thinking of that.

> Other than that this sounds good.

Tip top, thank you. Do you *need* me to do that before landing this
branch, or can I land this with a promise to sort out this new idea
asap? Red Squad are going to be working on longpoll as of now so even
a day or two's delay on this is going to affect that.

Revision history for this message
Robert Collins (lifeless) wrote :

On Thu, Sep 15, 2011 at 7:39 AM, Gavin Panella
<email address hidden> wrote:

> Tip top, thank you. Do you *need* me to do that before landing this
> branch, or can I land this with a promise to sort out this new idea
> asap? Red Squad are going to be working on longpoll as of now so even
> a day or two's delay on this is going to affect that.

asap is fine.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile'
--- Makefile 2011-09-10 09:01:08 +0000
+++ Makefile 2011-09-15 19:55:38 +0000
@@ -253,7 +253,7 @@
253 $(PY) cronscripts/merge-proposal-jobs.py -v253 $(PY) cronscripts/merge-proposal-jobs.py -v
254254
255run: build inplace stop255run: build inplace stop
256 bin/run -r librarian,google-webservice,memcached -i $(LPCONFIG)256 bin/run -r librarian,google-webservice,memcached,rabbitmq -i $(LPCONFIG)
257257
258run.gdb:258run.gdb:
259 echo 'run' > run.gdb259 echo 'run' > run.gdb
@@ -265,7 +265,7 @@
265265
266run_all: build inplace stop266run_all: build inplace stop
267 bin/run \267 bin/run \
268 -r librarian,sftp,forker,mailman,codebrowse,google-webservice,memcached \268 -r librarian,sftp,forker,mailman,codebrowse,google-webservice,memcached,rabbitmq \
269 -i $(LPCONFIG)269 -i $(LPCONFIG)
270270
271run_codebrowse: build271run_codebrowse: build
272272
=== modified file 'configs/development/launchpad-lazr.conf'
--- configs/development/launchpad-lazr.conf 2011-08-14 23:11:45 +0000
+++ configs/development/launchpad-lazr.conf 2011-09-15 19:55:38 +0000
@@ -239,6 +239,13 @@
239host_key_private=lib/lp/poppy/tests/poppy-sftp239host_key_private=lib/lp/poppy/tests/poppy-sftp
240host_key_public=lib/lp/poppy/tests/poppy-sftp.pub240host_key_public=lib/lp/poppy/tests/poppy-sftp.pub
241241
242[rabbitmq]
243launch: True
244host: localhost:56720
245userid: guest
246password: guest
247virtual_host: /
248
242[reclaimbranchspace]249[reclaimbranchspace]
243error_dir: /var/tmp/codehosting.test250error_dir: /var/tmp/codehosting.test
244oops_prefix: RBS251oops_prefix: RBS
245252
=== modified file 'configs/testrunner/launchpad-lazr.conf'
--- configs/testrunner/launchpad-lazr.conf 2011-09-05 15:42:27 +0000
+++ configs/testrunner/launchpad-lazr.conf 2011-09-15 19:55:38 +0000
@@ -201,6 +201,13 @@
201oops_prefix: TAPPORTBLOB201oops_prefix: TAPPORTBLOB
202error_dir: /var/tmp/lperr.test202error_dir: /var/tmp/lperr.test
203203
204[rabbitmq]
205launch: False
206host: none
207userid: none
208password: none
209virtual_host: none
210
204[request_daily_builds]211[request_daily_builds]
205oops_prefix: TRDB212oops_prefix: TRDB
206error_dir: /var/tmp/lperr.test213error_dir: /var/tmp/lperr.test
207214
=== modified file 'lib/canonical/config/schema-lazr.conf'
--- lib/canonical/config/schema-lazr.conf 2011-09-02 16:22:48 +0000
+++ lib/canonical/config/schema-lazr.conf 2011-09-15 19:55:38 +0000
@@ -511,7 +511,8 @@
511forced_hostname: none511forced_hostname: none
512512
513# Where to find the code import scheduler service.513# Where to find the code import scheduler service.
514codeimportscheduler_url: http://xmlrpc-private.launchpad.dev:8087/codeimportscheduler514codeimportscheduler_url:
515 http://xmlrpc-private.launchpad.dev:8087/codeimportscheduler
515516
516# The maximum number of jobs to run on a machine at one time.517# The maximum number of jobs to run on a machine at one time.
517max_jobs_per_machine: 3518max_jobs_per_machine: 3
@@ -585,7 +586,8 @@
585# The database user which will be used by this process.586# The database user which will be used by this process.
586# datatype: string587# datatype: string
587dbuser: rosettaadmin588dbuser: rosettaadmin
588source_interface: lp.translations.interfaces.translationpackagingjob.ITranslationPackagingJobSource589source_interface:
590 lp.translations.interfaces.translationpackagingjob.ITranslationPackagingJobSource
589591
590# See [error_reports].592# See [error_reports].
591error_dir: none593error_dir: none
@@ -950,7 +952,8 @@
950952
951[initializedistroseries]953[initializedistroseries]
952dbuser: initializedistroseries954dbuser: initializedistroseries
953source_interface: lp.soyuz.interfaces.distributionjob.IInitializeDistroSeriesJobSource955source_interface:
956 lp.soyuz.interfaces.distributionjob.IInitializeDistroSeriesJobSource
954957
955# See [error_reports].958# See [error_reports].
956error_dir: none959error_dir: none
@@ -1025,7 +1028,8 @@
1025# domains listed here will be sent to the parent domain,1028# domains listed here will be sent to the parent domain,
1026# allowing sessions to be shared between vhosts.1029# allowing sessions to be shared between vhosts.
1027# Domains should not start with a leading '.'.1030# Domains should not start with a leading '.'.
1028cookie_domains: demo.launchpad.net, staging.launchpad.net, launchpad.net, launchpad.dev1031cookie_domains:
1032 demo.launchpad.net, staging.launchpad.net, launchpad.net, launchpad.dev
10291033
1030# Maximum size of product release download files in bytes. A value1034# Maximum size of product release download files in bytes. A value
1031# of 0 means no limit.1035# of 0 means no limit.
@@ -1702,15 +1706,18 @@
1702memory_profile_log:1706memory_profile_log:
17031707
1704[rabbitmq]1708[rabbitmq]
1709# Should RabbitMQ be launched by default?
1710# datatype: boolean
1711launch: False
1705# The host:port at which RabbitMQ is listening.1712# The host:port at which RabbitMQ is listening.
1706# datatype: string1713# datatype: string
1707host: none1714host: none
1708# datatype: string1715# datatype: string
1709userid: guest1716userid: none
1710# datatype: string1717# datatype: string
1711password: guest1718password: none
1712# datatype: string1719# datatype: string
1713virtual_host: /1720virtual_host: none
17141721
1715[reclaimbranchspace]1722[reclaimbranchspace]
1716# The database user which will be used by this process.1723# The database user which will be used by this process.
17171724
=== modified file 'lib/canonical/launchpad/scripts/runlaunchpad.py'
--- lib/canonical/launchpad/scripts/runlaunchpad.py 2011-03-07 16:32:12 +0000
+++ lib/canonical/launchpad/scripts/runlaunchpad.py 2011-09-15 19:55:38 +0000
@@ -14,6 +14,8 @@
14import sys14import sys
1515
16import fixtures16import fixtures
17from lazr.config import as_host_port
18from rabbitfixture.server import RabbitServerResources
17from zope.app.server.main import main19from zope.app.server.main import main
1820
19from canonical.config import config21from canonical.config import config
@@ -22,9 +24,10 @@
22 make_pidfile,24 make_pidfile,
23 pidfile_path,25 pidfile_path,
24 )26 )
27from lp.services.googlesearch import googletestservice
25from lp.services.mailman import runmailman28from lp.services.mailman import runmailman
26from lp.services.osutils import ensure_directory_exists29from lp.services.osutils import ensure_directory_exists
27from lp.services.googlesearch import googletestservice30from lp.services.rabbit.server import RabbitServer
2831
2932
30def make_abspath(path):33def make_abspath(path):
@@ -221,6 +224,20 @@
221 process.stdin.close()224 process.stdin.close()
222225
223226
227class RabbitService(Service):
228 """A RabbitMQ service."""
229
230 @property
231 def should_launch(self):
232 return config.rabbitmq.launch
233
234 def launch(self):
235 hostname, port = as_host_port(config.rabbitmq.host, None, None)
236 self.server = RabbitServer(
237 RabbitServerResources(hostname=hostname, port=port))
238 self.useFixture(self.server)
239
240
224def stop_process(process):241def stop_process(process):
225 """kill process and BLOCK until process dies.242 """kill process and BLOCK until process dies.
226243
@@ -245,6 +262,7 @@
245 'codebrowse': CodebrowseService(),262 'codebrowse': CodebrowseService(),
246 'google-webservice': GoogleWebService(),263 'google-webservice': GoogleWebService(),
247 'memcached': MemcachedService(),264 'memcached': MemcachedService(),
265 'rabbitmq': RabbitService(),
248 }266 }
249267
250268
@@ -287,8 +305,8 @@
287 """305 """
288 if '-i' in args:306 if '-i' in args:
289 index = args.index('-i')307 index = args.index('-i')
290 config.setInstance(args[index+1])308 config.setInstance(args[index + 1])
291 del args[index:index+2]309 del args[index:index + 2]
292310
293 if '-C' not in args:311 if '-C' not in args:
294 zope_config_file = config.zope_config_file312 zope_config_file = config.zope_config_file
@@ -319,10 +337,10 @@
319 if config.launchpad.launch:337 if config.launchpad.launch:
320 main(argv)338 main(argv)
321 else:339 else:
322 # We just need the foreground process to sit around forever waiting340 # We just need the foreground process to sit around forever
323 # for the signal to shut everything down. Normally, Zope itself would341 # waiting for the signal to shut everything down. Normally, Zope
324 # be this master process, but we're not starting that up, so we need342 # itself would be this master process, but we're not starting that
325 # to do something else.343 # up, so we need to do something else.
326 try:344 try:
327 signal.pause()345 signal.pause()
328 except KeyboardInterrupt:346 except KeyboardInterrupt:
329347
=== modified file 'lib/canonical/launchpad/scripts/tests/test_runlaunchpad.py'
--- lib/canonical/launchpad/scripts/tests/test_runlaunchpad.py 2010-10-11 02:37:27 +0000
+++ lib/canonical/launchpad/scripts/tests/test_runlaunchpad.py 2011-09-15 19:55:38 +0000
@@ -152,6 +152,10 @@
152 if config.google_test_service.launch:152 if config.google_test_service.launch:
153 expected.append(SERVICES['google-webservice'])153 expected.append(SERVICES['google-webservice'])
154154
155 # RabbitMQ may or may not be asked to run.
156 if config.rabbitmq.launch:
157 expected.append(SERVICES['rabbitmq'])
158
155 expected = sorted(expected)159 expected = sorted(expected)
156 self.assertEqual(expected, services)160 self.assertEqual(expected, services)
157161
158162
=== modified file 'lib/canonical/testing/layers.py'
--- lib/canonical/testing/layers.py 2011-09-13 08:44:05 +0000
+++ lib/canonical/testing/layers.py 2011-09-15 19:55:38 +0000
@@ -143,13 +143,13 @@
143import lp.services.mail.stub143import lp.services.mail.stub
144from lp.services.memcache.client import memcache_client_factory144from lp.services.memcache.client import memcache_client_factory
145from lp.services.osutils import kill_by_pidfile145from lp.services.osutils import kill_by_pidfile
146from lp.services.rabbit.server import RabbitServer
146from lp.testing import (147from lp.testing import (
147 ANONYMOUS,148 ANONYMOUS,
148 is_logged_in,149 is_logged_in,
149 login,150 login,
150 logout,151 logout,
151 )152 )
152from lp.testing.fixture import RabbitServer
153from lp.testing.pgsql import PgTestSetup153from lp.testing.pgsql import PgTestSetup
154154
155155
156156
=== added directory 'lib/lp/services/rabbit'
=== added file 'lib/lp/services/rabbit/__init__.py'
=== added file 'lib/lp/services/rabbit/server.py'
--- lib/lp/services/rabbit/server.py 1970-01-01 00:00:00 +0000
+++ lib/lp/services/rabbit/server.py 2011-09-15 19:55:38 +0000
@@ -0,0 +1,31 @@
1# Copyright 2011 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""RabbitMQ server fixture."""
5
6__metaclass__ = type
7__all__ = [
8 'RabbitServer',
9 ]
10
11from textwrap import dedent
12
13import rabbitfixture.server
14
15
16class RabbitServer(rabbitfixture.server.RabbitServer):
17 """A RabbitMQ server fixture with Launchpad-specific config.
18
19 :ivar service_config: A snippet of .ini that describes the `rabbitmq`
20 configuration.
21 """
22
23 def setUp(self):
24 super(RabbitServer, self).setUp()
25 self.config.service_config = dedent("""\
26 [rabbitmq]
27 host: localhost:%d
28 userid: guest
29 password: guest
30 virtual_host: /
31 """ % self.config.port)
032
=== added directory 'lib/lp/services/rabbit/tests'
=== added file 'lib/lp/services/rabbit/tests/__init__.py'
=== added file 'lib/lp/services/rabbit/tests/test_server.py'
--- lib/lp/services/rabbit/tests/test_server.py 1970-01-01 00:00:00 +0000
+++ lib/lp/services/rabbit/tests/test_server.py 2011-09-15 19:55:38 +0000
@@ -0,0 +1,40 @@
1# Copyright 2011 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Tests for lp.testing.fixture."""
5
6__metaclass__ = type
7
8from ConfigParser import SafeConfigParser
9from StringIO import StringIO
10
11from fixtures import EnvironmentVariableFixture
12
13from canonical.testing.layers import BaseLayer
14from lp.services.rabbit.server import RabbitServer
15from lp.testing import TestCase
16
17
18class TestRabbitServer(TestCase):
19
20 layer = BaseLayer
21
22 def test_service_config(self):
23 # Rabbit needs to fully isolate itself: an existing per user
24 # .erlang.cookie has to be ignored, and ditto bogus HOME if other
25 # tests fail to cleanup.
26 self.useFixture(EnvironmentVariableFixture('HOME', '/nonsense/value'))
27
28 # RabbitServer pokes some .ini configuration into its config.
29 fixture = self.useFixture(RabbitServer())
30 service_config = SafeConfigParser()
31 service_config.readfp(StringIO(fixture.config.service_config))
32 self.assertEqual(["rabbitmq"], service_config.sections())
33 expected = {
34 "host": "localhost:%d" % fixture.config.port,
35 "userid": "guest",
36 "password": "guest",
37 "virtual_host": "/",
38 }
39 observed = dict(service_config.items("rabbitmq"))
40 self.assertEqual(expected, observed)
041
=== modified file 'lib/lp/testing/fixture.py'
--- lib/lp/testing/fixture.py 2011-09-05 16:39:46 +0000
+++ lib/lp/testing/fixture.py 2011-09-15 19:55:38 +0000
@@ -5,7 +5,6 @@
55
6__metaclass__ = type6__metaclass__ = type
7__all__ = [7__all__ = [
8 'RabbitServer',
9 'ZopeAdapterFixture',8 'ZopeAdapterFixture',
10 'ZopeEventHandlerFixture',9 'ZopeEventHandlerFixture',
11 'ZopeViewReplacementFixture',10 'ZopeViewReplacementFixture',
@@ -13,14 +12,12 @@
1312
14from ConfigParser import SafeConfigParser13from ConfigParser import SafeConfigParser
15import os.path14import os.path
16from textwrap import dedent
1715
18from fixtures import (16from fixtures import (
19 EnvironmentVariableFixture,17 EnvironmentVariableFixture,
20 Fixture,18 Fixture,
21 )19 )
22import pgbouncer.fixture20import pgbouncer.fixture
23import rabbitfixture.server
24from zope.component import (21from zope.component import (
25 getGlobalSiteManager,22 getGlobalSiteManager,
26 provideHandler,23 provideHandler,
@@ -36,24 +33,6 @@
36from canonical.config import config33from canonical.config import config
3734
3835
39class 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
57class PGBouncerFixture(pgbouncer.fixture.PGBouncerFixture):36class PGBouncerFixture(pgbouncer.fixture.PGBouncerFixture):
58 """Inserts a controllable pgbouncer instance in front of PostgreSQL.37 """Inserts a controllable pgbouncer instance in front of PostgreSQL.
5938
6039
=== modified file 'lib/lp/testing/tests/test_fixture.py'
--- lib/lp/testing/tests/test_fixture.py 2011-09-05 15:42:27 +0000
+++ lib/lp/testing/tests/test_fixture.py 2011-09-15 19:55:38 +0000
@@ -5,9 +5,6 @@
55
6__metaclass__ = type6__metaclass__ = type
77
8from textwrap import dedent
9
10from fixtures import EnvironmentVariableFixture
11import psycopg28import psycopg2
12from storm.exceptions import DisconnectionError9from storm.exceptions import DisconnectionError
13from zope.component import (10from zope.component import (
@@ -30,33 +27,10 @@
30from lp.testing import TestCase27from lp.testing import TestCase
31from lp.testing.fixture import (28from lp.testing.fixture import (
32 PGBouncerFixture,29 PGBouncerFixture,
33 RabbitServer,
34 ZopeAdapterFixture,30 ZopeAdapterFixture,
35 )31 )
3632
3733
38class TestRabbitServer(TestCase):
39
40 layer = BaseLayer
41
42 def test_service_config(self):
43 # Rabbit needs to fully isolate itself: an existing per user
44 # .erlange.cookie has to be ignored, and ditto bogus HOME if other
45 # tests fail to cleanup.
46 self.useFixture(EnvironmentVariableFixture('HOME', '/nonsense/value'))
47
48 # RabbitServer pokes some .ini configuration into its config.
49 with RabbitServer() as fixture:
50 expected = dedent("""\
51 [rabbitmq]
52 host: localhost:%d
53 userid: guest
54 password: guest
55 virtual_host: /
56 """ % fixture.config.port)
57 self.assertEqual(expected, fixture.config.service_config)
58
59
60class IFoo(Interface):34class IFoo(Interface):
61 pass35 pass
6236