Merge lp:~stevenk/launchpad/bpb-currentcomponent-assertion-part-3 into lp:launchpad

Proposed by Steve Kowalik
Status: Merged
Approved by: Graham Binns
Approved revision: no longer in the source branch.
Merged at revision: 12253
Proposed branch: lp:~stevenk/launchpad/bpb-currentcomponent-assertion-part-3
Merge into: lp:launchpad
Prerequisite: lp:~stevenk/launchpad/bpb-currentcomponent-assertion-part-2
Diff against target: 736 lines (+187/-455)
3 files modified
lib/lp/soyuz/doc/binarypackagebuild.txt (+0/-443)
lib/lp/soyuz/tests/test_binarypackagebuild.py (+3/-3)
lib/lp/soyuz/tests/test_hasbuildrecords.py (+184/-9)
To merge this branch: bzr merge lp:~stevenk/launchpad/bpb-currentcomponent-assertion-part-3
Reviewer Review Type Date Requested Status
Graham Binns (community) code Approve
Review via email: mp+46209@code.launchpad.net

Description of the change

This branch moves more of binarypackagebuild.txt into unit tests.

To post a comment you must log in.
Revision history for this message
Graham Binns (gmb) wrote :

StevenK: r=me; There are a few instances of "# Test that ..." that need to be turned into a statement of expected behaviour, but I know you'll take care of those.

review: Approve (code)
Revision history for this message
Graham Binns (gmb) wrote :

Oops. Missed part of the diff.

review: Abstain (code)
Revision history for this message
Graham Binns (gmb) wrote :

This method is crying out for some comments explaining what it's actually doing and why. I mean, I get that it's setting things up for later tests, but it took me a couple of goes to understand what each bit does. If you can add comments to explain it a bit better, that'd be great.

538 + def setUp(self):
539 + super(TestDistributionHasBuildRecords, self).setUp()
540 + self.admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)
541 + self.pf_one = self.factory.makeProcessorFamily()
542 + pf_proc_1 = self.pf_one.addProcessor(
543 + self.factory.getUniqueString(), '', '')
544 + self.pf_two = self.factory.makeProcessorFamily()
545 + pf_proc_2 = self.pf_two.addProcessor(
546 + self.factory.getUniqueString(), '', '')
547 + self.distroseries = self.factory.makeDistroSeries()
548 + self.distribution = self.distroseries.distribution
549 + self.das_one = self.factory.makeDistroArchSeries(
550 + distroseries=self.distroseries, processorfamily=self.pf_one,
551 + supports_virtualized=True)
552 + self.das_two = self.factory.makeDistroArchSeries(
553 + distroseries=self.distroseries, processorfamily=self.pf_two,
554 + supports_virtualized=True)
555 + self.archive = self.factory.makeArchive(
556 + distribution=self.distroseries.distribution,
557 + purpose=ArchivePurpose.PRIMARY)
558 + self.arch_ids = [arch.id for arch in self.distroseries.architectures]
559 + with person_logged_in(self.admin):
560 + self.publisher = SoyuzTestPublisher()
561 + self.publisher.prepareBreezyAutotest()
562 + self.distroseries.nominatedarchindep = self.das_one
563 + self.publisher.addFakeChroots(distroseries=self.distroseries)
564 + self.builder_one = self.factory.makeBuilder(processor=pf_proc_1)
565 + self.builder_two = self.factory.makeBuilder(processor=pf_proc_2)
566 + self.builds = []
567 + self.createBuilds()

Also, bigjool's concerns on IRC need to be dealt with.

review: Needs Fixing (code)
Revision history for this message
Graham Binns (gmb) wrote :

Happy joy happy happy joy.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/soyuz/doc/binarypackagebuild.txt'
2--- lib/lp/soyuz/doc/binarypackagebuild.txt 2011-01-20 21:02:32 +0000
3+++ lib/lp/soyuz/doc/binarypackagebuild.txt 2011-01-20 21:02:59 +0000
4@@ -1,446 +1,3 @@
5-== The BuildSet Class ==
6-
7-The BuildSet class gives us some useful ways to consider the
8-collection of builds.
9-
10- >>> bs = getUtility(IBinaryPackageBuildSet)
11-
12-We can find builds given a source package release and architecture tag.
13-
14- >>> i386_builds = bs.getBuildBySRAndArchtag(20, 'i386')
15- >>> i386_builds.count()
16- 4
17-
18-IHasBuildRecords uses a base method provided by IBinaryPackageBuildSet,
19-getBuildsByArchIds():
20-
21-It receives list of architectures IDs:
22-
23- >>> hoary = ubuntu.getSeries('hoary')
24- >>> arch_ids = [arch.id for arch in hoary.architectures]
25- >>> bs.getBuildsByArchIds(ubuntu, arch_ids).count()
26- 5
27-
28-It still working for empty list or None:
29-
30- >>> bs.getBuildsByArchIds(ubuntu, []).count()
31- 0
32-
33- >>> bs.getBuildsByArchIds(ubuntu, None).count()
34- 0
35-
36-Using build status, only the successfully built ones:
37-
38- >>> bs.getBuildsByArchIds(ubuntu, arch_ids,
39- ... status=BuildStatus.FULLYBUILT).count()
40- 2
41-
42-Check the result content:
43-
44- >>> [b.title for b in bs.getBuildsByArchIds(ubuntu, arch_ids,
45- ... status=BuildStatus.FULLYBUILT)]
46- [u'i386 build of pmount 0.1-1 in ubuntu hoary RELEASE', u'hppa build
47- of pmount 0.1-1 in ubuntu hoary RELEASE']
48-
49-Using optional 'name' filter (matching with SQL LIKE %||filter||%)
50-
51- >>> bs.getBuildsByArchIds(ubuntu, arch_ids,
52- ... status=BuildStatus.FULLYBUILT,
53- ... name='pmo').count()
54- 2
55-
56-Checking optional 'pocket' restriction:
57-
58- >>> from lp.registry.interfaces.pocket import PackagePublishingPocket
59- >>> bs.getBuildsByArchIds(ubuntu, arch_ids,
60- ... pocket=PackagePublishingPocket.UPDATES).count()
61- 0
62-
63- >>> bs.getBuildsByArchIds(ubuntu, arch_ids,
64- ... pocket=PackagePublishingPocket.RELEASE).count()
65- 5
66-
67-getBuildsByArchIds will also return builds for archives other than the
68-primary archive.
69-
70- >>> breezy = ubuntu.getSeries('breezy-autotest')
71- >>> arch_ids = [arch.id for arch in breezy.architectures]
72- >>> [(build.archive.purpose.name, build.title) for build in
73- ... bs.getBuildsByArchIds(ubuntu, arch_ids, name='commercialpackage')]
74- [('PARTNER', u'i386 build of commercialpackage 1.0-1 in ubuntu breezy-autotest RELEASE')]
75-
76-`IBinaryPackageBuildSet` also provides getStatusSummaryForBuilds which
77-summarizes the build status of a set of builds:
78-
79-First we'll define a helper to print the build summary:
80-
81- >>> def print_build_summary(summary):
82- ... print "%s\n%s\nRelevant builds:\n%s" % (
83- ... summary['status'].title,
84- ... summary['status'].description,
85- ... "\n".join(
86- ... " - %s" % build.title for build in summary['builds'])
87- ... )
88-
89- >>> build_summary = bs.getStatusSummaryForBuilds(i386_builds)
90- >>> print_build_summary(build_summary)
91- NEEDSBUILD
92- There are some builds waiting to be built.
93- Relevant builds:
94- - i386 build of pmount 0.1-1 in ubuntu warty RELEASE
95-
96-The build set class furthermore provides a mechanism to load build-related
97-data from the database for a given set of builds:
98-
99- >>> from lp.soyuz.model.binarypackagebuild import BinaryPackageBuild
100- >>> from storm.expr import In
101- >>> from canonical.launchpad.webapp.interfaces import (
102- ... IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
103- >>> store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
104- >>> results = list(store.find(
105- ... BinaryPackageBuild, In(BinaryPackageBuild.id, (2,6,7,8))))
106- >>> rset = removeSecurityProxy(bs)._prefetchBuildData(results)
107- >>> def filename_or_none(item):
108- ... if item is not None:
109- ... return '%s' % item.filename
110- ... else:
111- ... return 'n/a'
112- >>> def id_or_none(item):
113- ... if item is not None:
114- ... return '%d' % item.id
115- ... else:
116- ... return 'n/a'
117- >>> def sort_result_key(row):
118- ... return row[0].id
119- >>> for row in sorted(rset, key=sort_result_key):
120- ... (sourcepackagerelease, buildlog,
121- ... sourcepackagename, buildlog_content, builder,
122- ... package_build, build_farm_job) = row
123- ... print(
124- ... 'builder: %s, spr: %s, log: %s' %
125- ... (id_or_none(builder),
126- ... sourcepackagerelease.title, filename_or_none(buildlog)))
127- builder: 1, spr: mozilla-firefox - 0.9, log: netapplet-1.0.0.tar.gz
128- builder: n/a, spr: mozilla-firefox - 0.9, log: n/a
129- builder: 1, spr: pmount - 0.1-1, log: netapplet-1.0.0.tar.gz
130- builder: 1, spr: foobar - 1.0, log: netapplet-1.0.0.tar.gz
131-
132-
133-== IHadBuildRecords.getBuildRecords() Implementations ==
134-
135-XXX: Michael Nelson 20090701 bug=394276
136-The documentation for IHasBuildRecords is now in
137-lp/soyuz/doc/hasbuildrecords.txt. The following implementation tests should
138-be converted to unit-tests in lib/soyuz/tests/test_hasbuildrecords.py.
139-
140-We can find recent and pending builds for a given distrarchoseries.
141-
142- >>> hoaryi386 = hoary['i386']
143- >>> hoaryi386.title
144- u'The Hoary Hedgehog Release for i386 (x86)'
145-
146-Exercises IHasBuildRecords abilities for distroarchseriess
147-
148- >>> hoaryi386.getBuildRecords().count()
149- 4
150-
151- >>> hoaryi386.getBuildRecords(build_state=BuildStatus.FULLYBUILT).count()
152- 1
153-
154- >>> hoaryi386.getBuildRecords(name='pm').count()
155- 1
156-
157- >>> hoaryi386.getBuildRecords(
158- ... pocket=PackagePublishingPocket.RELEASE).count()
159- 4
160-
161- >>> hoaryi386.getBuildRecords(
162- ... pocket=PackagePublishingPocket.UPDATES).count()
163- 0
164-
165-
166-For SourcePackages, getBuildRecords() returns all build records
167-published in its context (distroseries and distribution main
168-archives), independent of their corresponding source publishing
169-status.
170-
171- >>> firefox = warty.getSourcePackage('mozilla-firefox')
172-
173- >>> firefox.getBuildRecords().count()
174- 8
175-
176- >>> firefox.getBuildRecords(
177- ... build_state=BuildStatus.FULLYBUILT).count()
178- 6
179-
180- >>> firefox.getBuildRecords(
181- ... pocket=PackagePublishingPocket.RELEASE).count()
182- 8
183-
184- >>> firefox.getBuildRecords(
185- ... pocket=PackagePublishingPocket.UPDATES).count()
186- 0
187-
188-As mentioned above, SourcePackage.getBuildRecords() will return builds
189-for packages that are no longer published. At first, there are no
190-traces of the 'old-source' sourcepackage in ubuntutest/breezy-autotest
191-
192- >>> ubuntutest = getUtility(IDistributionSet).getByName('ubuntutest')
193- >>> breezy_autotest = ubuntutest.getSeries('breezy-autotest')
194- >>> print breezy_autotest.getSourcePackage('old-source')
195- None
196-
197-Once the SourcePackage exists and has builds, they will be returned by
198-getBuildRecords() ordered by descending creation date.
199-
200- # Create a DELETED and a SUPERSEDED source publication in
201- # ubuntutest/breezy-autotest.
202- >>> from lp.soyuz.enums import PackagePublishingStatus
203- >>> login('foo.bar@canonical.com')
204- >>> old_source_pub = test_publisher.getPubSource(
205- ... sourcename='old-source', version='1.0',
206- ... status=PackagePublishingStatus.SUPERSEDED)
207- >>> [superseded_build] = old_source_pub.createMissingBuilds()
208- >>> deleted_source_pub = test_publisher.getPubSource(
209- ... sourcename='old-source', version='1.1',
210- ... status=PackagePublishingStatus.DELETED)
211- >>> [deleted_build] = deleted_source_pub.createMissingBuilds()
212- >>> login(ANONYMOUS)
213-
214- >>> old_source_sp = breezy_autotest.getSourcePackage('old-source')
215- >>> old_source_builds = old_source_sp.getBuildRecords()
216- >>> [deleted_build, superseded_build] == list(old_source_builds)
217- True
218-
219- >>> deleted_build.date_created > superseded_build.date_created
220- True
221-
222-Builds records for the exactly the same `SourcePackageRelease`s may
223-exist in a rebuild archive context, but they do not 'leak' to the
224-domain of SourcePackage.
225-
226- # Create a rebuild archive, copy the 'old-source' source
227- # publications to it and create builds in the rebuild archive
228- # context.
229- >>> from lp.soyuz.enums import ArchivePurpose
230- >>> login('foo.bar@canonical.com')
231- >>> rebuild_archive = factory.makeArchive(
232- ... ubuntutest, ubuntutest.owner, 'test-rebuild',
233- ... ArchivePurpose.COPY)
234- >>> rebuild_old_pub = old_source_pub.copyTo(
235- ... breezy_autotest, PackagePublishingPocket.RELEASE,
236- ... rebuild_archive)
237- >>> [rebuild_old_build] = rebuild_old_pub.createMissingBuilds()
238- >>> rebuild_deleted_pub = deleted_source_pub.copyTo(
239- ... breezy_autotest, PackagePublishingPocket.RELEASE,
240- ... rebuild_archive)
241- >>> [rebuild_deleted_build] = rebuild_deleted_pub.createMissingBuilds()
242- >>> login(ANONYMOUS)
243-
244- >>> rebuild_builds = rebuild_archive.getBuildRecords()
245- >>> [rebuild_deleted_build, rebuild_old_build] == list(rebuild_builds)
246- True
247-
248- >>> old_source_sp.getBuildRecords().count()
249- 2
250-
251-For a given distribution as well:
252-
253- >>> ubuntu.getBuildRecords().count()
254- 17
255-
256- >>> builds = ubuntu.getBuildRecords(build_state=BuildStatus.FULLYBUILT)
257- >>> for build in builds:
258- ... print build.date_finished, build.id, build.status.value
259- 2007-08-10 00:00:14+00:00 30 1
260- 2007-08-09 23:59:59+00:00 29 1
261- 2005-03-25 00:00:03+00:00 7 1
262- 2005-03-25 00:00:02+00:00 16 1
263- 2005-03-25 00:00:01+00:00 19 1
264- 2004-09-27 11:57:14+00:00 2 1
265- 2004-09-27 11:57:13+00:00 18 1
266-
267-Retrieve the current PENDING builds
268-
269- >>> builds = ubuntu.getBuildRecords(build_state=BuildStatus.NEEDSBUILD)
270- >>> builds.count()
271- 2
272-
273-Note, by ordering the build by BuildQueue.lastscore, it already notice
274-the existence of a new pending build, since retry already creates a
275-new BuildQueue record:
276-
277- >>> builds = ubuntu.getBuildRecords(build_state=BuildStatus.NEEDSBUILD)
278- >>> builds.count()
279- 2
280-
281-Note that they are ordered by DESC lastscore, as expected:
282-
283- >>> for b in builds:
284- ... b.id, b.status.value, b.buildqueue_record.lastscore
285- (9, 0, 2505)
286- (11, 0, 10)
287-
288-Define a helper function to print out build details.
289-
290- >>> def print_build_details(builds):
291- ... for build in builds:
292- ... if build.archive.owner:
293- ... print "%s: %s" % (build.archive.owner.name, build.title)
294- ... else:
295- ... print "main: %s" % (build.title)
296-
297-Using the optional name argument to filter build results:
298-
299- >>> builds = ubuntu.getBuildRecords(name='pm')
300- >>> builds.count()
301- 4
302- >>> print_build_details(builds)
303- ubuntu-team: i386 build of pmount 0.1-1 in ubuntu warty RELEASE
304- ubuntu-team: i386 build of pmount 0.1-1 in ubuntu breezy-autotest RELEASE
305- ubuntu-team: hppa build of pmount 0.1-1 in ubuntu hoary RELEASE
306- ubuntu-team: i386 build of pmount 0.1-1 in ubuntu hoary RELEASE
307-
308-or using optional pocket argument:
309-
310- >>> from lp.registry.interfaces.pocket import PackagePublishingPocket
311-
312- >>> ubuntu.getBuildRecords(
313- ... build_state=BuildStatus.NEEDSBUILD,
314- ... pocket=PackagePublishingPocket.RELEASE).count()
315- 2
316-
317- >>> ubuntu.getBuildRecords(
318- ... build_state=BuildStatus.NEEDSBUILD,
319- ... pocket=PackagePublishingPocket.SECURITY).count()
320- 0
321-
322-IHasBuildRecords is implemented by Builder. It can filter on build state
323-and name. A user can also be passed for security checks on private builds;
324-if user is not passed then the query runs anonymously which means private
325-builds are excluded from anything returned.
326-
327-Log in as admin to avoid security on IBinaryPackageBuild for the moment.
328-
329- >>> login('foo.bar@canonical.com')
330-
331-Let's create a private PPA for cprov (and hence its builds become private):
332-
333- >>> from lp.registry.interfaces.person import IPersonSet
334- >>> cprov = removeSecurityProxy(getUtility(IPersonSet).getByName('cprov'))
335- >>> cprov_private_ppa = factory.makeArchive(
336- ... owner=cprov, private=True, name='p3a',
337- ... distribution=cprov.archive.distribution)
338- >>> from lp.buildmaster.interfaces.builder import IBuilderSet
339- >>> bob = getUtility(IBuilderSet)['bob']
340- >>> binaries = test_publisher.getPubBinaries(
341- ... archive=cprov_private_ppa, builder=bob,
342- ... binaryname='privacycheck-bin')
343- >>> flush_database_updates()
344-
345-The default set of builds with no user specified excludes private builds:
346-
347- >>> bob_builds = bob.getBuildRecords()
348- >>> print_build_details(bob_builds)
349- ubuntu-team: hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
350- cprov: hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
351- cprov: i386 build of pmount 0.1-1 in ubuntu warty RELEASE
352- cprov: i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
353- no-priv: i386 build of cdrkit 1.0 in ubuntu warty RELEASE
354- ubuntu-team: i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
355- ...
356- ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu warty RELEASE
357- ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu breezy-autotest
358- RELEASE
359-
360- >>> bob_builds.count()
361- 16
362-
363-If we include an admin user, we can see all the builds. Here, we get
364-an additional private build for cprov:
365-
366- >>> from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
367- >>> admin = getUtility(ILaunchpadCelebrities).admin
368- >>> bob_builds = bob.getBuildRecords(user=admin)
369- >>> print_build_details(bob_builds)
370- cprov: i386 build of privacycheck 666 in ubuntutest breezy-autotest...
371- ubuntu-team: hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
372- cprov: hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
373- cprov: i386 build of pmount 0.1-1 in ubuntu warty RELEASE
374- cprov: i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
375- no-priv: i386 build of cdrkit 1.0 in ubuntu warty RELEASE
376- ubuntu-team: i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
377- ...
378- ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu warty RELEASE
379- ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu breezy-autotest
380- RELEASE
381-
382- >>> bob_builds.count()
383- 17
384-
385-Cprov can also see his own builds of course:
386-
387- >>> bob_builds = bob.getBuildRecords(user=cprov)
388- >>> print_build_details(bob_builds)
389- cprov: i386 build of privacycheck 666 in ubuntutest breezy-autotest...
390- ubuntu-team: hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
391- cprov: hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
392- cprov: i386 build of pmount 0.1-1 in ubuntu warty RELEASE
393- cprov: i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
394- no-priv: i386 build of cdrkit 1.0 in ubuntu warty RELEASE
395- ubuntu-team: i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
396- ...
397- ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu warty RELEASE
398- ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu breezy-autotest
399- RELEASE
400-
401- >>> bob_builds.count()
402- 17
403-
404-Buildd admins specifically are not allowed to see private builds, which will
405-be filtered from the list returned:
406-
407- >>> buildd_admin = factory.makePerson()
408- >>> buildd_admins = getUtility(
409- ... IPersonSet).getByName('launchpad-buildd-admins')
410- >>> ignored = buildd_admins.addMember(buildd_admin, buildd_admin)
411- >>> bob_builds = bob.getBuildRecords(user=buildd_admin)
412- >>> print_build_details(bob_builds)
413- ubuntu-team: hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
414- cprov: hppa build of mozilla-firefox 0.9 in ubuntu warty RELEASE
415- cprov: i386 build of pmount 0.1-1 in ubuntu warty RELEASE
416- cprov: i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
417- no-priv: i386 build of cdrkit 1.0 in ubuntu warty RELEASE
418- ubuntu-team: i386 build of cdrkit 1.0 in ubuntu breezy-autotest RELEASE
419- ...
420- ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu warty RELEASE
421- ubuntu-team: i386 build of mozilla-firefox 0.9 in ubuntu breezy-autotest
422- RELEASE
423-
424- >>> bob_builds.count()
425- 16
426-
427-You can filter on build state:
428-
429- >>> bob_failed_builds = bob.getBuildRecords(
430- ... build_state=BuildStatus.FAILEDTOBUILD, user=admin)
431- >>> bob_failed_builds.count()
432- 3
433-
434-You can filter on package name:
435-
436- >>> bob_pmount_builds = bob.getBuildRecords(name='pmount', user=admin)
437- >>> bob_pmount_builds.count()
438- 4
439-
440-You can filter on build state and package name:
441-
442- >>> bob_pmount_ok_builds = bob.getBuildRecords(
443- ... build_state=BuildStatus.FULLYBUILT, name='pmount', user=admin)
444- >>> bob_pmount_ok_builds.count()
445- 4
446-
447-
448 == AssertionErrors in IBinaryPackageBuild ==
449
450 Build records inserted by gina don't provide calculated_buildstart
451
452=== modified file 'lib/lp/soyuz/tests/test_binarypackagebuild.py'
453--- lib/lp/soyuz/tests/test_binarypackagebuild.py 2011-01-14 10:06:08 +0000
454+++ lib/lp/soyuz/tests/test_binarypackagebuild.py 2011-01-20 21:02:59 +0000
455@@ -49,9 +49,9 @@
456 super(TestBinaryPackageBuild, self).setUp()
457 publisher = SoyuzTestPublisher()
458 publisher.prepareBreezyAutotest()
459- gedit_spr = publisher.getPubSource(
460- spr_only=True, sourcename="gedit",
461- status=PackagePublishingStatus.PUBLISHED)
462+ gedit_spph = publisher.getPubSource(
463+ sourcename="gedit", status=PackagePublishingStatus.PUBLISHED)
464+ gedit_spr = gedit_spph.sourcepackagerelease
465 self.build = gedit_spr.createBuild(
466 distro_arch_series=publisher.distroseries['i386'],
467 archive=gedit_spr.upload_archive,
468
469=== modified file 'lib/lp/soyuz/tests/test_hasbuildrecords.py'
470--- lib/lp/soyuz/tests/test_hasbuildrecords.py 2010-10-04 19:50:45 +0000
471+++ lib/lp/soyuz/tests/test_hasbuildrecords.py 2011-01-20 21:02:59 +0000
472@@ -1,20 +1,33 @@
473-# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
474+# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
475 # GNU Affero General Public License version 3 (see the file LICENSE).
476
477 """Test implementations of the IHasBuildRecords interface."""
478
479+from datetime import (
480+ datetime,
481+ timedelta,
482+ )
483+import pytz
484 from zope.component import getUtility
485 from zope.security.proxy import removeSecurityProxy
486
487 from canonical.testing.layers import LaunchpadZopelessLayer
488-from lp.buildmaster.enums import BuildFarmJobType
489+from lp.buildmaster.enums import (
490+ BuildFarmJobType,
491+ BuildStatus,
492+ )
493 from lp.buildmaster.interfaces.builder import IBuilderSet
494 from lp.buildmaster.interfaces.buildfarmjob import (
495 IBuildFarmJob,
496 )
497 from lp.buildmaster.interfaces.packagebuild import IPackageBuildSource
498+from lp.registry.interfaces.person import IPersonSet
499 from lp.registry.interfaces.pocket import PackagePublishingPocket
500 from lp.registry.model.sourcepackage import SourcePackage
501+from lp.soyuz.enums import (
502+ ArchivePurpose,
503+ PackagePublishingStatus,
504+ )
505 from lp.soyuz.interfaces.binarypackagebuild import IBinaryPackageBuild
506 from lp.soyuz.interfaces.buildrecords import (
507 IHasBuildRecords,
508@@ -22,6 +35,12 @@
509 )
510 from lp.soyuz.model.processor import ProcessorFamilySet
511 from lp.soyuz.tests.test_binarypackagebuild import BaseTestCaseWithThreeBuilds
512+from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
513+from lp.testing import (
514+ person_logged_in,
515+ TestCaseWithFactory,
516+ )
517+from lp.testing.sampledata import ADMIN_EMAIL
518
519
520 class TestHasBuildRecordsInterface(BaseTestCaseWithThreeBuilds):
521@@ -37,7 +56,6 @@
522 def setUp(self):
523 """Use `SoyuzTestPublisher` to publish some sources in archives."""
524 super(TestHasBuildRecordsInterface, self).setUp()
525-
526 self.context = self.publisher.distroseries.distribution
527
528 def testProvidesHasBuildRecords(self):
529@@ -64,6 +82,67 @@
530 self.assertContentEqual(i386_builds, builds)
531
532
533+class TestDistributionHasBuildRecords(TestCaseWithFactory):
534+ """Populate a distroseries with builds"""
535+
536+ layer = LaunchpadZopelessLayer
537+
538+ def setUp(self):
539+ super(TestDistributionHasBuildRecords, self).setUp()
540+ self.admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)
541+ # Create the machinery we need to create builds, such as
542+ # DistroArchSeries and builders.
543+ self.pf_one = self.factory.makeProcessorFamily()
544+ pf_proc_1 = self.pf_one.addProcessor(
545+ self.factory.getUniqueString(), '', '')
546+ self.pf_two = self.factory.makeProcessorFamily()
547+ pf_proc_2 = self.pf_two.addProcessor(
548+ self.factory.getUniqueString(), '', '')
549+ self.distroseries = self.factory.makeDistroSeries()
550+ self.distribution = self.distroseries.distribution
551+ self.das_one = self.factory.makeDistroArchSeries(
552+ distroseries=self.distroseries, processorfamily=self.pf_one,
553+ supports_virtualized=True)
554+ self.das_two = self.factory.makeDistroArchSeries(
555+ distroseries=self.distroseries, processorfamily=self.pf_two,
556+ supports_virtualized=True)
557+ self.archive = self.factory.makeArchive(
558+ distribution=self.distroseries.distribution,
559+ purpose=ArchivePurpose.PRIMARY)
560+ self.arch_ids = [arch.id for arch in self.distroseries.architectures]
561+ with person_logged_in(self.admin):
562+ self.publisher = SoyuzTestPublisher()
563+ self.publisher.prepareBreezyAutotest()
564+ self.distroseries.nominatedarchindep = self.das_one
565+ self.publisher.addFakeChroots(distroseries=self.distroseries)
566+ self.builder_one = self.factory.makeBuilder(processor=pf_proc_1)
567+ self.builder_two = self.factory.makeBuilder(processor=pf_proc_2)
568+ self.builds = []
569+ self.createBuilds()
570+
571+ def createBuilds(self):
572+ for i in range(5):
573+ # Create some test builds.
574+ spph = self.publisher.getPubSource(
575+ sourcename=self.factory.getUniqueString(),
576+ version="%s.%s" % (self.factory.getUniqueInteger(), i),
577+ distroseries=self.distroseries, architecturehintlist='any')
578+ builds = spph.createMissingBuilds()
579+ for b in builds:
580+ if i == 4:
581+ b.status = BuildStatus.FAILEDTOBUILD
582+ else:
583+ b.status = BuildStatus.FULLYBUILT
584+ b.buildqueue_record.destroySelf()
585+ b.date_started = datetime.now(pytz.UTC)
586+ b.date_finished = b.date_started + timedelta(minutes=5)
587+ self.builds += builds
588+
589+ def test_get_build_records(self):
590+ # A Distribution also implements IHasBuildRecords.
591+ builds = self.distribution.getBuildRecords().count()
592+ self.assertEquals(10, builds)
593+
594 class TestDistroSeriesHasBuildRecords(TestHasBuildRecordsInterface):
595 """Test the DistroSeries implementation of IHasBuildRecords."""
596
597@@ -73,13 +152,30 @@
598 self.context = self.publisher.distroseries
599
600
601-class TestDistroArchSeriesHasBuildRecords(TestHasBuildRecordsInterface):
602+class TestDistroArchSeriesHasBuildRecords(TestDistributionHasBuildRecords):
603 """Test the DistroArchSeries implementation of IHasBuildRecords."""
604
605+ layer = LaunchpadZopelessLayer
606+
607 def setUp(self):
608 super(TestDistroArchSeriesHasBuildRecords, self).setUp()
609
610- self.context = self.publisher.distroseries['i386']
611+ def test_distroarchseries(self):
612+ # We can fetch builds records from a DistroArchSeries.
613+ builds = self.das_one.getBuildRecords().count()
614+ self.assertEquals(5, builds)
615+ builds = self.das_one.getBuildRecords(
616+ build_state=BuildStatus.FULLYBUILT).count()
617+ self.assertEquals(4, builds)
618+ spn = self.builds[0].source_package_release.sourcepackagename.name
619+ builds = self.das_one.getBuildRecords(name=spn).count()
620+ self.assertEquals(1, builds)
621+ builds = self.das_one.getBuildRecords(
622+ pocket=PackagePublishingPocket.RELEASE).count()
623+ self.assertEquals(5, builds)
624+ builds = self.das_one.getBuildRecords(
625+ pocket=PackagePublishingPocket.UPDATES).count()
626+ self.assertEquals(0, builds)
627
628
629 class TestArchiveHasBuildRecords(TestHasBuildRecordsInterface):
630@@ -144,7 +240,6 @@
631 # can only test this by creating a lone IBuildFarmJob of a
632 # different type.
633 from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
634- from lp.buildmaster.enums import BuildStatus
635 build_farm_job = getUtility(IBuildFarmJobSource).new(
636 job_type=BuildFarmJobType.RECIPEBRANCHBUILD, virtualized=True,
637 status=BuildStatus.BUILDING)
638@@ -180,11 +275,9 @@
639
640 def setUp(self):
641 super(TestSourcePackageHasBuildRecords, self).setUp()
642-
643 gedit_name = self.builds[0].source_package_release.sourcepackagename
644 self.context = SourcePackage(
645- gedit_name,
646- self.builds[0].distro_arch_series.distroseries)
647+ gedit_name, self.builds[0].distro_arch_series.distroseries)
648
649 # Convert the other two builds to be builds of
650 # gedit as well so that the one source package (gedit) will have
651@@ -192,3 +285,85 @@
652 for build in self.builds[1:3]:
653 spr = build.source_package_release
654 removeSecurityProxy(spr).sourcepackagename = gedit_name
655+
656+ # Set them as sucessfully built
657+ for build in self.builds:
658+ build.status = BuildStatus.FULLYBUILT
659+ build.buildqueue_record.destroySelf()
660+ removeSecurityProxy(build).date_created = (
661+ self.factory.getUniqueDate())
662+ build.date_started = datetime.now(pytz.UTC)
663+ build.date_finished = build.date_started + timedelta(minutes=5)
664+
665+ def test_get_build_records(self):
666+ # We can fetch builds records from a SourcePackage.
667+ builds = self.context.getBuildRecords(
668+ build_state=BuildStatus.FULLYBUILT).count()
669+ self.assertEquals(3, builds)
670+ builds = self.context.getBuildRecords(
671+ pocket=PackagePublishingPocket.RELEASE).count()
672+ self.assertEquals(3, builds)
673+ builds = self.context.getBuildRecords(
674+ pocket=PackagePublishingPocket.UPDATES).count()
675+ self.assertEquals(0, builds)
676+
677+ def test_ordering_date(self):
678+ # Build records returned are ordered by creation date.
679+ builds = self.context.getBuildRecords(
680+ build_state=BuildStatus.FULLYBUILT)
681+ date_created = [build.date_created for build in builds]
682+ self.assertTrue(date_created[0] > date_created[1] > date_created[2])
683+
684+ def test_ordering_lastscore(self):
685+ # PENDING build records returned are ordered by score.
686+ spph = self.factory.makeSourcePackagePublishingHistory()
687+ spr = spph.sourcepackagerelease
688+ source_package = SourcePackage.new(
689+ spph.sourcepackagerelease.sourcepackagename, spph.distroseries)
690+ build1 = self.factory.makeBinaryPackageBuild(
691+ source_package_release=spr)
692+ build2 = self.factory.makeBinaryPackageBuild(
693+ source_package_release=spr)
694+ build1.queueBuild()
695+ build2.queueBuild()
696+ build1.buildqueue_record.lastscore = 10
697+ build2.buildqueue_record.lastscore = 1000
698+ builds = list(source_package.getBuildRecords())
699+ self.assertEquals([build2, build1], builds)
700+
701+ def test_copy_archive_without_leak(self):
702+ # If source publications are copied to a .COPY archive, they don't
703+ # "leak" into SourcePackage.getBuildRecords().
704+ admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)
705+ # Set up a distroseries and related bits, so we can create builds.
706+ source_name = self.factory.getUniqueString()
707+ spn = self.factory.makeSourcePackageName(name=source_name)
708+ pf = self.factory.makeProcessorFamily()
709+ pf_proc = pf.addProcessor(self.factory.getUniqueString(), '', '')
710+ distroseries = self.factory.makeDistroSeries()
711+ das = self.factory.makeDistroArchSeries(
712+ distroseries=distroseries, processorfamily=pf,
713+ supports_virtualized=True)
714+ with person_logged_in(admin):
715+ publisher = SoyuzTestPublisher()
716+ publisher.prepareBreezyAutotest()
717+ publisher.addFakeChroots(distroseries=distroseries)
718+ distroseries.nominatedarchindep = das
719+ builder = self.factory.makeBuilder(processor=pf_proc)
720+ spph = self.factory.makeSourcePackagePublishingHistory(
721+ sourcepackagename=spn, distroseries=distroseries)
722+ spph.createMissingBuilds()
723+ # Create a copy archive.
724+ copy = self.factory.makeArchive(
725+ purpose=ArchivePurpose.COPY,
726+ distribution=distroseries.distribution)
727+ # And copy the publication into it.
728+ copy_spph = spph.copyTo(
729+ distroseries, PackagePublishingPocket.RELEASE, copy)
730+ [copy_build] = copy_spph.createMissingBuilds()
731+ builds = copy.getBuildRecords()
732+ self.assertEquals([copy_build], list(builds))
733+ source = SourcePackage(spn, spph.distroseries)
734+ # SourcePackage.getBuildRecords() doesn't have two build records.
735+ builds = source.getBuildRecords().count()
736+ self.assertEquals(1, builds)