Merge lp:~mbp/launchpad/mbp-trivial into lp:launchpad/db-devel
- mbp-trivial
- Merge into db-devel
Proposed by
Martin Pool
Status: | Superseded |
---|---|
Proposed branch: | lp:~mbp/launchpad/mbp-trivial |
Merge into: | lp:launchpad/db-devel |
Diff against target: |
728 lines (+243/-98) 17 files modified
Makefile (+46/-22) cronscripts/publishing/cron.publish-copy-archives (+4/-21) lib/canonical/buildd/binarypackage.py (+0/-2) lib/canonical/buildd/buildrecipe (+2/-0) lib/canonical/launchpad/doc/emailaddress.txt (+9/-7) lib/lp/app/javascript/tests/test_lp_collapsibles.html (+6/-6) lib/lp/app/javascript/tests/test_lp_collapsibles.js (+17/-9) lib/lp/app/windmill/testing.py (+21/-0) lib/lp/app/windmill/tests/test_yuitests.py (+24/-0) lib/lp/buildmaster/manager.py (+5/-3) lib/lp/buildmaster/model/builder.py (+39/-3) lib/lp/buildmaster/tests/test_builder.py (+54/-0) lib/lp/code/model/recipebuilder.py (+3/-1) lib/lp/code/model/tests/test_recipebuilder.py (+9/-3) lib/lp/registry/javascript/tests/test_milestone_table.html (+1/-1) lib/lp/services/mailman/doc/postings.txt (+0/-19) lib/lp/translations/windmill/tests/test_languages.py (+3/-1) |
To merge this branch: | bzr merge lp:~mbp/launchpad/mbp-trivial |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jeroen T. Vermeulen (community) | code | Needs Resubmitting | |
Launchpad code reviewers | Pending | ||
Review via email: mp+41268@code.launchpad.net |
This proposal has been superseded by a proposal from 2010-11-21.
Commit message
Description of the change
This tweaks Jeroen and Benji's recent work in "Faster builds" so that the makefile dependencies are more precise, to avoid unnecessary rebuilds.
To post a comment you must log in.
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote : | # |
review:
Needs Resubmitting
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Makefile' |
2 | --- Makefile 2010-11-02 01:34:05 +0000 |
3 | +++ Makefile 2010-11-19 08:04:58 +0000 |
4 | @@ -34,6 +34,9 @@ |
5 | # Do not add bin/buildout to this list. |
6 | # It is impossible to get buildout to tell us all the files it would |
7 | # build, since each egg's setup.py doesn't tell us that information. |
8 | +# |
9 | +# NB: It's important BUILDOUT_BIN only mentions things genuinely produced by |
10 | +# buildout. |
11 | BUILDOUT_BIN = \ |
12 | $(PY) bin/apiindex bin/combine-css bin/fl-build-report \ |
13 | bin/fl-credential-ctl bin/fl-install-demo bin/fl-monitor-ctl \ |
14 | @@ -45,6 +48,8 @@ |
15 | bin/start_librarian bin/stxdocs bin/tags bin/test bin/tracereport \ |
16 | bin/twistd bin/update-download-cache bin/windmill |
17 | |
18 | +BUILDOUT_TEMPLATES = buildout-templates/_pythonpath.py.in |
19 | + |
20 | # DO NOT ALTER : this should just build by default |
21 | default: inplace |
22 | |
23 | @@ -58,7 +63,7 @@ |
24 | hosted_branches: $(PY) |
25 | $(PY) ./utilities/make-dummy-hosted-branches |
26 | |
27 | -$(API_INDEX): $(BZR_VERSION_INFO) |
28 | +$(API_INDEX): $(BZR_VERSION_INFO) $(PY) |
29 | mkdir -p $(APIDOC_DIR).tmp |
30 | LPCONFIG=$(LPCONFIG) $(PY) ./utilities/create-lp-wadl-and-apidoc.py --force "$(WADL_TEMPLATE)" |
31 | mv $(APIDOC_DIR).tmp $(APIDOC_DIR) |
32 | @@ -66,7 +71,7 @@ |
33 | apidoc: compile $(API_INDEX) |
34 | |
35 | # Run by PQM. |
36 | -check_merge: $(PY) |
37 | +check_merge: $(BUILDOUT_BIN) |
38 | [ `PYTHONPATH= bzr status -S database/schema/ | \ |
39 | grep -v "\(^P\|pending\|security.cfg\|Makefile\|unautovacuumable\|_pythonpath.py\)" | wc -l` -eq 0 ] |
40 | ${PY} lib/canonical/tests/test_no_conflict_marker.py |
41 | @@ -139,13 +144,15 @@ |
42 | sprite_image: |
43 | ${SHHH} bin/sprite-util create-image |
44 | |
45 | +# We absolutely do not want to include the lazr.testing module and |
46 | +# its jsTestDriver test harness modifications in the lazr.js and |
47 | +# launchpad.js roll-up files. They fiddle with built-in functions! |
48 | +# See Bug 482340. |
49 | jsbuild_lazr: bin/jsbuild |
50 | - # We absolutely do not want to include the lazr.testing module and its |
51 | - # jsTestDriver test harness modifications in the lazr.js and launchpad.js |
52 | - # roll-up files. They fiddle with built-in functions! See Bug 482340. |
53 | - ${SHHH} bin/jsbuild $(JSFLAGS) -b $(LAZR_BUILT_JS_ROOT) -x testing/ -c $(LAZR_BUILT_JS_ROOT)/yui |
54 | + ${SHHH} bin/jsbuild $(JSFLAGS) -b $(LAZR_BUILT_JS_ROOT) -x testing/ \ |
55 | + -c $(LAZR_BUILT_JS_ROOT)/yui |
56 | |
57 | -jsbuild: jsbuild_lazr bin/jsbuild bin/jssize |
58 | +jsbuild: jsbuild_lazr bin/jsbuild bin/jssize $(BUILDOUT_BIN) |
59 | ${SHHH} bin/jsbuild \ |
60 | $(JSFLAGS) \ |
61 | -n launchpad \ |
62 | @@ -177,30 +184,45 @@ |
63 | find eggs -name '*.pyc' -exec rm {} \; |
64 | |
65 | # The download-cache dependency comes *before* eggs so that developers get the |
66 | -# warning before the eggs directory is made. The target for the eggs directory |
67 | -# is only there for deployment convenience. |
68 | +# warning before the eggs directory is made. The target for the eggs |
69 | +# directory is only there for deployment convenience. |
70 | # Note that the buildout version must be maintained here and in versions.cfg |
71 | # to make sure that the build does not go over the network. |
72 | +# |
73 | +# buildout won't touch files that would have the same contents, but for Make's |
74 | +# sake we need them to get fresh timestamps, so we touch them after building. |
75 | bin/buildout: download-cache eggs |
76 | $(SHHH) PYTHONPATH= $(PYTHON) bootstrap.py\ |
77 | --setup-source=ez_setup.py \ |
78 | --download-base=download-cache/dist --eggs=eggs \ |
79 | --version=1.5.1 |
80 | + touch --no-create $@ |
81 | |
82 | # This target is used by LOSAs to prepare a build to be pushed out to |
83 | # destination machines. We only want eggs: they are the expensive bits, |
84 | # and the other bits might run into problems like bug 575037. This |
85 | # target runs buildout, and then removes everything created except for |
86 | # the eggs. |
87 | -build_eggs: $(BUILDOUT_BIN) clean_buildout |
88 | +build_eggs: $(BUILDOUT_BIN) |
89 | |
90 | # This builds bin/py and all the other bin files except bin/buildout. |
91 | # Remove the target before calling buildout to ensure that buildout |
92 | # updates the timestamp. |
93 | -$(BUILDOUT_BIN): bin/buildout versions.cfg $(BUILDOUT_CFG) setup.py |
94 | - $(RM) $@ |
95 | +buildout_bin: $(BUILDOUT_BIN) |
96 | + |
97 | +# buildout won't touch files that would have the same contents, but for Make's |
98 | +# sake we need them to get fresh timestamps, so we touch them after building. |
99 | +# |
100 | +# If we listed every target on the left-hand side, a parallel make would try |
101 | +# multiple copies of this rule to build them all. Instead, we nominally build |
102 | +# just $(PY), and everything else is implicitly updated by that. |
103 | +$(PY): bin/buildout versions.cfg $(BUILDOUT_CFG) setup.py \ |
104 | + $(BUILDOUT_TEMPLATES) |
105 | $(SHHH) PYTHONPATH= ./bin/buildout \ |
106 | configuration:instance_name=${LPCONFIG} -c $(BUILDOUT_CFG) |
107 | + touch $@ |
108 | + |
109 | +$(subst $(PY),,$(BUILDOUT_BIN)): $(PY) |
110 | |
111 | # bin/compile_templates is responsible for building all chameleon templates, |
112 | # of which there is currently one, but of which many more are coming. |
113 | @@ -405,7 +427,8 @@ |
114 | # We insert the absolute path to the branch-rewrite script |
115 | # into the Apache config as we copy the file into position. |
116 | sed -e 's,%BRANCH_REWRITE%,$(shell pwd)/scripts/branch-rewrite.py,' configs/development/local-launchpad-apache > /etc/apache2/sites-available/local-launchpad |
117 | - cp configs/development/local-vostok-apache /etc/apache2/sites-available/local-vostok |
118 | + cp configs/development/local-vostok-apache \ |
119 | + /etc/apache2/sites-available/local-vostok |
120 | touch /var/tmp/bazaar.launchpad.dev/rewrite.log |
121 | chown $(SUDO_UID):$(SUDO_GID) /var/tmp/bazaar.launchpad.dev/rewrite.log |
122 | |
123 | @@ -430,8 +453,9 @@ |
124 | |
125 | lp.sfood: |
126 | # Generate import dependency graph |
127 | - sfood -i -u -I lib/sqlobject -I lib/schoolbell -I lib/devscripts -I lib/contrib \ |
128 | - -I lib/canonical/not-used lib/canonical lib/lp 2>/dev/null | grep -v contrib/ \ |
129 | + sfood -i -u -I lib/sqlobject -I lib/schoolbell -I lib/devscripts \ |
130 | + -I lib/contrib -I lib/canonical/not-used lib/canonical \ |
131 | + lib/lp 2>/dev/null | grep -v contrib/ \ |
132 | | grep -v sqlobject | grep -v BeautifulSoup | grep -v psycopg \ |
133 | | grep -v schoolbell > lp.sfood.tmp |
134 | mv lp.sfood.tmp lp.sfood |
135 | @@ -463,10 +487,10 @@ |
136 | --docformat restructuredtext --verbose-about epytext-summary \ |
137 | $(PYDOCTOR_OPTIONS) |
138 | |
139 | -.PHONY: apidoc check tags TAGS zcmldocs realclean clean debug stop\ |
140 | - start run ftest_build ftest_inplace test_build test_inplace pagetests\ |
141 | - check check_merge \ |
142 | - schema default launchpad.pot check_merge_ui pull scan sync_branches\ |
143 | - reload-apache hosted_branches check_db_merge check_mailman check_config\ |
144 | - jsbuild jsbuild_lazr clean_js clean_buildout buildonce_eggs build_eggs\ |
145 | - sprite_css sprite_image css_combine compile check_schema pydoctor |
146 | +.PHONY: apidoc buildout_bin check tags TAGS zcmldocs realclean clean debug \ |
147 | + stop start run ftest_build ftest_inplace test_build test_inplace \ |
148 | + pagetests check check_merge schema default launchpad.pot \ |
149 | + check_merge_ui pull scan sync_branches reload-apache hosted_branches \ |
150 | + check_db_merge check_mailman check_config jsbuild jsbuild_lazr \ |
151 | + clean_js clean_buildout buildonce_eggs build_eggs sprite_css \ |
152 | + sprite_image css_combine compile check_schema pydoctor |
153 | |
154 | === modified file 'cronscripts/publishing/cron.publish-copy-archives' |
155 | --- cronscripts/publishing/cron.publish-copy-archives 2010-06-25 14:36:11 +0000 |
156 | +++ cronscripts/publishing/cron.publish-copy-archives 2010-11-19 08:04:58 +0000 |
157 | @@ -10,7 +10,6 @@ |
158 | exit 1 |
159 | fi |
160 | |
161 | -set -x |
162 | set -e |
163 | set -u |
164 | |
165 | @@ -20,24 +19,23 @@ |
166 | |
167 | |
168 | # Informational -- this *MUST* match the database. |
169 | -ARCHIVEROOT=/srv/launchpad.net/ubuntu-archive/ubuntu |
170 | +ARCHIVEROOT=/srv/launchpad.net/rebuild-test/ubuntu |
171 | DISTSROOT=$ARCHIVEROOT/dists |
172 | OVERRIDEROOT=$ARCHIVEROOT/../ubuntu-overrides |
173 | INDICES=$ARCHIVEROOT/indices |
174 | PRODUCTION_CONFIG=ftpmaster-publish |
175 | |
176 | if [ "$LPCONFIG" = "$PRODUCTION_CONFIG" ]; then |
177 | - GNUPGHOME=/srv/launchpad.net/ubuntu-archive/gnupg-home |
178 | + GNUPGHOME=/srv/launchpad.net/rebuild-test/gnupg-home |
179 | else |
180 | echo GPG keys will come from ~/.gnupg |
181 | # GNUPGHOME does not need to be set, keys can come from ~/.gnupg. |
182 | fi |
183 | |
184 | # Configuration options. |
185 | -LAUNCHPADROOT=/srv/launchpad.net/codelines/current |
186 | -LOCKFILE=/srv/launchpad.net/ubuntu-archive/cron.daily.lock |
187 | +LAUNCHPADROOT=/srv/launchpad.net/production/launchpad |
188 | +LOCKFILE=/srv/launchpad.net/rebuild-test/cron.daily.lock |
189 | DISTRONAME=ubuntu |
190 | -TRACEFILE=$ARCHIVEROOT/project/trace/$(hostname --fqdn) |
191 | |
192 | # Manipulate the environment. |
193 | export GNUPGHOME |
194 | @@ -64,20 +62,5 @@ |
195 | # Publish the packages to disk. |
196 | publish-distro.py -v -v --copy-archive -d $DISTRONAME |
197 | |
198 | -set +x |
199 | - |
200 | echo Removing uncompressed Packages and Sources files |
201 | find ${DISTSROOT} \( -name "Packages" -o -name "Sources" \) -exec rm "{}" \; |
202 | - |
203 | -# Copy in the indices. |
204 | -if [ "$LPCONFIG" = "$PRODUCTION_CONFIG" ]; then |
205 | - echo Copying the indices into place. |
206 | - rm -f $INDICES/override.* |
207 | - cp $OVERRIDEROOT/override.* $INDICES |
208 | -fi |
209 | - |
210 | -# Timestamp our trace file to track when the last archive publisher run took |
211 | -# place. |
212 | -if [ "$LPCONFIG" = "$PRODUCTION_CONFIG" ]; then |
213 | - date -u > "$TRACEFILE" |
214 | -fi |
215 | |
216 | === modified file 'lib/canonical/buildd/binarypackage.py' |
217 | --- lib/canonical/buildd/binarypackage.py 2010-07-13 09:13:41 +0000 |
218 | +++ lib/canonical/buildd/binarypackage.py 2010-11-19 08:04:58 +0000 |
219 | @@ -19,9 +19,7 @@ |
220 | class BuildLogRegexes: |
221 | """Build log regexes for performing actions based on regexes, and extracting dependencies for auto dep-waits""" |
222 | GIVENBACK = [ |
223 | - (" terminated by signal 4"), |
224 | ("^E: There are problems and -y was used without --force-yes"), |
225 | - ("^make.* Illegal instruction"), |
226 | ] |
227 | DEPFAIL = [ |
228 | ("(?P<pk>[\-+.\w]+)\(inst [^ ]+ ! >> wanted (?P<v>[\-.+\w:~]+)\)","\g<pk> (>> \g<v>)"), |
229 | |
230 | === modified file 'lib/canonical/buildd/buildrecipe' |
231 | --- lib/canonical/buildd/buildrecipe 2010-09-30 20:22:15 +0000 |
232 | +++ lib/canonical/buildd/buildrecipe 2010-11-19 08:04:58 +0000 |
233 | @@ -11,6 +11,7 @@ |
234 | import os |
235 | import pwd |
236 | import re |
237 | +from resource import RLIMIT_AS, setrlimit |
238 | import socket |
239 | from subprocess import call, Popen, PIPE |
240 | import sys |
241 | @@ -206,6 +207,7 @@ |
242 | |
243 | |
244 | if __name__ == '__main__': |
245 | + setrlimit(RLIMIT_AS, (1000000000, -1)) |
246 | builder = RecipeBuilder(*sys.argv[1:]) |
247 | if builder.buildTree() != 0: |
248 | sys.exit(RETCODE_FAILURE_BUILD_TREE) |
249 | |
250 | === renamed file 'lib/canonical/launchpad/doc/emailaddress.txt.disabled' => 'lib/canonical/launchpad/doc/emailaddress.txt' |
251 | --- lib/canonical/launchpad/doc/emailaddress.txt.disabled 2009-08-13 19:03:36 +0000 |
252 | +++ lib/canonical/launchpad/doc/emailaddress.txt 2010-11-19 08:04:58 +0000 |
253 | @@ -1,4 +1,5 @@ |
254 | -= Email Addresses = |
255 | +Email Addresses |
256 | +=============== |
257 | |
258 | In Launchpad we use email addresses to uniquely identify a person. This is why |
259 | email addresses must be unique. |
260 | @@ -22,7 +23,7 @@ |
261 | |
262 | Email addresses provide both IEmailAddress and IHasOwner. |
263 | |
264 | - >>> from canonical.launchpad.interfaces.launchpad import IHasOwner |
265 | + >>> from lp.registry.interfaces.role import IHasOwner |
266 | >>> verifyObject(IEmailAddress, email) |
267 | True |
268 | >>> verifyObject(IHasOwner, email) |
269 | @@ -66,11 +67,12 @@ |
270 | [u'celso.providelo@canonical.com', u'colin.watson@ubuntulinux.com', |
271 | u'daniel.silverstone@canonical.com', u'edgar@monteparadiso.hr', |
272 | u'foo.bar@canonical.com', u'jeff.waugh@ubuntulinux.com', |
273 | - u'limi@plone.org', u'mark@example.com', u'steve.alexander@ubuntulinux.com', |
274 | - u'support@ubuntu.com'] |
275 | - |
276 | - |
277 | -== Deleting email addresses == |
278 | + u'limi@plone.org', u'mark@example.com', |
279 | + u'steve.alexander@ubuntulinux.com', u'support@ubuntu.com'] |
280 | + |
281 | + |
282 | +Deleting email addresses |
283 | +------------------------ |
284 | |
285 | Email addresses may be deleted if they're not a person's preferred one |
286 | or the address of a team's mailing list. |
287 | |
288 | === modified file 'lib/lp/app/javascript/tests/test_lp_collapsibles.html' |
289 | --- lib/lp/app/javascript/tests/test_lp_collapsibles.html 2010-07-26 13:42:32 +0000 |
290 | +++ lib/lp/app/javascript/tests/test_lp_collapsibles.html 2010-11-19 08:04:58 +0000 |
291 | @@ -4,14 +4,14 @@ |
292 | <title>Launchpad Collapsibles</title> |
293 | |
294 | <!-- YUI 3.0 Setup --> |
295 | - <script type="text/javascript" src="../../../icing/yui/yui/yui.js"></script> |
296 | - <link rel="stylesheet" href="../../../icing/yui/cssreset/reset.css"/> |
297 | - <link rel="stylesheet" href="../../../icing/yui/cssfonts/fonts.css"/> |
298 | - <link rel="stylesheet" href="../../../icing/yui/cssbase/base.css"/> |
299 | - <link rel="stylesheet" href="../../test.css" /> |
300 | + <script type="text/javascript" src="../../../../canonical/launchpad/icing/yui/yui/yui.js"></script> |
301 | + <script type="text/javascript" src="../../../../canonical/launchpad/icing/lazr/build/lazr.js"></script> |
302 | + <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssreset/reset.css"/> |
303 | + <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssfonts/fonts.css"/> |
304 | + <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssbase/base.css"/> |
305 | + <link rel="stylesheet" href="../../../../canonical/launchpad/javascript/test.css" /> |
306 | |
307 | <!-- The module under test --> |
308 | - <script type="text/javascript" src="../../../icing/lazr/build/effects/effects.js"></script> |
309 | <script type="text/javascript" src="../lp.js"></script> |
310 | |
311 | <!-- The test suite --> |
312 | |
313 | === modified file 'lib/lp/app/javascript/tests/test_lp_collapsibles.js' |
314 | --- lib/lp/app/javascript/tests/test_lp_collapsibles.js 2010-07-26 13:42:32 +0000 |
315 | +++ lib/lp/app/javascript/tests/test_lp_collapsibles.js 2010-11-19 08:04:58 +0000 |
316 | @@ -1,21 +1,21 @@ |
317 | /* Copyright (c) 2009, Canonical Ltd. All rights reserved. */ |
318 | |
319 | YUI({ |
320 | - base: '../../../icing/yui/', |
321 | + base: '../../../../canonical/launchpad/icing/yui/', |
322 | filter: 'raw', |
323 | combine: false |
324 | }).use('test', 'console', 'lp', function(Y) { |
325 | |
326 | var Assert = Y.Assert; // For easy access to isTrue(), etc. |
327 | |
328 | -Y.Test.Runner.add(new Y.Test.Case({ |
329 | +var suite = new Y.Test.Suite("Collapsibles Tests"); |
330 | +suite.add(new Y.Test.Case({ |
331 | name: "activate_collapsibles", |
332 | |
333 | _should: { |
334 | - error: { |
335 | + fail: { |
336 | test_toggle_collapsible_fails_on_wrapperless_collapsible: true, |
337 | test_toggle_collapsible_fails_on_iconless_collapsible: true, |
338 | - test_activate_collapsibles_handles_no_collapsibles: false |
339 | } |
340 | }, |
341 | |
342 | @@ -149,17 +149,16 @@ |
343 | test_toggle_collapsible_opens_collapsed_collapsible: function() { |
344 | // Calling toggle_collapsible() on a collapsed collapsible will |
345 | // toggle its state to open. |
346 | + Y.lp.activate_collapsibles(); |
347 | var collapsible = this.container.one('.collapsible'); |
348 | - collapsible.addClass('collapsed'); |
349 | + var wrapper_div = collapsible.one('.collapseWrapper'); |
350 | + wrapper_div.addClass('lazr-closed'); |
351 | |
352 | - Y.lp.activate_collapsibles(); |
353 | Y.lp.toggle_collapsible(collapsible); |
354 | this.wait(function() { |
355 | - |
356 | // The collapsible's wrapper div will now be open. |
357 | var icon = collapsible.one('img'); |
358 | - var wrapper_div = collapsible.one('.collapseWrapper'); |
359 | - Assert.isTrue(wrapper_div.hasClass('lazr-open')); |
360 | + Assert.isFalse(wrapper_div.hasClass('lazr-closed')); |
361 | Assert.areNotEqual( |
362 | -1, icon.get('src').indexOf('/@@/treeExpanded')); |
363 | }, 500); |
364 | @@ -321,6 +320,15 @@ |
365 | } |
366 | })); |
367 | |
368 | +// Lock, stock, and two smoking barrels. |
369 | +var handle_complete = function(data) { |
370 | + status_node = Y.Node.create( |
371 | + '<p id="complete">Test status: complete</p>'); |
372 | + Y.get('body').appendChild(status_node); |
373 | + }; |
374 | +Y.Test.Runner.on('complete', handle_complete); |
375 | +Y.Test.Runner.add(suite); |
376 | + |
377 | var yui_console = new Y.Console({ |
378 | newestOnTop: false |
379 | }); |
380 | |
381 | === added directory 'lib/lp/app/windmill' |
382 | === added file 'lib/lp/app/windmill/__init__.py' |
383 | === added file 'lib/lp/app/windmill/testing.py' |
384 | --- lib/lp/app/windmill/testing.py 1970-01-01 00:00:00 +0000 |
385 | +++ lib/lp/app/windmill/testing.py 2010-11-19 08:04:58 +0000 |
386 | @@ -0,0 +1,21 @@ |
387 | +# Copyright 2009-2010 Canonical Ltd. This software is licensed under the |
388 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
389 | + |
390 | +"""Launchpad app specific testing infrastructure for Windmill.""" |
391 | + |
392 | +__metaclass__ = type |
393 | +__all__ = [ |
394 | + 'AppWindmillLayer', |
395 | + ] |
396 | + |
397 | + |
398 | +from canonical.testing.layers import BaseWindmillLayer |
399 | + |
400 | + |
401 | +class AppWindmillLayer(BaseWindmillLayer): |
402 | + """Layer for App Windmill tests.""" |
403 | + |
404 | + @classmethod |
405 | + def setUp(cls): |
406 | + cls.base_url = cls.appserver_root_url() |
407 | + super(AppWindmillLayer, cls).setUp() |
408 | |
409 | === added directory 'lib/lp/app/windmill/tests' |
410 | === added file 'lib/lp/app/windmill/tests/__init__.py' |
411 | === added file 'lib/lp/app/windmill/tests/test_yuitests.py' |
412 | --- lib/lp/app/windmill/tests/test_yuitests.py 1970-01-01 00:00:00 +0000 |
413 | +++ lib/lp/app/windmill/tests/test_yuitests.py 2010-11-19 08:04:58 +0000 |
414 | @@ -0,0 +1,24 @@ |
415 | +# Copyright 2010 Canonical Ltd. This software is licensed under the |
416 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
417 | + |
418 | +"""Run YUI.test tests.""" |
419 | + |
420 | +__metaclass__ = type |
421 | +__all__ = [] |
422 | + |
423 | +from lp.app.windmill.testing import AppWindmillLayer |
424 | +from lp.testing import ( |
425 | + build_yui_unittest_suite, |
426 | + YUIUnitTestCase, |
427 | + ) |
428 | + |
429 | + |
430 | +class AppYUIUnitTestCase(YUIUnitTestCase): |
431 | + |
432 | + layer = AppWindmillLayer |
433 | + suite_name = 'AppYUIUnitTests' |
434 | + |
435 | + |
436 | +def test_suite(): |
437 | + app_testing_path = 'lp/app/javascript/tests' |
438 | + return build_yui_unittest_suite(app_testing_path, AppYUIUnitTestCase) |
439 | |
440 | === modified file 'lib/lp/buildmaster/manager.py' |
441 | --- lib/lp/buildmaster/manager.py 2010-10-28 15:04:15 +0000 |
442 | +++ lib/lp/buildmaster/manager.py 2010-11-19 08:04:58 +0000 |
443 | @@ -151,10 +151,12 @@ |
444 | if failure.check( |
445 | BuildSlaveFailure, CannotBuild, BuildBehaviorMismatch, |
446 | CannotResumeHost, BuildDaemonError, CannotFetchFile): |
447 | - self.logger.info("Scanning failed with: %s" % error_message) |
448 | + self.logger.info("Scanning %s failed with: %s" % ( |
449 | + self.builder_name, error_message)) |
450 | else: |
451 | - self.logger.info("Scanning failed with: %s\n%s" % |
452 | - (failure.getErrorMessage(), failure.getTraceback())) |
453 | + self.logger.info("Scanning %s failed with: %s\n%s" % ( |
454 | + self.builder_name, failure.getErrorMessage(), |
455 | + failure.getTraceback())) |
456 | |
457 | # Decide if we need to terminate the job or fail the |
458 | # builder. |
459 | |
460 | === modified file 'lib/lp/buildmaster/model/builder.py' |
461 | --- lib/lp/buildmaster/model/builder.py 2010-11-10 13:06:05 +0000 |
462 | +++ lib/lp/buildmaster/model/builder.py 2010-11-19 08:04:58 +0000 |
463 | @@ -8,6 +8,7 @@ |
464 | __all__ = [ |
465 | 'Builder', |
466 | 'BuilderSet', |
467 | + 'ProxyWithConnectionTimeout', |
468 | 'rescueBuilderIfLost', |
469 | 'updateBuilderStatus', |
470 | ] |
471 | @@ -99,6 +100,41 @@ |
472 | noisy = False |
473 | |
474 | |
475 | +class ProxyWithConnectionTimeout(xmlrpc.Proxy): |
476 | + """Extend Twisted's Proxy to provide a configurable connection timeout.""" |
477 | + |
478 | + def __init__(self, url, user=None, password=None, allowNone=False, |
479 | + useDateTime=False, timeout=None): |
480 | + xmlrpc.Proxy.__init__( |
481 | + self, url, user, password, allowNone, useDateTime) |
482 | + if timeout is None: |
483 | + self.timeout = config.builddmaster.socket_timeout |
484 | + else: |
485 | + self.timeout = timeout |
486 | + |
487 | + def callRemote(self, method, *args): |
488 | + """Basically a carbon copy of the parent but passes the timeout |
489 | + to connectTCP.""" |
490 | + |
491 | + def cancel(d): |
492 | + factory.deferred = None |
493 | + connector.disconnect() |
494 | + factory = self.queryFactory( |
495 | + self.path, self.host, method, self.user, |
496 | + self.password, self.allowNone, args, cancel, self.useDateTime) |
497 | + if self.secure: |
498 | + from twisted.internet import ssl |
499 | + connector = default_reactor.connectSSL( |
500 | + self.host, self.port or 443, factory, |
501 | + ssl.ClientContextFactory(), |
502 | + timeout=self.timeout) |
503 | + else: |
504 | + connector = default_reactor.connectTCP( |
505 | + self.host, self.port or 80, factory, |
506 | + timeout=self.timeout) |
507 | + return factory.deferred |
508 | + |
509 | + |
510 | class BuilderSlave(object): |
511 | """Add in a few useful methods for the XMLRPC slave. |
512 | |
513 | @@ -141,7 +177,7 @@ |
514 | """ |
515 | rpc_url = urlappend(builder_url.encode('utf-8'), 'rpc') |
516 | if proxy is None: |
517 | - server_proxy = xmlrpc.Proxy(rpc_url, allowNone=True) |
518 | + server_proxy = ProxyWithConnectionTimeout(rpc_url, allowNone=True) |
519 | server_proxy.queryFactory = QuietQueryFactory |
520 | else: |
521 | server_proxy = proxy |
522 | @@ -213,7 +249,7 @@ |
523 | :param libraryfilealias: An `ILibraryFileAlias`. |
524 | """ |
525 | url = libraryfilealias.http_url |
526 | - logger.debug( |
527 | + logger.info( |
528 | "Asking builder on %s to ensure it has file %s (%s, %s)" % ( |
529 | self._file_cache_url, libraryfilealias.filename, url, |
530 | libraryfilealias.content.sha1)) |
531 | @@ -432,7 +468,7 @@ |
532 | return defer.fail(CannotResumeHost('Undefined vm_host.')) |
533 | |
534 | logger = self._getSlaveScannerLogger() |
535 | - logger.debug("Resuming %s (%s)" % (self.name, self.url)) |
536 | + logger.info("Resuming %s (%s)" % (self.name, self.url)) |
537 | |
538 | d = self.slave.resume() |
539 | def got_resume_ok((stdout, stderr, returncode)): |
540 | |
541 | === modified file 'lib/lp/buildmaster/tests/test_builder.py' |
542 | --- lib/lp/buildmaster/tests/test_builder.py 2010-11-10 22:40:05 +0000 |
543 | +++ lib/lp/buildmaster/tests/test_builder.py 2010-11-19 08:04:58 +0000 |
544 | @@ -43,6 +43,10 @@ |
545 | ) |
546 | from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet |
547 | from lp.buildmaster.interfaces.builder import CannotResumeHost |
548 | +from lp.buildmaster.model.builder import ( |
549 | + BuilderSlave, |
550 | + ProxyWithConnectionTimeout, |
551 | + ) |
552 | from lp.buildmaster.model.buildfarmjobbehavior import IdleBuildBehavior |
553 | from lp.buildmaster.model.buildqueue import BuildQueue |
554 | from lp.buildmaster.tests.mock_slaves import ( |
555 | @@ -1059,6 +1063,56 @@ |
556 | self.slave.build(None, None, None, None, None)) |
557 | |
558 | |
559 | +class TestSlaveConnectionTimeouts(TrialTestCase): |
560 | + # Testing that we can override the default 30 second connection |
561 | + # timeout. |
562 | + |
563 | + layer = TwistedLayer |
564 | + |
565 | + def setUp(self): |
566 | + super(TestSlaveConnectionTimeouts, self).setUp() |
567 | + self.slave_helper = SlaveTestHelpers() |
568 | + self.slave_helper.setUp() |
569 | + self.addCleanup(self.slave_helper.cleanUp) |
570 | + self.clock = Clock() |
571 | + self.proxy = ProxyWithConnectionTimeout("fake_url") |
572 | + self.slave = self.slave_helper.getClientSlave( |
573 | + reactor=self.clock, proxy=self.proxy) |
574 | + |
575 | + def test_connection_timeout(self): |
576 | + # The default timeout of 30 seconds should not cause a timeout, |
577 | + # only the config value should. |
578 | + timeout_config = """ |
579 | + [builddmaster] |
580 | + socket_timeout: 180 |
581 | + """ |
582 | + config.push('timeout', timeout_config) |
583 | + self.addCleanup(config.pop, 'timeout') |
584 | + |
585 | + d = self.slave.echo() |
586 | + # Advance past the 30 second timeout. The real reactor will |
587 | + # never call connectTCP() since we're not spinning it up. This |
588 | + # avoids "connection refused" errors and simulates an |
589 | + # environment where the endpoint doesn't respond. |
590 | + self.clock.advance(31) |
591 | + self.assertFalse(d.called) |
592 | + |
593 | + # Now advance past the real socket timeout and expect a |
594 | + # Failure. |
595 | + |
596 | + def got_timeout(failure): |
597 | + self.assertIsInstance(failure.value, CancelledError) |
598 | + |
599 | + d.addBoth(got_timeout) |
600 | + self.clock.advance(config.builddmaster.socket_timeout + 1) |
601 | + self.assertTrue(d.called) |
602 | + |
603 | + def test_BuilderSlave_uses_ProxyWithConnectionTimeout(self): |
604 | + # Make sure that BuilderSlaves use the custom proxy class. |
605 | + slave = BuilderSlave.makeBuilderSlave("url", "host") |
606 | + self.assertIsInstance(slave._server, ProxyWithConnectionTimeout) |
607 | + |
608 | + |
609 | class TestSlaveWithLibrarian(TrialTestCase): |
610 | """Tests that need more of Launchpad to run.""" |
611 | |
612 | |
613 | === modified file 'lib/lp/code/model/recipebuilder.py' |
614 | --- lib/lp/code/model/recipebuilder.py 2010-10-27 14:25:19 +0000 |
615 | +++ lib/lp/code/model/recipebuilder.py 2010-11-19 08:04:58 +0000 |
616 | @@ -122,6 +122,8 @@ |
617 | if chroot is None: |
618 | raise CannotBuild("Unable to find a chroot for %s" % |
619 | distroarchseries.displayname) |
620 | + logger.info( |
621 | + "Sending chroot file for recipe build to %s" % self._builder.name) |
622 | d = self._builder.slave.cacheFile(logger, chroot) |
623 | |
624 | def got_cache_file(ignored): |
625 | @@ -131,7 +133,7 @@ |
626 | buildid = "%s-%s" % (self.build.id, build_queue_id) |
627 | cookie = self.buildfarmjob.generateSlaveBuildCookie() |
628 | chroot_sha1 = chroot.content.sha1 |
629 | - logger.debug( |
630 | + logger.info( |
631 | "Initiating build %s on %s" % (buildid, self._builder.url)) |
632 | |
633 | return self._builder.slave.build( |
634 | |
635 | === modified file 'lib/lp/code/model/tests/test_recipebuilder.py' |
636 | --- lib/lp/code/model/tests/test_recipebuilder.py 2010-10-26 15:47:24 +0000 |
637 | +++ lib/lp/code/model/tests/test_recipebuilder.py 2010-11-19 08:04:58 +0000 |
638 | @@ -282,8 +282,13 @@ |
639 | d = defer.maybeDeferred(job.dispatchBuildToSlave, "someid", logger) |
640 | def check_dispatch(ignored): |
641 | logger.buffer.seek(0) |
642 | - self.assertEquals( |
643 | - "DEBUG: Initiating build 1-someid on http://fake:0000\n", |
644 | + |
645 | + self.assertEquals( |
646 | + "INFO: Sending chroot file for recipe build to " |
647 | + "bob-de-bouwer\n", |
648 | + logger.buffer.readline()) |
649 | + self.assertEquals( |
650 | + "INFO: Initiating build 1-someid on http://fake:0000\n", |
651 | logger.buffer.readline()) |
652 | self.assertEquals(["ensurepresent", "build"], |
653 | [call[0] for call in slave.call_log]) |
654 | @@ -293,7 +298,8 @@ |
655 | self.assertEquals(build_args[1], "sourcepackagerecipe") |
656 | self.assertEquals(build_args[3], []) |
657 | distroarchseries = job.build.distroseries.architectures[0] |
658 | - self.assertEqual(build_args[4], job._extraBuildArgs(distroarchseries)) |
659 | + self.assertEqual( |
660 | + build_args[4], job._extraBuildArgs(distroarchseries)) |
661 | return d.addCallback(check_dispatch) |
662 | |
663 | def test_dispatchBuildToSlave_nochroot(self): |
664 | |
665 | === modified file 'lib/lp/registry/javascript/tests/test_milestone_table.html' |
666 | --- lib/lp/registry/javascript/tests/test_milestone_table.html 2010-04-28 18:43:25 +0000 |
667 | +++ lib/lp/registry/javascript/tests/test_milestone_table.html 2010-11-19 08:04:58 +0000 |
668 | @@ -9,7 +9,7 @@ |
669 | <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssreset/reset.css"/> |
670 | <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssfonts/fonts.css"/> |
671 | <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssbase/base.css"/> |
672 | - <link rel="stylesheet" href="../../../canonical/launchpad/javascript/test.css" /> |
673 | + <link rel="stylesheet" href="../../../../canonical/launchpad/javascript/test.css" /> |
674 | |
675 | <!-- The module under test --> |
676 | <script type="text/javascript" src="../milestonetable.js"></script> |
677 | |
678 | === modified file 'lib/lp/services/mailman/doc/postings.txt' |
679 | --- lib/lp/services/mailman/doc/postings.txt 2010-10-25 12:11:43 +0000 |
680 | +++ lib/lp/services/mailman/doc/postings.txt 2010-11-19 08:04:58 +0000 |
681 | @@ -177,25 +177,6 @@ |
682 | From: itest-one-...@lists.launchpad.dev |
683 | To: anne.person@example.com |
684 | ... |
685 | - Sender: itest-one-bounces+anne.person=example.com@lists.launchpad.dev |
686 | - Errors-To: itest-one-bounces+anne.person=example.com@lists.launchpad.dev |
687 | - ... |
688 | - X-MailFrom: itest-one-bounces+anne.person=example.com@lists.launchpad.dev |
689 | - X-RcptTo: anne.person@example.com |
690 | - <BLANKLINE> |
691 | - Your request to the Itest-one mailing list |
692 | - <BLANKLINE> |
693 | - Posting of your message titled "An unsubscribed post" |
694 | - <BLANKLINE> |
695 | - has been rejected by the list moderator. The moderator gave the |
696 | - following reason for rejecting your request: |
697 | - <BLANKLINE> |
698 | - "[No reason given]" |
699 | - <BLANKLINE> |
700 | - Any questions or comments should be directed to the list administrator |
701 | - at: |
702 | - <BLANKLINE> |
703 | - itest-one-owner@lists.launchpad.dev |
704 | |
705 | Anne posts another message to the mailing list, but she is still not |
706 | subscribed to it. The team administrator deems this message to be spam and |
707 | |
708 | === modified file 'lib/lp/translations/windmill/tests/test_languages.py' |
709 | --- lib/lp/translations/windmill/tests/test_languages.py 2010-10-18 12:56:47 +0000 |
710 | +++ lib/lp/translations/windmill/tests/test_languages.py 2010-11-19 08:04:58 +0000 |
711 | @@ -7,6 +7,7 @@ |
712 | __all__ = [] |
713 | |
714 | from canonical.launchpad.windmill.testing.constants import ( |
715 | + FOR_ELEMENT, |
716 | PAGE_LOAD, |
717 | SLEEP, |
718 | ) |
719 | @@ -61,7 +62,8 @@ |
720 | # "Not-matching" message is hidden and languages are visible. |
721 | self.client.asserts.assertProperty( |
722 | id=u'no_filter_matches', |
723 | - validator='className|unseen') |
724 | + validator='className|unseen', |
725 | + timeout=FOR_ELEMENT) |
726 | self._assert_languages_visible({ |
727 | u'German': True, |
728 | u'Mende': True, |
The Makefile changes look good—and thanks again for making them!—but I think you accidentally submitted this for db-devel (after branching off devel) so the diff contains a lot of unrelated material.