Merge lp:~mbp/launchpad/mbp-trivial into lp:launchpad/db-devel
- mbp-trivial
- Merge into db-devel
Proposed by
Martin Pool
on 2010-11-19
| 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 | 2010-11-19 | Resubmit on 2010-11-19 |
| Launchpad code reviewers | 2010-11-19 | Pending | |
|
Review via email:
|
|||
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.
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.