Merge lp:~jml/launchpad/more-recipe-model-code into lp:launchpad/db-devel
- more-recipe-model-code
- Merge into db-devel
Proposed by
Jonathan Lange
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~jml/launchpad/more-recipe-model-code |
Merge into: | lp:launchpad/db-devel |
Prerequisite: | lp:~mwhudson/launchpad/recipe-model-code |
Diff against target: |
594 lines (+311/-41) 13 files modified
.bzrignore (+1/-0) database/schema/security.cfg (+1/-0) lib/lp/soyuz/configure.zcml (+11/-0) lib/lp/soyuz/interfaces/build.py (+1/-0) lib/lp/soyuz/interfaces/sourcepackagebuild.py (+94/-0) lib/lp/soyuz/interfaces/sourcepackagerecipe.py (+0/-1) lib/lp/soyuz/model/sourcepackagebuild.py (+97/-0) lib/lp/soyuz/model/sourcepackagerecipe.py (+3/-1) lib/lp/soyuz/tests/test_sourcepackagebuild.py (+43/-0) lib/lp/soyuz/tests/test_sourcepackagerecipe.py (+11/-33) lib/lp/testing/factory.py (+47/-3) standard_template.py (+1/-1) standard_test_template.py (+1/-2) |
To merge this branch: | bzr merge lp:~jml/launchpad/more-recipe-model-code |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Canonical Launchpad Engineering | Pending | ||
Review via email: mp+17188@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Jonathan Lange (jml) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2010-01-10 22:23:32 +0000 |
3 | +++ .bzrignore 2010-01-12 04:22:16 +0000 |
4 | @@ -54,3 +54,4 @@ |
5 | _trial_temp |
6 | lazr-js |
7 | lib/canonical/buildd/launchpad-files |
8 | +.testrepository |
9 | |
10 | === modified file 'database/schema/security.cfg' |
11 | --- database/schema/security.cfg 2010-01-12 04:22:13 +0000 |
12 | +++ database/schema/security.cfg 2010-01-12 04:22:16 +0000 |
13 | @@ -275,6 +275,7 @@ |
14 | public.sourcepackagepublishinghistory = SELECT |
15 | public.seriessourcepackagebranch = SELECT, INSERT, UPDATE, DELETE |
16 | public.sourcepackageformatselection = SELECT |
17 | +public.sourcepackagebuild = SELECT, INSERT, UPDATE, DELETE |
18 | public.sourcepackagerecipe = SELECT, INSERT, UPDATE, DELETE |
19 | public.sourcepackagerecipedata = SELECT, INSERT, UPDATE, DELETE |
20 | public.sourcepackagerecipedatainstruction = SELECT, INSERT, UPDATE, DELETE |
21 | |
22 | === modified file 'lib/lp/soyuz/configure.zcml' |
23 | --- lib/lp/soyuz/configure.zcml 2010-01-12 04:22:13 +0000 |
24 | +++ lib/lp/soyuz/configure.zcml 2010-01-12 04:22:16 +0000 |
25 | @@ -945,4 +945,15 @@ |
26 | <allow interface="lp.soyuz.interfaces.sourcepackagerecipe.ISourcePackageRecipeSource"/> |
27 | </securedutility> |
28 | |
29 | + <class |
30 | + class="lp.soyuz.model.sourcepackagebuild.SourcePackageBuild"> |
31 | + <allow interface="lp.soyuz.interfaces.sourcepackagebuild.ISourcePackageBuild"/> |
32 | + </class> |
33 | + |
34 | + <securedutility |
35 | + component="lp.soyuz.model.sourcepackagebuild.SourcePackageBuild" |
36 | + provides="lp.soyuz.interfaces.sourcepackagebuild.ISourcePackageBuildSource"> |
37 | + <allow interface="lp.soyuz.interfaces.sourcepackagebuild.ISourcePackageBuildSource"/> |
38 | + </securedutility> |
39 | + |
40 | </configure> |
41 | |
42 | === modified file 'lib/lp/soyuz/interfaces/build.py' |
43 | --- lib/lp/soyuz/interfaces/build.py 2009-11-20 18:06:28 +0000 |
44 | +++ lib/lp/soyuz/interfaces/build.py 2010-01-12 04:22:16 +0000 |
45 | @@ -201,6 +201,7 @@ |
46 | description=_("Build duration interval, calculated when the " |
47 | "build result gets collected.")) |
48 | |
49 | + # XXX: jml 2010-01-12: Rename to build_log. |
50 | buildlog = Object( |
51 | schema=ILibraryFileAlias, required=False, |
52 | title=_("The LibraryFileAlias containing the entire buildlog.")) |
53 | |
54 | === added file 'lib/lp/soyuz/interfaces/sourcepackagebuild.py' |
55 | --- lib/lp/soyuz/interfaces/sourcepackagebuild.py 1970-01-01 00:00:00 +0000 |
56 | +++ lib/lp/soyuz/interfaces/sourcepackagebuild.py 2010-01-12 04:22:16 +0000 |
57 | @@ -0,0 +1,94 @@ |
58 | +# Copyright 2010 Canonical Ltd. This software is licensed under the |
59 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
60 | + |
61 | +"""Interfaces for source package builds.""" |
62 | + |
63 | +__metaclass__ = type |
64 | +__all__ = [ |
65 | + 'ISourcePackageBuild', |
66 | + 'ISourcePackageBuildSource', |
67 | + ] |
68 | + |
69 | +from lazr.restful.fields import Reference |
70 | + |
71 | +from zope.interface import Attribute, Interface |
72 | +from zope.schema import Choice, Datetime, Object, Timedelta |
73 | + |
74 | +from canonical.launchpad import _ |
75 | +from canonical.launchpad.interfaces.librarian import ILibraryFileAlias |
76 | + |
77 | +from lp.registry.interfaces.person import IPerson |
78 | +from lp.registry.interfaces.distroseries import IDistroSeries |
79 | +from lp.registry.interfaces.sourcepackagename import ISourcePackageName |
80 | +from lp.soyuz.interfaces.build import BuildStatus |
81 | +from lp.soyuz.interfaces.builder import IBuilder |
82 | +from lp.soyuz.interfaces.sourcepackagerecipe import ISourcePackageRecipe |
83 | + |
84 | + |
85 | +class ISourcePackageBuild(Interface): |
86 | + """A build of a source package.""" |
87 | + |
88 | + date_created = Datetime(required=True, readonly=True) |
89 | + |
90 | + distroseries = Reference( |
91 | + IDistroSeries, title=_("The distroseries being built for"), |
92 | + readonly=True) |
93 | + |
94 | + sourcepackagename = Reference( |
95 | + ISourcePackageName, |
96 | + title=_("The name of the source package being built"), |
97 | + readonly=True) |
98 | + |
99 | + # XXX: JonathanLange 2010-01-12: Move build_state, date_built, |
100 | + # build_duration, build_log, builder and maybe date_first_dispatched to a |
101 | + # separate base interface shared by this and IBuild. Additionally, change |
102 | + # IBuild to IBinaryPackageBuild. |
103 | + build_state = Choice( |
104 | + title=_('State'), required=True, vocabulary=BuildStatus, |
105 | + description=_("The current build state.")) |
106 | + |
107 | + date_built = Datetime(required=False) |
108 | + |
109 | + build_duration = Timedelta( |
110 | + title=_("Build Duration"), required=False, |
111 | + description=_("Build duration interval, calculated when the " |
112 | + "build result gets collected.")) |
113 | + |
114 | + build_log = Object( |
115 | + schema=ILibraryFileAlias, required=False, |
116 | + title=_("The LibraryFileAlias containing the entire build log.")) |
117 | + |
118 | + builder = Object( |
119 | + title=_("Builder"), schema=IBuilder, required=False, |
120 | + description=_("The builder handling this build request.")) |
121 | + |
122 | + date_first_dispatched = Datetime( |
123 | + title=_('Date first dispatched'), required=False, |
124 | + description=_("The actual build start time. Set when the build " |
125 | + "is dispatched the first time and not changed in " |
126 | + "subsequent build attempts.")) |
127 | + |
128 | + requester = Object( |
129 | + schema=IPerson, required=False, |
130 | + title=_("The person who wants this to be done.")) |
131 | + |
132 | + recipe = Object( |
133 | + schema=ISourcePackageRecipe, required=True, |
134 | + title=_("The recipe being built.")) |
135 | + |
136 | + manifest = Attribute(_("The manifest of the built package.")) |
137 | + |
138 | + |
139 | +class ISourcePackageBuildSource(Interface): |
140 | + """A utility of this interface be used to create source package builds.""" |
141 | + |
142 | + def new(sourcepackage, recipe, requester, date_created=None): |
143 | + """Create an `ISourcePackageBuild`. |
144 | + |
145 | + :param sourcepackage: The `ISourcePackage` that this is building. |
146 | + :param recipe: The `ISourcePackageRecipe` that this is building. |
147 | + :param requester: The `IPerson` who wants to build it. |
148 | + :param date_created: The date this build record was created. If not |
149 | + provided, defaults to now. |
150 | + :return: `ISourcePackageBuild`. |
151 | + """ |
152 | |
153 | === modified file 'lib/lp/soyuz/interfaces/sourcepackagerecipe.py' |
154 | --- lib/lp/soyuz/interfaces/sourcepackagerecipe.py 2010-01-12 04:22:13 +0000 |
155 | +++ lib/lp/soyuz/interfaces/sourcepackagerecipe.py 2010-01-12 04:22:16 +0000 |
156 | @@ -14,7 +14,6 @@ |
157 | from lazr.restful.fields import Reference |
158 | |
159 | from zope.interface import Interface |
160 | - |
161 | from zope.schema import Datetime, Text, TextLine |
162 | |
163 | from canonical.launchpad import _ |
164 | |
165 | === added file 'lib/lp/soyuz/model/sourcepackagebuild.py' |
166 | --- lib/lp/soyuz/model/sourcepackagebuild.py 1970-01-01 00:00:00 +0000 |
167 | +++ lib/lp/soyuz/model/sourcepackagebuild.py 2010-01-12 04:22:16 +0000 |
168 | @@ -0,0 +1,97 @@ |
169 | +# Copyright 2010 Canonical Ltd. This software is licensed under the |
170 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
171 | + |
172 | +"""Implementation code for source package builds.""" |
173 | + |
174 | +__metaclass__ = type |
175 | +__all__ = [ |
176 | + 'SourcePackageBuild', |
177 | + ] |
178 | + |
179 | +from canonical.database.constants import UTC_NOW |
180 | +from canonical.database.datetimecol import UtcDateTimeCol |
181 | +from canonical.database.enumcol import EnumCol |
182 | +from canonical.launchpad.interfaces.lpstorm import IMasterStore |
183 | + |
184 | +from storm.locals import Int, Reference, Storm, TimeDelta |
185 | + |
186 | +from zope.interface import classProvides, implements |
187 | + |
188 | +from lp.soyuz.interfaces.build import BuildStatus |
189 | +from lp.soyuz.interfaces.sourcepackagebuild import ( |
190 | + ISourcePackageBuild, ISourcePackageBuildSource) |
191 | + |
192 | + |
193 | +class SourcePackageBuild(Storm): |
194 | + |
195 | + __storm_table__ = 'SourcePackageBuild' |
196 | + |
197 | + implements(ISourcePackageBuild) |
198 | + classProvides(ISourcePackageBuildSource) |
199 | + |
200 | + id = Int(primary=True) |
201 | + |
202 | + build_duration = TimeDelta(name='build_duration', default=None) |
203 | + |
204 | + builder_id = Int(name='builder', allow_none=True) |
205 | + builder = Reference(builder_id, 'Builder.id') |
206 | + |
207 | + build_log_id = Int(name='build_log', allow_none=True) |
208 | + build_log = Reference(build_log_id, 'LibraryFileAlias.id') |
209 | + |
210 | + build_state = EnumCol( |
211 | + dbName='build_state', notNull=True, schema=BuildStatus) |
212 | + |
213 | + date_created = UtcDateTimeCol(notNull=True) |
214 | + date_built = UtcDateTimeCol(notNull=False) |
215 | + date_first_dispatched = UtcDateTimeCol(notNull=False) |
216 | + |
217 | + distroseries_id = Int(name='distroseries', allow_none=True) |
218 | + distroseries = Reference(distroseries_id, 'DistroSeries.id') |
219 | + |
220 | + sourcepackagename_id = Int(name='sourcepackagename', allow_none=True) |
221 | + sourcepackagename = Reference(sourcepackagename_id, 'SourcePackageName.id') |
222 | + |
223 | + recipe_id = Int(name='recipe', allow_none=False) |
224 | + recipe = Reference(recipe_id, 'SourcePackageRecipe.id') |
225 | + |
226 | + requester_id = Int(name='requester', allow_none=False) |
227 | + requester = Reference(requester_id, 'Person.id') |
228 | + |
229 | + manifest_id = Int(name='manifest', allow_none=True) |
230 | + manifest = Reference(manifest_id, '_SourcePackageRecipeData.id') |
231 | + |
232 | + def __init__(self, distroseries, sourcepackagename, recipe, requester, |
233 | + date_created=None, date_first_dispatched=None, |
234 | + date_built=None, manifest=None, builder=None, |
235 | + build_state=BuildStatus.NEEDSBUILD, build_log=None, |
236 | + build_duration=None): |
237 | + """Construct a SourcePackageBuild.""" |
238 | + super(SourcePackageBuild, self).__init__() |
239 | + self.build_duration = build_duration |
240 | + self.build_log = build_log |
241 | + self.builder = builder |
242 | + self.build_state = build_state |
243 | + self.date_built = date_built |
244 | + self.date_created = date_created |
245 | + self.date_first_dispatched = date_first_dispatched |
246 | + self.distroseries = distroseries |
247 | + self.manifest = manifest |
248 | + self.recipe = recipe |
249 | + self.requester = requester |
250 | + self.sourcepackagename = sourcepackagename |
251 | + |
252 | + @classmethod |
253 | + def new(cls, sourcepackage, recipe, requester, date_created=None): |
254 | + """See `ISourcePackageBuildSource`.""" |
255 | + store = IMasterStore(SourcePackageBuild) |
256 | + if date_created is None: |
257 | + date_created = UTC_NOW |
258 | + spbuild = cls( |
259 | + sourcepackage.distroseries, |
260 | + sourcepackage.sourcepackagename, |
261 | + recipe, |
262 | + requester, |
263 | + date_created=date_created) |
264 | + store.add(spbuild) |
265 | + return spbuild |
266 | |
267 | === modified file 'lib/lp/soyuz/model/sourcepackagerecipe.py' |
268 | --- lib/lp/soyuz/model/sourcepackagerecipe.py 2010-01-12 04:22:13 +0000 |
269 | +++ lib/lp/soyuz/model/sourcepackagerecipe.py 2010-01-12 04:22:16 +0000 |
270 | @@ -4,7 +4,9 @@ |
271 | """Implementation of the `SourcePackageRecipe` content type.""" |
272 | |
273 | __metaclass__ = type |
274 | -__all__ = ['SourcePackageRecipe'] |
275 | +__all__ = [ |
276 | + 'SourcePackageRecipe', |
277 | + ] |
278 | |
279 | from storm.locals import Int, Reference, Storm, Unicode |
280 | |
281 | |
282 | === added file 'lib/lp/soyuz/tests/test_sourcepackagebuild.py' |
283 | --- lib/lp/soyuz/tests/test_sourcepackagebuild.py 1970-01-01 00:00:00 +0000 |
284 | +++ lib/lp/soyuz/tests/test_sourcepackagebuild.py 2010-01-12 04:22:16 +0000 |
285 | @@ -0,0 +1,43 @@ |
286 | +# Copyright 2010 Canonical Ltd. This software is licensed under the |
287 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
288 | + |
289 | +"""Tests for source package builds.""" |
290 | + |
291 | +__metaclass__ = type |
292 | + |
293 | +import unittest |
294 | + |
295 | +import transaction |
296 | +from zope.component import getUtility |
297 | + |
298 | +from canonical.testing.layers import DatabaseFunctionalLayer |
299 | + |
300 | +from lp.soyuz.interfaces.sourcepackagebuild import ( |
301 | + ISourcePackageBuild, ISourcePackageBuildSource) |
302 | +from lp.testing import TestCaseWithFactory |
303 | + |
304 | + |
305 | +class TestSourcePackageBuild(TestCaseWithFactory): |
306 | + """Test the source package build object.""" |
307 | + |
308 | + layer = DatabaseFunctionalLayer |
309 | + |
310 | + def makeSourcePackageBuild(self): |
311 | + return getUtility(ISourcePackageBuildSource).new( |
312 | + sourcepackage=self.factory.makeSourcePackage(), |
313 | + recipe=self.factory.makeSourcePackageRecipe(), |
314 | + requester=self.factory.makePerson()) |
315 | + |
316 | + def test_providesInterface(self): |
317 | + # SourcePackageBuild provides ISourcePackageBuild. |
318 | + spb = self.makeSourcePackageBuild() |
319 | + self.assertProvides(spb, ISourcePackageBuild) |
320 | + |
321 | + def test_saves_record(self): |
322 | + spb = self.makeSourcePackageBuild() |
323 | + transaction.commit() |
324 | + self.assertProvides(spb, ISourcePackageBuild) |
325 | + |
326 | + |
327 | +def test_suite(): |
328 | + return unittest.TestLoader().loadTestsFromName(__name__) |
329 | |
330 | === modified file 'lib/lp/soyuz/tests/test_sourcepackagerecipe.py' |
331 | --- lib/lp/soyuz/tests/test_sourcepackagerecipe.py 2010-01-12 04:22:13 +0000 |
332 | +++ lib/lp/soyuz/tests/test_sourcepackagerecipe.py 2010-01-12 04:22:16 +0000 |
333 | @@ -21,32 +21,11 @@ |
334 | from lp.testing import login_person, TestCaseWithFactory |
335 | |
336 | |
337 | -MINIMAL_RECIPE_TEXT = u'''\ |
338 | -# bzr-builder format 0.2 deb-version 1.0 |
339 | -%s |
340 | -''' |
341 | - |
342 | class TestSourcePackageRecipe(TestCaseWithFactory): |
343 | """Tests for `SourcePackageRecipe` objects.""" |
344 | |
345 | layer = DatabaseFunctionalLayer |
346 | |
347 | - def makeBuilderRecipe(self, *branches): |
348 | - """Make a builder recipe that references `branches`. |
349 | - |
350 | - If no branches are passed, return a recipe text that references an |
351 | - arbitrary branch. |
352 | - """ |
353 | - if len(branches) == 0: |
354 | - branches = (self.factory.makeAnyBranch(),) |
355 | - base_branch = branches[0] |
356 | - other_branches = branches[1:] |
357 | - text = MINIMAL_RECIPE_TEXT % base_branch.bzr_identity |
358 | - for i, branch in enumerate(other_branches): |
359 | - text += 'merge dummy-%s %s\n' % (i, branch.bzr_identity) |
360 | - parser = RecipeParser(text) |
361 | - return parser.parse() |
362 | - |
363 | def makeSourcePackageRecipeFromBuilderRecipe(self, builder_recipe): |
364 | """Make a SourcePackageRecipe from `builder_recipe` and arbitrary other fields. |
365 | """ |
366 | @@ -68,7 +47,7 @@ |
367 | distroseries = self.factory.makeDistroSeries() |
368 | sourcepackagename = self.factory.makeSourcePackageName() |
369 | name = self.factory.getUniqueString(u'recipe-name') |
370 | - builder_recipe = self.makeBuilderRecipe() |
371 | + builder_recipe = self.factory.makeRecipe() |
372 | recipe = getUtility(ISourcePackageRecipeSource).new( |
373 | registrant=registrant, owner=owner, distroseries=distroseries, |
374 | sourcepackagename=sourcepackagename, name=name, |
375 | @@ -87,14 +66,14 @@ |
376 | def test_recipe_implements_interface(self): |
377 | # SourcePackageRecipe objects implement ISourcePackageRecipe. |
378 | recipe = self.makeSourcePackageRecipeFromBuilderRecipe( |
379 | - self.makeBuilderRecipe()) |
380 | + self.factory.makeRecipe()) |
381 | self.assertProvides(recipe, ISourcePackageRecipe) |
382 | |
383 | def test_branch_links_created(self): |
384 | # When a recipe is created, we can query it for links to the branch |
385 | # it references. |
386 | branch = self.factory.makeAnyBranch() |
387 | - builder_recipe = self.makeBuilderRecipe(branch) |
388 | + builder_recipe = self.factory.makeRecipe(branch) |
389 | sp_recipe = self.makeSourcePackageRecipeFromBuilderRecipe( |
390 | builder_recipe) |
391 | self.assertEquals([branch], list(sp_recipe.getReferencedBranches())) |
392 | @@ -104,7 +83,7 @@ |
393 | # returns all of them. |
394 | branch1 = self.factory.makeAnyBranch() |
395 | branch2 = self.factory.makeAnyBranch() |
396 | - builder_recipe = self.makeBuilderRecipe(branch1, branch2) |
397 | + builder_recipe = self.factory.makeRecipe(branch1, branch2) |
398 | sp_recipe = self.makeSourcePackageRecipeFromBuilderRecipe( |
399 | builder_recipe) |
400 | self.assertEquals( |
401 | @@ -114,11 +93,11 @@ |
402 | def test_random_user_cant_edit(self): |
403 | # An arbitrary user can't set attributes. |
404 | branch1 = self.factory.makeAnyBranch() |
405 | - builder_recipe1 = self.makeBuilderRecipe(branch1) |
406 | + builder_recipe1 = self.factory.makeRecipe(branch1) |
407 | sp_recipe = self.makeSourcePackageRecipeFromBuilderRecipe( |
408 | builder_recipe1) |
409 | branch2 = self.factory.makeAnyBranch() |
410 | - builder_recipe2 = self.makeBuilderRecipe(branch2) |
411 | + builder_recipe2 = self.factory.makeRecipe(branch2) |
412 | login_person(self.factory.makePerson()) |
413 | self.assertRaises( |
414 | Unauthorized, setattr, sp_recipe, 'builder_recipe', |
415 | @@ -128,11 +107,11 @@ |
416 | # When the recipe_text is replaced, getReferencedBranches returns |
417 | # (only) the branches referenced by the new recipe. |
418 | branch1 = self.factory.makeAnyBranch() |
419 | - builder_recipe1 = self.makeBuilderRecipe(branch1) |
420 | + builder_recipe1 = self.factory.makeRecipe(branch1) |
421 | sp_recipe = self.makeSourcePackageRecipeFromBuilderRecipe( |
422 | builder_recipe1) |
423 | branch2 = self.factory.makeAnyBranch() |
424 | - builder_recipe2 = self.makeBuilderRecipe(branch2) |
425 | + builder_recipe2 = self.factory.makeRecipe(branch2) |
426 | login_person(sp_recipe.owner.teamowner) |
427 | #import pdb; pdb.set_trace() |
428 | sp_recipe.builder_recipe = builder_recipe2 |
429 | @@ -152,7 +131,7 @@ |
430 | |
431 | def test_run_rejected_without_mangling_recipe(self): |
432 | branch1 = self.factory.makeAnyBranch() |
433 | - builder_recipe1 = self.makeBuilderRecipe(branch1) |
434 | + builder_recipe1 = self.factory.makeRecipe(branch1) |
435 | sp_recipe = self.makeSourcePackageRecipeFromBuilderRecipe( |
436 | builder_recipe1) |
437 | recipe_text = '''\ |
438 | @@ -169,12 +148,13 @@ |
439 | self.assertEquals([branch1], list(sp_recipe.getReferencedBranches())) |
440 | |
441 | def test_reject_newer_formats(self): |
442 | - builder_recipe = self.makeBuilderRecipe() |
443 | + builder_recipe = self.factory.makeRecipe() |
444 | builder_recipe.format = 0.3 |
445 | self.assertRaises( |
446 | TooNewRecipeFormat, |
447 | self.makeSourcePackageRecipeFromBuilderRecipe, builder_recipe) |
448 | |
449 | + |
450 | class TestRecipeBranchRoundTripping(TestCaseWithFactory): |
451 | |
452 | layer = DatabaseFunctionalLayer |
453 | @@ -364,7 +344,5 @@ |
454 | child_branch, "zam", self.merged_branch.bzr_identity, revspec="2") |
455 | |
456 | |
457 | - |
458 | def test_suite(): |
459 | return unittest.TestLoader().loadTestsFromName(__name__) |
460 | - |
461 | |
462 | === modified file 'lib/lp/testing/factory.py' |
463 | --- lib/lp/testing/factory.py 2010-01-05 00:53:47 +0000 |
464 | +++ lib/lp/testing/factory.py 2010-01-12 04:22:16 +0000 |
465 | @@ -22,6 +22,7 @@ |
466 | from itertools import count |
467 | from StringIO import StringIO |
468 | import os.path |
469 | +from textwrap import dedent |
470 | |
471 | import pytz |
472 | from storm.store import Store |
473 | @@ -40,6 +41,7 @@ |
474 | from lp.soyuz.adapters.packagelocation import PackageLocation |
475 | from lp.soyuz.interfaces.publishing import PackagePublishingStatus |
476 | from lp.soyuz.interfaces.section import ISectionSet |
477 | +from lp.soyuz.interfaces.sourcepackagerecipe import ISourcePackageRecipeSource |
478 | from canonical.launchpad.database.account import Account |
479 | from canonical.launchpad.database.emailaddress import EmailAddress |
480 | from canonical.launchpad.database.message import Message, MessageChunk |
481 | @@ -76,7 +78,7 @@ |
482 | from lp.translations.interfaces.translationgroup import ( |
483 | ITranslationGroupSet) |
484 | from lp.translations.interfaces.translator import ITranslatorSet |
485 | -from lp.translations.interfaces.translationsperson import ITranslationsPerson |
486 | +from lp.translations.interfaces.translationsperson import ITranslationsPerson |
487 | from canonical.launchpad.ftests._sqlobject import syncUpdate |
488 | from lp.services.mail.signedmessage import SignedMessage |
489 | from lp.services.worlddata.interfaces.country import ICountrySet |
490 | @@ -225,6 +227,12 @@ |
491 | for any other required objects. |
492 | """ |
493 | |
494 | + # Used for makeBuilderRecipe. |
495 | + MINIMAL_RECIPE_TEXT = dedent(u'''\ |
496 | + # bzr-builder format 0.2 deb-version 1.0 |
497 | + %s |
498 | + ''') |
499 | + |
500 | def makeCopyArchiveLocation(self, distribution=None, owner=None, |
501 | name=None, enabled=True): |
502 | """Create and return a new arbitrary location for copy packages.""" |
503 | @@ -511,7 +519,8 @@ |
504 | group = self.makeTranslationGroup() |
505 | if person is None: |
506 | person = self.makePerson() |
507 | - ITranslationsPerson(person).translations_relicensing_agreement = license |
508 | + tx_person = ITranslationsPerson(person) |
509 | + tx_person.translations_relicensing_agreement = license |
510 | return getUtility(ITranslatorSet).new(group, language, person) |
511 | |
512 | def makeMilestone( |
513 | @@ -946,7 +955,7 @@ |
514 | author = self.getUniqueString('author') |
515 | for index in range(count): |
516 | revision = revision_set.new( |
517 | - revision_id = self.getUniqueString('revision-id'), |
518 | + revision_id=self.getUniqueString('revision-id'), |
519 | log_body=self.getUniqueString('log-body'), |
520 | revision_date=date_generator.next(), |
521 | revision_author=author, |
522 | @@ -1552,6 +1561,41 @@ |
523 | processor, url, name, title, description, owner, active, |
524 | virtualized, vm_host) |
525 | |
526 | + def makeRecipe(self, *branches): |
527 | + """Make a builder recipe that references `branches`. |
528 | + |
529 | + If no branches are passed, return a recipe text that references an |
530 | + arbitrary branch. |
531 | + """ |
532 | + from bzrlib.plugins.builder.recipe import RecipeParser |
533 | + if len(branches) == 0: |
534 | + branches = (self.makeAnyBranch(),) |
535 | + base_branch = branches[0] |
536 | + other_branches = branches[1:] |
537 | + text = self.MINIMAL_RECIPE_TEXT % base_branch.bzr_identity |
538 | + for i, branch in enumerate(other_branches): |
539 | + text += 'merge dummy-%s %s\n' % (i, branch.bzr_identity) |
540 | + parser = RecipeParser(text) |
541 | + return parser.parse() |
542 | + |
543 | + def makeSourcePackageRecipe(self, registrant=None, owner=None, |
544 | + distroseries=None, sourcepackagename=None, |
545 | + name=None, *branches): |
546 | + """Make a `SourcePackageRecipe`.""" |
547 | + if registrant is None: |
548 | + registrant = self.makePerson() |
549 | + if owner is None: |
550 | + owner = self.makePerson() |
551 | + if distroseries is None: |
552 | + distroseries = self.makeDistroSeries() |
553 | + if sourcepackagename is None: |
554 | + sourcepackagename = self.makeSourcePackageName() |
555 | + if name is None: |
556 | + name = self.getUniqueString().decode('utf8') |
557 | + recipe = self.makeRecipe(*branches) |
558 | + return getUtility(ISourcePackageRecipeSource).new( |
559 | + registrant, owner, distroseries, sourcepackagename, name, recipe) |
560 | + |
561 | def makePOTemplate(self, productseries=None, distroseries=None, |
562 | sourcepackagename=None, owner=None, name=None, |
563 | translation_domain=None, path=None): |
564 | |
565 | === modified file 'standard_template.py' |
566 | --- standard_template.py 2010-01-01 04:02:51 +0000 |
567 | +++ standard_template.py 2010-01-12 04:22:16 +0000 |
568 | @@ -1,7 +1,7 @@ |
569 | # Copyright 2010 Canonical Ltd. This software is licensed under the |
570 | # GNU Affero General Public License version 3 (see the file LICENSE). |
571 | |
572 | -"""Module docstring goes here.""" |
573 | +"""XXX: Module docstring goes here.""" |
574 | |
575 | __metaclass__ = type |
576 | __all__ = [] |
577 | |
578 | === modified file 'standard_test_template.py' |
579 | --- standard_test_template.py 2010-01-01 04:02:51 +0000 |
580 | +++ standard_test_template.py 2010-01-12 04:22:16 +0000 |
581 | @@ -1,7 +1,7 @@ |
582 | # Copyright 2010 Canonical Ltd. This software is licensed under the |
583 | # GNU Affero General Public License version 3 (see the file LICENSE). |
584 | |
585 | -"""Module docstring goes here.""" |
586 | +"""XXX: Module docstring goes here.""" |
587 | |
588 | __metaclass__ = type |
589 | |
590 | @@ -12,4 +12,3 @@ |
591 | |
592 | def test_suite(): |
593 | return unittest.TestLoader().loadTestsFromName(__name__) |
594 | - |
This branch adds model code for the SourcePackageBuild table. That's pretty much it.