Merge lp:~danilo/launchpad/bug-817398 into lp:launchpad

Proposed by Данило Шеган
Status: Merged
Approved by: Данило Шеган
Approved revision: no longer in the source branch.
Merged at revision: 14171
Proposed branch: lp:~danilo/launchpad/bug-817398
Merge into: lp:launchpad
Diff against target: 349 lines (+99/-19)
10 files modified
configs/development/launchpad-lazr.conf (+1/-0)
lib/canonical/buildd/debian/changelog (+6/-0)
lib/canonical/buildd/generate-translation-templates (+3/-2)
lib/lp/poppy/tests/test_poppy.py (+3/-3)
lib/lp/translations/configure.zcml (+7/-1)
lib/lp/translations/model/translationtemplatesbuild.py (+12/-2)
lib/lp/translations/model/translationtemplatesbuildbehavior.py (+50/-9)
lib/lp/translations/stories/buildfarm/xx-build-summary.txt (+1/-1)
lib/lp/translations/tests/test_translationtemplatesbuildbehavior.py (+13/-0)
utilities/make-lp-user (+3/-1)
To merge this branch: bzr merge lp:~danilo/launchpad/bug-817398
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Approve
Review via email: mp+79571@code.launchpad.net

Commit message

[r=jtv][bug=817398] Pass the path pottery is installed into as PYTHONPATH when running generate_translation_templates.py on the buildd slaves. Also link all the relevant bits for TranslationTemplateBuilds to show up in the builder history web pages together with their log files. Oh yeah, finally.

Description of the change

= Bug 817398: template generation (WIP) =

Template generation has stopped working when buildd default image has switched to Ubuntu Natty (as the development version). That included Python 2.7 by default and generate-translation-templates hard-coded Python 2.6 module path.

This is easy to fix, but this has been broken for quite some time (maybe a full year even) because there is no proper logging for TranslationTemplatesBuild jobs. I decided to introduce that to avoid further breakage going unnoticed for this long.

== Implementation details ==

1. configs/development/launchpad-lazr.conf: change the default development poppy port so it doesn't conflict with codehosting port, thus allowing both to be run locally simultaneously
2. utilities/make-lp-user fails for me with no default timeout function set, so setting one makes it work
3. generate-translation-templates is an actual fix for the bug 817398; as an extra measure of protection, I pass PYTHONPATH in the ultimate script run to ensure modules are found even if Python 2.8 ever comes out for instance
4. configure.zcml copies a similar declaration that SourcePackageRecipeBuild is using (otherwise, a removeSecurityProxy would have to be used inside buildmaster/model/manager.py when .status is being set, and in other places introduced in this branch)
5. translationtemplatebuild.py provides a nicer title for TranslationTemplateBuilds compared to the default, and provides a direct link to librarian files for logs from the builds (since we do not support private branches for template generation, no need to proxy these URLs).
6. translationtemplatesbuildbehavior.py introduces fetching of the log files and saving them like PackageBuildDerived does

I've only did the minimal test changes. I don't think I can spend more time on this branch, but I did spend a lot of time trying stuff out locally. Ideally, most of this code would be refactored to use the "generic" infrastructure provided by things like PackageBuildDerived, but that's more involved than it sounds.

== Tests ==

bin/test -vvt translationtemplatesbuild -t xx-build-behavior.txt -t TestPoppy

== Demo and Q/A ==

 * Set up translation import for a project (translations.l.n/<project/+configure-translations and translations.l.n/<project>/trunk/+translations-settings
 * Push a branch which should generate translation template (eg. lp:eog) to staging, link it to the trunk series (what was set-up above)
 * Run cronscripts/scan-branches.py to scan the branch and generate translation templates build job
 * Wait for build-manager to pick it up and build it (you may need to ask for it to be run on staging as "bin/twistd --logile ... --pidfile ... -y daemons/buildd-manager.tac -n" — -n to not daemonize it so you could see any exceptions if they happen)
 * When the job finishes, it should keep the log in the builder history available from the builder page on launchpad.net/builders

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  configs/development/launchpad-lazr.conf
  lib/canonical/buildd/generate-translation-templates
  lib/canonical/buildd/debian/changelog
  lib/lp/poppy/tests/test_poppy.py
  lib/lp/translations/configure.zcml
  lib/lp/translations/model/translationtemplatesbuild.py
  lib/lp/translations/model/translationtemplatesbuildbehavior.py
  lib/lp/translations/stories/buildfarm/xx-build-summary.txt
  lib/lp/translations/tests/test_translationtemplatesbuildbehavior.py
  utilities/make-lp-user

./configs/development/launchpad-lazr.conf
      92: Line exceeds 78 characters.
     111: Line exceeds 78 characters.
     125: Line exceeds 78 characters.
./lib/canonical/buildd/generate-translation-templates
      59: Line exceeds 78 characters.
./lib/canonical/buildd/debian/changelog
     232: Line exceeds 78 characters.
     298: Line exceeds 78 characters.
     488: Line exceeds 78 characters.
     495: Line exceeds 78 characters.
     516: Line exceeds 78 characters.
     522: Line exceeds 78 characters.
     528: Line exceeds 78 characters.
     534: Line exceeds 78 characters.
     541: Line exceeds 78 characters.
     549: Line exceeds 78 characters.
     556: Line exceeds 78 characters.
     570: Line exceeds 78 characters.
     576: Line exceeds 78 characters.
     582: Line exceeds 78 characters.
     590: Line exceeds 78 characters.
     596: Line exceeds 78 characters.
     603: Line exceeds 78 characters.
     614: Line exceeds 78 characters.
     623: Line exceeds 78 characters.
     630: Line exceeds 78 characters.
     636: Line exceeds 78 characters.
     643: Line exceeds 78 characters.
     649: Line exceeds 78 characters.
     655: Line exceeds 78 characters.
     662: Line exceeds 78 characters.
     669: Line exceeds 78 characters.
     676: Line exceeds 78 characters.
     683: Line exceeds 78 characters.
     689: Line exceeds 78 characters.

To post a comment you must log in.
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Looks good. As agreed on IRC, please make test_poppy.py get poppy's port number from the config so you don't have to hard-code matching port numbers.

It's a good thing I'm reviewing this branch. It is going to clash with one I have pending, which puts buildd-manager in a read-only transaction policy by default. Build-master callbacks that need to write to the database will then have to open an explicit write transaction, make their changes, and commit before returning. Otherwise there seems to be a risk of another builder committing or aborting your changes while your builder is waiting for a slave XMLRPC call to return (and we've had reports of problems that seem to be symptoms of this actually happening).

Thanks for fixing this. Lack of monitoring of these jobs has been a thorn in my side for years now!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'configs/development/launchpad-lazr.conf'
--- configs/development/launchpad-lazr.conf 2011-09-30 16:01:42 +0000
+++ configs/development/launchpad-lazr.conf 2011-10-19 12:27:49 +0000
@@ -239,6 +239,7 @@
239authentication_endpoint: http://xmlrpc-private.launchpad.dev:8087/authserver239authentication_endpoint: http://xmlrpc-private.launchpad.dev:8087/authserver
240host_key_private=lib/lp/poppy/tests/poppy-sftp240host_key_private=lib/lp/poppy/tests/poppy-sftp
241host_key_public=lib/lp/poppy/tests/poppy-sftp.pub241host_key_public=lib/lp/poppy/tests/poppy-sftp.pub
242port: tcp:5023
242243
243[rabbitmq]244[rabbitmq]
244launch: True245launch: True
245246
=== modified file 'lib/canonical/buildd/debian/changelog'
--- lib/canonical/buildd/debian/changelog 2011-09-26 06:30:07 +0000
+++ lib/canonical/buildd/debian/changelog 2011-10-19 12:27:49 +0000
@@ -1,3 +1,9 @@
1launchpad-buildd (81) hardy-cat; urgency=low
2
3 * generate-translation-templates: switch to Python 2.7.
4
5 -- Danilo Šegan <danilo@canonical.com> Mon, 17 Oct 2011 14:46:13 +0200
6
1launchpad-buildd (80) hardy-cat; urgency=low7launchpad-buildd (80) hardy-cat; urgency=low
28
3 * binfmt-support demonstrated umount ordering issues for us. LP: #8519349 * binfmt-support demonstrated umount ordering issues for us. LP: #851934
410
=== modified file 'lib/canonical/buildd/generate-translation-templates'
--- lib/canonical/buildd/generate-translation-templates 2010-12-21 17:52:32 +0000
+++ lib/canonical/buildd/generate-translation-templates 2011-10-19 12:27:49 +0000
@@ -41,7 +41,7 @@
41BUILDD_PACKAGE=canonical/buildd41BUILDD_PACKAGE=canonical/buildd
42POTTERY=$BUILDD_PACKAGE/pottery42POTTERY=$BUILDD_PACKAGE/pottery
43# The script should be smarter about detecting the python version.43# The script should be smarter about detecting the python version.
44PYMODULES=/usr/lib/pymodules/python2.644PYMODULES=/usr/lib/pymodules/python2.7
45echo -n "Default Python in the chroot is: "45echo -n "Default Python in the chroot is: "
46$BUILD_CHROOT/usr/bin/python --version46$BUILD_CHROOT/usr/bin/python --version
4747
@@ -62,4 +62,5 @@
6262
63# Enter chroot, switch back to unprivileged user, execute the generate script.63# Enter chroot, switch back to unprivileged user, execute the generate script.
64$SUDO $CHROOT $BUILD_CHROOT \64$SUDO $CHROOT $BUILD_CHROOT \
65 $SU - $USER -c "$GENERATE_SCRIPT $BRANCH_URL $RESULT_NAME"65 $SU - $USER \
66 -c "PYTHONPATH=$PYMODULES $GENERATE_SCRIPT $BRANCH_URL $RESULT_NAME"
6667
=== modified file 'lib/lp/poppy/tests/test_poppy.py'
--- lib/lp/poppy/tests/test_poppy.py 2011-02-24 17:38:19 +0000
+++ lib/lp/poppy/tests/test_poppy.py 2011-10-19 12:27:49 +0000
@@ -83,7 +83,7 @@
83 def __init__(self, root_dir, factory):83 def __init__(self, root_dir, factory):
84 self.root_dir = root_dir84 self.root_dir = root_dir
85 self._factory = factory85 self._factory = factory
86 self.port = 502286 self.port = int(config.poppy.port.partition(':')[2])
8787
88 def addSSHKey(self, person, public_key_path):88 def addSSHKey(self, person, public_key_path):
89 f = open(public_key_path, 'r')89 f = open(public_key_path, 'r')
@@ -221,7 +221,7 @@
221221
222 if transport is None:222 if transport is None:
223 transport = self.server.getTransport()223 transport = self.server.getTransport()
224 transport.stat('foo/bar') # .stat will implicity chdir for us224 transport.stat('foo/bar') # .stat will implicity chdir for us
225225
226 self.server.disconnect(transport)226 self.server.disconnect(transport)
227 self.server.waitForClose()227 self.server.waitForClose()
@@ -400,7 +400,7 @@
400 self.assertRaises(400 self.assertRaises(
401 ftplib.error_perm,401 ftplib.error_perm,
402 f.storbinary,402 f.storbinary,
403 'STOR '+'foo_source.changes',403 'STOR ' + 'foo_source.changes',
404 fake_file)404 fake_file)
405405
406406
407407
=== modified file 'lib/lp/translations/configure.zcml'
--- lib/lp/translations/configure.zcml 2011-08-29 00:13:22 +0000
+++ lib/lp/translations/configure.zcml 2011-10-19 12:27:49 +0000
@@ -659,7 +659,13 @@
659 <!-- TranslationTemplatesBuild -->659 <!-- TranslationTemplatesBuild -->
660 <class660 <class
661 class="lp.translations.model.translationtemplatesbuild.TranslationTemplatesBuild">661 class="lp.translations.model.translationtemplatesbuild.TranslationTemplatesBuild">
662 <allow interface="lp.translations.interfaces.translationtemplatesbuild.ITranslationTemplatesBuild"/>662 <require permission="launchpad.View" interface="lp.translations.interfaces.translationtemplatesbuild.ITranslationTemplatesBuild"/>
663 <!-- This is needed for BuildManager to run. The permission isn't
664 important; launchpad.Edit isn't actually held by anybody.
665 Inspired by the similar change for SourcePackageRecipeBuild. -->
666 <require permission="launchpad.Edit"
667 set_attributes="builder date_finished date_started log status" />
668
663 </class>669 </class>
664 <securedutility670 <securedutility
665 component="lp.translations.model.translationtemplatesbuild.TranslationTemplatesBuild"671 component="lp.translations.model.translationtemplatesbuild.TranslationTemplatesBuild"
666672
=== modified file 'lib/lp/translations/model/translationtemplatesbuild.py'
--- lib/lp/translations/model/translationtemplatesbuild.py 2011-05-04 04:10:58 +0000
+++ lib/lp/translations/model/translationtemplatesbuild.py 2011-10-19 12:27:49 +0000
@@ -13,12 +13,10 @@
13 Reference,13 Reference,
14 Storm,14 Storm,
15 )15 )
16from storm.store import Store
17from zope.interface import (16from zope.interface import (
18 classProvides,17 classProvides,
19 implements,18 implements,
20 )19 )
21from zope.security.proxy import ProxyFactory
2220
23from canonical.launchpad.interfaces.lpstorm import IStore21from canonical.launchpad.interfaces.lpstorm import IStore
24from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived22from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived
@@ -49,6 +47,11 @@
49 branch_id = Int(name='branch', allow_none=False)47 branch_id = Int(name='branch', allow_none=False)
50 branch = Reference(branch_id, 'Branch.id')48 branch = Reference(branch_id, 'Branch.id')
5149
50 @property
51 def title(self):
52 return u'Translation template build for %s' % (
53 self.branch.displayname)
54
52 def __init__(self, build_farm_job, branch):55 def __init__(self, build_farm_job, branch):
53 super(TranslationTemplatesBuild, self).__init__()56 super(TranslationTemplatesBuild, self).__init__()
54 self.build_farm_job = build_farm_job57 self.build_farm_job = build_farm_job
@@ -110,3 +113,10 @@
110 return store.find(113 return store.find(
111 TranslationTemplatesBuild,114 TranslationTemplatesBuild,
112 TranslationTemplatesBuild.branch == branch)115 TranslationTemplatesBuild.branch == branch)
116
117 @property
118 def log_url(self):
119 """See `IBuildFarmJob`."""
120 if self.log is None:
121 return None
122 return self.log.http_url
113123
=== modified file 'lib/lp/translations/model/translationtemplatesbuildbehavior.py'
--- lib/lp/translations/model/translationtemplatesbuildbehavior.py 2011-09-07 15:10:38 +0000
+++ lib/lp/translations/model/translationtemplatesbuildbehavior.py 2011-10-19 12:27:49 +0000
@@ -11,7 +11,9 @@
11 'TranslationTemplatesBuildBehavior',11 'TranslationTemplatesBuildBehavior',
12 ]12 ]
1313
14import datetime
14import os15import os
16import pytz
15import tempfile17import tempfile
1618
17from twisted.internet import defer19from twisted.internet import defer
@@ -20,6 +22,7 @@
20from zope.security.proxy import removeSecurityProxy22from zope.security.proxy import removeSecurityProxy
2123
22from lp.app.interfaces.launchpad import ILaunchpadCelebrities24from lp.app.interfaces.launchpad import ILaunchpadCelebrities
25from lp.buildmaster.enums import BuildStatus
23from lp.buildmaster.interfaces.buildfarmjobbehavior import (26from lp.buildmaster.interfaces.buildfarmjobbehavior import (
24 IBuildFarmJobBehavior,27 IBuildFarmJobBehavior,
25 )28 )
@@ -111,6 +114,35 @@
111 if len(raw_slave_status) >= 4:114 if len(raw_slave_status) >= 4:
112 status['filemap'] = raw_slave_status[3]115 status['filemap'] = raw_slave_status[3]
113116
117 def setBuildStatus(self, status):
118 self.build.status = status
119
120 @staticmethod
121 def getLogFromSlave(templates_build, queue_item):
122 """See `IPackageBuild`."""
123 SLAVE_LOG_FILENAME = 'buildlog'
124 builder = queue_item.builder
125 d = builder.transferSlaveFileToLibrarian(
126 SLAVE_LOG_FILENAME,
127 templates_build.buildfarmjob.getLogFileName(),
128 False)
129 return d
130
131 @staticmethod
132 def storeBuildInfo(build, queue_item, build_status):
133 """See `IPackageBuild`."""
134 def got_log(lfa_id):
135 build.build.log = lfa_id
136 build.build.builder = queue_item.builder
137 build.build.date_started = queue_item.date_started
138 # XXX cprov 20060615 bug=120584: Currently buildduration includes
139 # the scanner latency, it should really be asking the slave for
140 # the duration spent building locally.
141 build.build.date_finished = datetime.datetime.now(pytz.UTC)
142
143 d = build.getLogFromSlave(build, queue_item)
144 return d.addCallback(got_log)
145
114 def updateBuild_WAITING(self, queue_item, slave_status, logtail, logger):146 def updateBuild_WAITING(self, queue_item, slave_status, logtail, logger):
115 """Deal with a finished ("WAITING" state, perversely) build job.147 """Deal with a finished ("WAITING" state, perversely) build job.
116148
@@ -139,6 +171,7 @@
139 # dangerous.171 # dangerous.
140 if filename is None:172 if filename is None:
141 logger.error("Build produced no tarball.")173 logger.error("Build produced no tarball.")
174 self.setBuildStatus(BuildStatus.FULLYBUILT)
142 return175 return
143176
144 tarball_file = open(filename)177 tarball_file = open(filename)
@@ -152,15 +185,23 @@
152 queue_item.specific_job.branch, tarball, logger)185 queue_item.specific_job.branch, tarball, logger)
153 logger.debug("Upload complete.")186 logger.debug("Upload complete.")
154 finally:187 finally:
188 self.setBuildStatus(BuildStatus.FULLYBUILT)
155 tarball_file.close()189 tarball_file.close()
156 os.remove(filename)190 os.remove(filename)
157191
158 if build_status == 'OK':192 def build_info_stored(ignored):
159 logger.debug("Processing successful templates build.")193 if build_status == 'OK':
160 filemap = slave_status.get('filemap')194 self.setBuildStatus(BuildStatus.UPLOADING)
161 d = self._readTarball(queue_item, filemap, logger)195 logger.debug("Processing successful templates build.")
162 d.addCallback(got_tarball)196 filemap = slave_status.get('filemap')
163 d.addCallback(clean_slave)197 d = self._readTarball(queue_item, filemap, logger)
164 return d198 d.addCallback(got_tarball)
165199 d.addCallback(clean_slave)
166 return clean_slave(None)200 return d
201
202 self.setBuildStatus(BuildStatus.FAILEDTOBUILD)
203 return clean_slave(None)
204
205 d = self.storeBuildInfo(self, queue_item, build_status)
206 d.addCallback(build_info_stored)
207 return d
167208
=== modified file 'lib/lp/translations/stories/buildfarm/xx-build-summary.txt'
--- lib/lp/translations/stories/buildfarm/xx-build-summary.txt 2011-07-01 19:17:03 +0000
+++ lib/lp/translations/stories/buildfarm/xx-build-summary.txt 2011-10-19 12:27:49 +0000
@@ -157,5 +157,5 @@
157 Build history for ...157 Build history for ...
158 1 ... 1 of 1 result158 1 ... 1 of 1 result
159 ...159 ...
160 Translation template build160 Translation template build for lp://dev/qblark
161 Build started ... and finished ... taking 5 minutes161 Build started ... and finished ... taking 5 minutes
162162
=== modified file 'lib/lp/translations/tests/test_translationtemplatesbuildbehavior.py'
--- lib/lp/translations/tests/test_translationtemplatesbuildbehavior.py 2011-05-27 21:12:25 +0000
+++ lib/lp/translations/tests/test_translationtemplatesbuildbehavior.py 2011-10-19 12:27:49 +0000
@@ -3,8 +3,10 @@
33
4"""Unit tests for TranslationTemplatesBuildBehavior."""4"""Unit tests for TranslationTemplatesBuildBehavior."""
55
6import datetime
6import logging7import logging
7import os8import os
9import pytz
810
9from testtools.deferredruntest import AsynchronousDeferredRunTest11from testtools.deferredruntest import AsynchronousDeferredRunTest
10import transaction12import transaction
@@ -17,6 +19,7 @@
17from canonical.librarian.utils import copy_and_close19from canonical.librarian.utils import copy_and_close
18from canonical.testing.layers import LaunchpadZopelessLayer20from canonical.testing.layers import LaunchpadZopelessLayer
19from lp.app.interfaces.launchpad import ILaunchpadCelebrities21from lp.app.interfaces.launchpad import ILaunchpadCelebrities
22from lp.buildmaster.enums import BuildStatus
20from lp.buildmaster.interfaces.buildfarmjobbehavior import (23from lp.buildmaster.interfaces.buildfarmjobbehavior import (
21 IBuildFarmJobBehavior,24 IBuildFarmJobBehavior,
22 )25 )
@@ -57,6 +60,7 @@
57 """60 """
58 self.builder = behavior._builder61 self.builder = behavior._builder
59 self.specific_job = behavior.buildfarmjob62 self.specific_job = behavior.buildfarmjob
63 self.date_started = datetime.datetime.now(pytz.UTC)
60 self.destroySelf = FakeMethod()64 self.destroySelf = FakeMethod()
6165
6266
@@ -161,6 +165,7 @@
161 path = behavior.templates_tarball_path165 path = behavior.templates_tarball_path
162 # Poke the file we're expecting into the mock slave.166 # Poke the file we're expecting into the mock slave.
163 behavior._builder.slave.valid_file_hashes.append(path)167 behavior._builder.slave.valid_file_hashes.append(path)
168
164 def got_tarball(filename):169 def got_tarball(filename):
165 tarball = open(filename, 'r')170 tarball = open(filename, 'r')
166 try:171 try:
@@ -201,6 +206,9 @@
201 queue_item, slave_status, None, logging), slave_call_log206 queue_item, slave_status, None, logging), slave_call_log
202207
203 def build_updated(ignored):208 def build_updated(ignored):
209 self.assertEqual(BuildStatus.FULLYBUILT, behavior.build.status)
210 # Log file is stored.
211 self.assertIsNotNone(behavior.build.log)
204 slave_call_log = behavior._builder.slave.call_log212 slave_call_log = behavior._builder.slave.call_log
205 self.assertEqual(1, queue_item.destroySelf.call_count)213 self.assertEqual(1, queue_item.destroySelf.call_count)
206 self.assertIn('clean', slave_call_log)214 self.assertIn('clean', slave_call_log)
@@ -240,6 +248,9 @@
240 queue_item, status_dict, None, logging)248 queue_item, status_dict, None, logging)
241249
242 def build_updated(ignored):250 def build_updated(ignored):
251 self.assertEqual(BuildStatus.FAILEDTOBUILD, behavior.build.status)
252 # Log file is stored.
253 self.assertIsNotNone(behavior.build.log)
243 self.assertEqual(1, queue_item.destroySelf.call_count)254 self.assertEqual(1, queue_item.destroySelf.call_count)
244 slave_call_log = behavior._builder.slave.call_log255 slave_call_log = behavior._builder.slave.call_log
245 self.assertIn('clean', slave_call_log)256 self.assertIn('clean', slave_call_log)
@@ -278,6 +289,7 @@
278 queue_item, status_dict, None, logging)289 queue_item, status_dict, None, logging)
279290
280 def build_updated(ignored):291 def build_updated(ignored):
292 self.assertEqual(BuildStatus.FULLYBUILT, behavior.build.status)
281 self.assertEqual(1, queue_item.destroySelf.call_count)293 self.assertEqual(1, queue_item.destroySelf.call_count)
282 slave_call_log = behavior._builder.slave.call_log294 slave_call_log = behavior._builder.slave.call_log
283 self.assertIn('clean', slave_call_log)295 self.assertIn('clean', slave_call_log)
@@ -321,6 +333,7 @@
321 queue_item, slave_status, None, logging)333 queue_item, slave_status, None, logging)
322334
323 def build_updated(ignored):335 def build_updated(ignored):
336 self.assertEqual(BuildStatus.FULLYBUILT, behavior.build.status)
324 entries = getUtility(337 entries = getUtility(
325 ITranslationImportQueue).getAllEntries(target=productseries)338 ITranslationImportQueue).getAllEntries(target=productseries)
326 expected_templates = [339 expected_templates = [
327340
=== modified file 'utilities/make-lp-user'
--- utilities/make-lp-user 2011-07-11 03:49:12 +0000
+++ utilities/make-lp-user 2011-10-19 12:27:49 +0000
@@ -44,6 +44,7 @@
4444
45from canonical.launchpad.interfaces.gpghandler import IGPGHandler45from canonical.launchpad.interfaces.gpghandler import IGPGHandler
46from canonical.launchpad.scripts import execute_zcml_for_scripts46from canonical.launchpad.scripts import execute_zcml_for_scripts
47from canonical.lazr.timeout import set_default_timeout_function
47from lp.registry.interfaces.gpg import GPGKeyAlgorithm, IGPGKeySet48from lp.registry.interfaces.gpg import GPGKeyAlgorithm, IGPGKeySet
48from lp.registry.interfaces.person import IPersonSet49from lp.registry.interfaces.person import IPersonSet
49from lp.registry.interfaces.ssh import ISSHKeySet50from lp.registry.interfaces.ssh import ISSHKeySet
@@ -57,6 +58,7 @@
57DEFAULT_PASSWORD = 'test'58DEFAULT_PASSWORD = 'test'
58factory = LaunchpadObjectFactory()59factory = LaunchpadObjectFactory()
5960
61set_default_timeout_function(lambda: 100)
6062
61def make_person(username, email):63def make_person(username, email):
62 """Create and return a person with the given username.64 """Create and return a person with the given username.
@@ -119,7 +121,7 @@
119 print 'Registered SSH key: %s' % (filename,)121 print 'Registered SSH key: %s' % (filename,)
120 break122 break
121 else:123 else:
122 print 'No SSH key files found in %s' % ssh_dir 124 print 'No SSH key files found in %s' % ssh_dir
123125
124126
125def parse_fingerprints(gpg_output):127def parse_fingerprints(gpg_output):