Merge lp:~jtv/launchpad/translationtemplatesbuild into lp:launchpad/db-devel

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 9793
Proposed branch: lp:~jtv/launchpad/translationtemplatesbuild
Merge into: lp:launchpad/db-devel
Diff against target: 423 lines (+242/-23)
12 files modified
database/schema/comments.sql (+5/-0)
database/schema/patch-2208-99-0.sql (+17/-0)
database/schema/security.cfg (+2/-0)
lib/lp/buildmaster/model/buildfarmjob.py (+1/-1)
lib/lp/code/doc/branch.txt (+1/-0)
lib/lp/code/model/branch.py (+9/-7)
lib/lp/translations/configure.zcml (+11/-0)
lib/lp/translations/interfaces/translationtemplatesbuild.py (+39/-0)
lib/lp/translations/model/translationtemplatesbuild.py (+71/-0)
lib/lp/translations/model/translationtemplatesbuildbehavior.py (+4/-2)
lib/lp/translations/model/translationtemplatesbuildjob.py (+16/-13)
lib/lp/translations/tests/test_translationtemplatesbuild.py (+66/-0)
To merge this branch: bzr merge lp:~jtv/launchpad/translationtemplatesbuild
Reviewer Review Type Date Requested Status
Stuart Bishop (community) db Approve
Michael Nelson (community) code Approve
Robert Collins db Pending
Review via email: mp+34952@code.launchpad.net

Commit message

TranslationTemplatesBuild.

Description of the change

= TranslationTemplatesBuild =

Buildfarm work. This creates a new TranslationTemplatesBuild class, which holds a reference to BuildFarmJob as per…

    http://people.ubuntu.com/~wgrant/launchpad/buildfarm/new-build-model-again.png

Until we actually move over to the new data model, the TranslationTemplatesBuild objects are created from the factory for the old TranslationTemplatesBuildJob. I also create the BuildFarmJob object in there, as I've seen in other build classes; we may want to move that into the TranslationTemplatesBuild factory later but doing it this way should maximize our flexibility if someone else entirely is (or will be) responsible for creating them.

The big picture I may still be missing is who's responsible for creating what objects. Implementing makeJob for the old-style setup triggered some upheaval in the TranslationTemplatesBuildJob factory, and now I'm not sure the BuildQueue is created in the right place, the specific job isn't being created redundantly elsewhere, etc.

Jeroen

To post a comment you must log in.
Revision history for this message
Michael Nelson (michael.nelson) wrote :

We did this review from a paste while LP was down. In summary, r=me assuming you'll not land this until you've got a second branch that ensures the builder (current builds/history) pages display these correctly (ie. you'll need to ensure BFJ.getSpecificJob() finds the appropriate adapted.

Thanks!

10:09 < jtv> noodles775: thanks for the review btw… I _would_ point you to my buildfarm work now, but Maintenance. :
/
10:10 * noodles775 breathes a sigh of relief ;)
10:11 < noodles775> jtv: if you can paste your MP (and a diff), I can do that too :)
10:13 < jtv> noodles775: the MP is at https://code.edge.launchpad.net/~jtv/launchpad/translationtemplatesbuild/+merge
/34952
10:13 < noodles775> jtv: sorry, I meant paste the text of your MP to paste.....com :)
10:13 < jtv> noodles775: yes, I'm otp so a little slow sorry :)
10:22 < jtv> noodles775: my diff is here: http://paste.ubuntu.com/490815/
10:31 < noodles775> jtv: Was that a decision to allow both interfaces for TranslationTemplateBuild via ZCML (rather t
han having ITranslationTemplatesBuild inherit from IBuildFarmJob - like IPackageBuild does)?
10:32 < jtv> noodles775: barely registered. :) I tend to avoid interface hierarchies because they can get a little confusing in combination with class hierarchies, but if that's wrong I'll happily change it.
10:32 < jtv> (not that zcml can't get a little confusing…)
10:33 < noodles775> I'm not sure if its better or worse... I think of it with the question: Is the interface ITranslationTemplatesBuild also an IBuildFarmJob? I'm not fussed either, I was just surprised.
10:34 < jtv> We're sort of probing the boundaries between is-a and has-a here, aren't we?
10:35 < jtv> I guess in python we're doing inheritance, just not in the db—in which case perhaps I should change this after all.
11:09 < noodles775> jtv: sheesh, it'll be nice to get rid of the BFJOld stuff (and makeJob). A question, in your makeJob() method, you don't add the TTBJ to the store... am I missing something? I'm wondering if you meant to call TTBJ.create() there?
11:10 < jtv> noodles775: ah good point, thanks
11:11 < jtv> noodles775: ah! Actually I do add it to the store.
11:11 < jtv> noodles775: in terms of db storage, the BranchJob _is_ the TTBJ
11:31 < noodles775> jtv: ah, so TTBJ isn't a storm class itself. Right.
11:31 < jtv> just one more reason to clean out these stables :)
11:41 < noodles775> jtv: so r=me, assuming that you won't be landing this without further branches (ie. to ensure BFJ.getSpecificJob() works for TranslationTemplatesBuild.
11:41 < noodles775> Thanks!
11:42 < jtv> noodles775: that's actually a lot more than I was hoping for, thanks! Any other points I need to cover?
11:43 < noodles775> jtv: er, you could refactor the code and get rid of IBuildFarmJobOld? ;)
11:44 < noodles775> I can't think of any other things... the above will make it self apparent when you look at current builders or builder histories after having dispatched TTBs.
11:45 < noodles775> (sorry, where "the above" is ensuring BFJ.getSpecificJob() works for the translation template builds)
11:45 < jtv> OK, so I'll move on to that next then.

review: Approve (code)
Revision history for this message
Stuart Bishop (stub) wrote :

Fine. Our naming 'standards' don't quite cope with this table, so I'll let it pass (TranslationTemplatesBuild vs. TranslationTemplateBuild).

patch-2208-13-0.sql

review: Approve (db)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'database/schema/comments.sql'
2--- database/schema/comments.sql 2010-09-09 16:53:16 +0000
3+++ database/schema/comments.sql 2010-09-10 11:48:51 +0000
4@@ -839,6 +839,11 @@
5 COMMENT ON COLUMN TranslationRelicensingAgreement.allow_relicensing IS 'Does this person want their translations relicensed under BSD.';
6 COMMENT ON COLUMN TranslationRelicensingAgreement.date_decided IS 'Date when the last change of opinion was registered.';
7
8+-- TranslationTemplatesBuild
9+COMMENT ON TABLE TranslationTemplatesBuild IS 'Build-farm record of a translation templates build.';
10+COMMENT ON COLUMN TranslationTemplatesBuild.build_farm_job IS 'Associated BuildFarmJob.';
11+COMMENT ON COLUMN TranslationTemplatesBuild.branch IS 'Branch to build templates out of.';
12+
13 -- RevisionAuthor
14 COMMENT ON TABLE RevisionAuthor IS 'All distinct authors for revisions.';
15 COMMENT ON COLUMN RevisionAuthor.name IS 'The exact text extracted from the branch revision.';
16
17=== added file 'database/schema/patch-2208-99-0.sql'
18--- database/schema/patch-2208-99-0.sql 1970-01-01 00:00:00 +0000
19+++ database/schema/patch-2208-99-0.sql 2010-09-10 11:48:51 +0000
20@@ -0,0 +1,17 @@
21+-- Copyright 2010 Canonical Ltd. This software is licensed under the
22+-- GNU Affero General Public License version 3 (see the file LICENSE).
23+
24+SET client_min_messages=ERROR;
25+
26+CREATE TABLE TranslationTemplatesBuild (
27+ id SERIAL PRIMARY KEY,
28+ build_farm_job integer NOT NULL REFERENCES BuildFarmJob(id),
29+ branch integer NOT NULL REFERENCES Branch(id));
30+
31+CREATE INDEX translationtemplatesbuild__build_farm_job__idx ON
32+ TranslationTemplatesBuild(build_farm_job);
33+
34+CREATE INDEX translationtemplatesbuild__branch__idx ON
35+ TranslationTemplatesBuild(branch);
36+
37+INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 99, 0);
38
39=== modified file 'database/schema/security.cfg'
40--- database/schema/security.cfg 2010-09-10 02:46:28 +0000
41+++ database/schema/security.cfg 2010-09-10 11:48:51 +0000
42@@ -276,6 +276,7 @@
43 public.translationgroup = SELECT, INSERT, UPDATE
44 public.translationimportqueueentry = SELECT, INSERT, UPDATE, DELETE
45 public.translationmessage = SELECT, INSERT, UPDATE
46+public.translationtemplatesbuild = SELECT, INSERT, DELETE
47 public.translator = SELECT, INSERT, UPDATE, DELETE
48 public.usertouseremail = SELECT, UPDATE
49 public.validpersoncache = SELECT
50@@ -1436,6 +1437,7 @@
51 [translationsbranchscanner]
52 type=user
53 groups=branchscanner,translations_approval
54+public.translationtemplatesbuild = SELECT, INSERT
55
56 [translationstobranch]
57 type=user
58
59=== modified file 'lib/lp/buildmaster/model/buildfarmjob.py'
60--- lib/lp/buildmaster/model/buildfarmjob.py 2010-08-30 15:00:23 +0000
61+++ lib/lp/buildmaster/model/buildfarmjob.py 2010-09-10 11:48:51 +0000
62@@ -272,7 +272,7 @@
63 return self.date_finished - self.date_started
64
65 def makeJob(self):
66- """See `IBuildFarmJob`."""
67+ """See `IBuildFarmJobOld`."""
68 raise NotImplementedError
69
70 def jobStarted(self):
71
72=== modified file 'lib/lp/code/doc/branch.txt'
73--- lib/lp/code/doc/branch.txt 2010-07-26 09:15:31 +0000
74+++ lib/lp/code/doc/branch.txt 2010-09-10 11:48:51 +0000
75@@ -379,6 +379,7 @@
76 sourcepackagerecipedata.base_branch
77 sourcepackagerecipedatainstruction.branch
78 specificationbranch.branch
79+ translationtemplatesbuild.branch
80
81 (Unfortunately, references can form a cycle-- note that codereviewcomments
82 aren't shown.)
83
84=== modified file 'lib/lp/code/model/branch.py'
85--- lib/lp/code/model/branch.py 2010-09-03 11:54:23 +0000
86+++ lib/lp/code/model/branch.py 2010-09-10 11:48:51 +0000
87@@ -26,7 +26,6 @@
88 And,
89 Count,
90 Desc,
91- Max,
92 NamedFunc,
93 Not,
94 Or,
95@@ -59,11 +58,6 @@
96 IPrivacy,
97 )
98 from canonical.launchpad.webapp import urlappend
99-from canonical.launchpad.webapp.interfaces import (
100- IStoreSelector,
101- MAIN_STORE,
102- SLAVE_FLAVOR,
103- )
104 from lp.app.errors import UserCannotUnsubscribePerson
105 from lp.buildmaster.model.buildqueue import BuildQueue
106 from lp.code.bzr import (
107@@ -1023,10 +1017,14 @@
108 """Delete jobs for this branch prior to deleting branch.
109
110 This deletion includes `BranchJob`s associated with the branch,
111- as well as `BuildQueue` entries for `TranslationTemplateBuildJob`s.
112+ as well as `BuildQueue` entries for `TranslationTemplateBuildJob`s
113+ and `TranslationTemplateBuild`s.
114 """
115 # Avoid circular imports.
116 from lp.code.model.branchjob import BranchJob
117+ from lp.translations.model.translationtemplatesbuild import (
118+ TranslationTemplatesBuild,
119+ )
120
121 store = Store.of(self)
122 affected_jobs = Select(
123@@ -1040,6 +1038,10 @@
124 # Delete Jobs. Their BranchJobs cascade along in the database.
125 store.find(Job, Job.id.is_in(affected_jobs)).remove()
126
127+ store.find(
128+ TranslationTemplatesBuild,
129+ TranslationTemplatesBuild.branch == self).remove()
130+
131 def destroySelf(self, break_references=False):
132 """See `IBranch`."""
133 from lp.code.interfaces.branchjob import IReclaimBranchSpaceJobSource
134
135=== modified file 'lib/lp/translations/configure.zcml'
136--- lib/lp/translations/configure.zcml 2010-08-19 02:11:43 +0000
137+++ lib/lp/translations/configure.zcml 2010-09-10 11:48:51 +0000
138@@ -610,6 +610,17 @@
139 provides="lp.buildmaster.interfaces.buildfarmjob.IBuildFarmJob"
140 name="TRANSLATIONTEMPLATESBUILD"/>
141
142+ <!-- TranslationTemplatesBuild -->
143+ <class
144+ class="lp.translations.model.translationtemplatesbuild.TranslationTemplatesBuild">
145+ <allow interface="lp.translations.interfaces.translationtemplatesbuild.ITranslationTemplatesBuild"/>
146+ </class>
147+ <securedutility
148+ component="lp.translations.model.translationtemplatesbuild.TranslationTemplatesBuild"
149+ provides="lp.translations.interfaces.translationtemplatesbuild.ITranslationTemplatesBuildSource">
150+ <allow interface="lp.translations.interfaces.translationtemplatesbuild.ITranslationTemplatesBuildSource"/>
151+ </securedutility>
152+
153 <!-- TranslationTemplateBuildBehavior -->
154 <class
155 class="lp.translations.model.translationtemplatesbuildbehavior.TranslationTemplatesBuildBehavior">
156
157=== added file 'lib/lp/translations/interfaces/translationtemplatesbuild.py'
158--- lib/lp/translations/interfaces/translationtemplatesbuild.py 1970-01-01 00:00:00 +0000
159+++ lib/lp/translations/interfaces/translationtemplatesbuild.py 2010-09-10 11:48:51 +0000
160@@ -0,0 +1,39 @@
161+# Copyright 2010 Canonical Ltd. This software is licensed under the
162+# GNU Affero General Public License version 3 (see the file LICENSE).
163+
164+"""Interface and utility for `TranslationTemplatesBuild`."""
165+
166+__metaclass__ = type
167+__all__ = [
168+ 'ITranslationTemplatesBuild',
169+ 'ITranslationTemplatesBuildSource',
170+ ]
171+
172+from lazr.restful.fields import Reference
173+from zope.interface import Interface
174+
175+from canonical.launchpad import _
176+from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJob
177+from lp.code.interfaces.branch import IBranch
178+
179+
180+class ITranslationTemplatesBuild(IBuildFarmJob):
181+ """The build information for translation templates builds."""
182+
183+ build_farm_job = Reference(
184+ title=_("The build farm job that this extends."),
185+ required=True, readonly=True, schema=IBuildFarmJob)
186+
187+ branch = Reference(
188+ title=_("The branch that this build operates on."),
189+ required=True, readonly=True, schema=IBranch)
190+
191+
192+class ITranslationTemplatesBuildSource(Interface):
193+ """Utility for `ITranslationTemplatesBuild`."""
194+
195+ def create(build_farm_job, branch):
196+ """Create a new `ITranslationTemplatesBuild`."""
197+
198+ def findByBranch(branch):
199+ """Find `ITranslationTemplatesBuild`s for `branch`."""
200
201=== added file 'lib/lp/translations/model/translationtemplatesbuild.py'
202--- lib/lp/translations/model/translationtemplatesbuild.py 1970-01-01 00:00:00 +0000
203+++ lib/lp/translations/model/translationtemplatesbuild.py 2010-09-10 11:48:51 +0000
204@@ -0,0 +1,71 @@
205+# Copyright 2010 Canonical Ltd. This software is licensed under the
206+# GNU Affero General Public License version 3 (see the file LICENSE).
207+
208+"""`TranslationTemplatesBuild` class."""
209+
210+__metaclass__ = type
211+__all__ = [
212+ 'TranslationTemplatesBuild',
213+ ]
214+
215+from storm.locals import (
216+ Int,
217+ Reference,
218+ Storm,
219+ )
220+from zope.interface import (
221+ classProvides,
222+ implements,
223+ )
224+
225+from canonical.launchpad.interfaces.lpstorm import IMasterStore
226+from lp.buildmaster.model.buildfarmjob import BuildFarmJobDerived
227+from lp.code.model.branchjob import (
228+ BranchJob,
229+ BranchJobType,
230+ )
231+from lp.translations.interfaces.translationtemplatesbuild import (
232+ ITranslationTemplatesBuild,
233+ ITranslationTemplatesBuildSource,
234+ )
235+from lp.translations.model.translationtemplatesbuildjob import (
236+ TranslationTemplatesBuildJob,
237+ )
238+
239+
240+class TranslationTemplatesBuild(BuildFarmJobDerived, Storm):
241+ """A `BuildFarmJob` extension for translation templates builds."""
242+
243+ implements(ITranslationTemplatesBuild)
244+ classProvides(ITranslationTemplatesBuildSource)
245+
246+ __storm_table__ = 'TranslationTemplatesBuild'
247+
248+ id = Int(primary=True)
249+ build_farm_job_id = Int(name='build_farm_job', allow_none=False)
250+ build_farm_job = Reference(build_farm_job_id, 'BuildFarmJob.id')
251+ branch_id = Int(name='branch', allow_none=False)
252+ branch = Reference(branch_id, 'Branch.id')
253+
254+ def __init__(self, build_farm_job, branch):
255+ super(TranslationTemplatesBuild, self).__init__()
256+ self.build_farm_job = build_farm_job
257+ self.branch = branch
258+
259+ @classmethod
260+ def create(self, build_farm_job, branch):
261+ """See `ITranslationTemplatesBuildSource`."""
262+ build = TranslationTemplatesBuild(build_farm_job, branch)
263+ IMasterStore(TranslationTemplatesBuild).add(build)
264+ return build
265+
266+ def makeJob(self):
267+ """See `IBuildFarmJobOld`."""
268+ store = IMasterStore(BranchJob)
269+
270+ # Pass public HTTP URL for the branch.
271+ metadata = {'branch_url': self.branch.composePublicURL()}
272+ branch_job = BranchJob(
273+ self.branch, BranchJobType.TRANSLATION_TEMPLATES_BUILD, metadata)
274+ store.add(branch_job)
275+ return TranslationTemplatesBuildJob(branch_job)
276
277=== modified file 'lib/lp/translations/model/translationtemplatesbuildbehavior.py'
278--- lib/lp/translations/model/translationtemplatesbuildbehavior.py 2010-08-20 20:31:18 +0000
279+++ lib/lp/translations/model/translationtemplatesbuildbehavior.py 2010-09-10 11:48:51 +0000
280@@ -44,8 +44,10 @@
281 self._builder.slave.cacheFile(logger, chroot)
282 cookie = self.buildfarmjob.generateSlaveBuildCookie()
283
284- args = {'arch_tag': self._getDistroArchSeries().architecturetag}
285- args.update(self.buildfarmjob.metadata)
286+ args = {
287+ 'arch_tag': self._getDistroArchSeries().architecturetag,
288+ 'branch_url': self.buildfarmjob.branch.composePublicURL(),
289+ }
290
291 filemap = {}
292
293
294=== modified file 'lib/lp/translations/model/translationtemplatesbuildjob.py'
295--- lib/lp/translations/model/translationtemplatesbuildjob.py 2010-08-27 15:03:18 +0000
296+++ lib/lp/translations/model/translationtemplatesbuildjob.py 2010-09-10 11:48:51 +0000
297@@ -25,6 +25,7 @@
298 )
299 from lp.buildmaster.enums import BuildFarmJobType
300 from lp.buildmaster.interfaces.buildfarmbranchjob import IBuildFarmBranchJob
301+from lp.buildmaster.interfaces.buildfarmjob import IBuildFarmJobSource
302 from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet
303 from lp.buildmaster.model.buildfarmjob import (
304 BuildFarmJobOld,
305@@ -37,6 +38,9 @@
306 BranchJobDerived,
307 BranchJobType,
308 )
309+from lp.translations.interfaces.translationtemplatesbuild import (
310+ ITranslationTemplatesBuildSource,
311+ )
312 from lp.translations.interfaces.translationtemplatesbuildjob import (
313 ITranslationTemplatesBuildJobSource,
314 )
315@@ -128,25 +132,24 @@
316 @classmethod
317 def create(cls, branch):
318 """See `ITranslationTemplatesBuildJobSource`."""
319- store = IMasterStore(BranchJob)
320-
321- # Pass public HTTP URL for the branch.
322- metadata = {'branch_url': branch.composePublicURL()}
323- branch_job = BranchJob(
324- branch, BranchJobType.TRANSLATION_TEMPLATES_BUILD, metadata)
325- store.add(branch_job)
326- specific_job = TranslationTemplatesBuildJob(branch_job)
327- duration_estimate = cls.duration_estimate
328-
329 # XXX Danilo Segan bug=580429: we hard-code processor to the Ubuntu
330 # default processor architecture. This stops the buildfarm from
331 # accidentally dispatching the jobs to private builders.
332+ processor = cls._getBuildArch()
333+
334+ build_farm_job = getUtility(IBuildFarmJobSource).new(
335+ BuildFarmJobType.TRANSLATIONTEMPLATESBUILD, processor=processor)
336+ build = getUtility(ITranslationTemplatesBuildSource).create(
337+ build_farm_job, branch)
338+
339+ specific_job = build.makeJob()
340+ duration_estimate = cls.duration_estimate
341+
342 build_queue_entry = BuildQueue(
343 estimated_duration=duration_estimate,
344 job_type=BuildFarmJobType.TRANSLATIONTEMPLATESBUILD,
345- job=specific_job.job.id,
346- processor=cls._getBuildArch())
347- store.add(build_queue_entry)
348+ job=specific_job.job, processor=processor)
349+ IMasterStore(BuildQueue).add(build_queue_entry)
350
351 return specific_job
352
353
354=== added file 'lib/lp/translations/tests/test_translationtemplatesbuild.py'
355--- lib/lp/translations/tests/test_translationtemplatesbuild.py 1970-01-01 00:00:00 +0000
356+++ lib/lp/translations/tests/test_translationtemplatesbuild.py 2010-09-10 11:48:51 +0000
357@@ -0,0 +1,66 @@
358+# Copyright 2010 Canonical Ltd. This software is licensed under the
359+# GNU Affero General Public License version 3 (see the file LICENSE).
360+
361+"""`TranslationTemplatesBuild` tests."""
362+
363+__metaclass__ = type
364+
365+from storm.store import Store
366+from zope.component import getUtility
367+from zope.interface.verify import verifyObject
368+
369+from canonical.testing import DatabaseFunctionalLayer
370+from lp.buildmaster.enums import BuildFarmJobType
371+from lp.buildmaster.interfaces.buildfarmjob import (
372+ IBuildFarmJob,
373+ IBuildFarmJobSource,
374+ )
375+from lp.testing import TestCaseWithFactory
376+from lp.translations.interfaces.translationtemplatesbuild import (
377+ ITranslationTemplatesBuild,
378+ ITranslationTemplatesBuildSource,
379+ )
380+from lp.translations.model.translationtemplatesbuild import (
381+ TranslationTemplatesBuild,
382+ )
383+from lp.translations.interfaces.translationtemplatesbuildjob import (
384+ ITranslationTemplatesBuildJobSource,
385+ )
386+
387+
388+class TestTranslationTemplatesBuild(TestCaseWithFactory):
389+
390+ layer = DatabaseFunctionalLayer
391+
392+ def _findBuildForBranch(self, branch):
393+ """Find the `TranslationTemplatesBuild` for `branch`, if any."""
394+ return Store.of(branch).find(
395+ TranslationTemplatesBuild,
396+ TranslationTemplatesBuild.branch == branch).one()
397+
398+ def _makeBuildFarmJob(self):
399+ """Create a `BuildFarmJob` for testing."""
400+ source = getUtility(IBuildFarmJobSource)
401+ return source.new(BuildFarmJobType.TRANSLATIONTEMPLATESBUILD)
402+
403+ def test_baseline(self):
404+ source = getUtility(ITranslationTemplatesBuildSource)
405+ branch = self.factory.makeBranch()
406+ build_farm_job = self._makeBuildFarmJob()
407+
408+ build = source.create(build_farm_job, branch)
409+
410+ self.assertTrue(verifyObject(ITranslationTemplatesBuild, build))
411+ self.assertTrue(verifyObject(IBuildFarmJob, build))
412+ self.assertEqual(build_farm_job, build.build_farm_job)
413+ self.assertEqual(branch, build.branch)
414+
415+ def test_created_by_buildjobsource(self):
416+ # ITranslationTemplatesBuildJobSource.create also creates a
417+ # TranslationTemplatesBuild. This utility will become obsolete
418+ # later.
419+ jobset = getUtility(ITranslationTemplatesBuildJobSource)
420+ branch = self.factory.makeBranch()
421+
422+ translationtemplatesbuildjob = jobset.create(branch)
423+ self.assertNotEqual(None, self._findBuildForBranch(branch))

Subscribers

People subscribed via source and target branches

to status/vote changes: