Merge lp:~rockstar/launchpad/branch-scan-job-script into lp:launchpad/db-devel

Proposed by Paul Hummer on 2010-01-14
Status: Merged
Approved by: Tim Penhey on 2010-01-14
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~rockstar/launchpad/branch-scan-job-script
Merge into: lp:launchpad/db-devel
Diff against target: 287 lines (+136/-24)
10 files modified
Makefile (+1/-1)
cronscripts/scan_branches.py (+25/-0)
cronscripts/upgrade_branches.py (+1/-1)
lib/lp/code/configure.zcml (+9/-0)
lib/lp/code/interfaces/branchjob.py (+6/-22)
lib/lp/code/model/branch.py (+2/-0)
lib/lp/code/model/branchjob.py (+11/-0)
lib/lp/code/model/tests/test_branch.py (+12/-0)
lib/lp/code/scripts/tests/test_scan_branches.py (+59/-0)
lib/lp/services/job/interfaces/job.py (+10/-0)
To merge this branch: bzr merge lp:~rockstar/launchpad/branch-scan-job-script
Reviewer Review Type Date Requested Status
Tim Penhey (community) 2010-01-14 Approve on 2010-01-14
Review via email: mp+17429@code.launchpad.net
To post a comment you must log in.
Paul Hummer (rockstar) wrote :

Hello there Tim sir-

  This branch adds the cron script that finds and runs all the BranchScanJobs,
and its accompanying tests. It also adds the creation of these BranchScanJobs
to IBranch.mirrorComplete, and has it accompanying tests as well.

Cheers,
Paul

Tim Penhey (thumper) wrote :

I'd like to see the Makefile updated for sync_branches to use this script.

review: Needs Fixing
Tim Penhey (thumper) wrote :

Land it!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2010-01-11 20:57:16 +0000
3+++ Makefile 2010-01-14 23:48:14 +0000
4@@ -218,7 +218,7 @@
5
6 scan_branches:
7 # Scan branches from the filesystem into the database.
8- $(PY) cronscripts/branch-scanner.py
9+ $(PY) cronscripts/scan_branches.py
10
11
12 sync_branches: pull_branches scan_branches mpcreationjobs
13
14=== added file 'cronscripts/scan_branches.py'
15--- cronscripts/scan_branches.py 1970-01-01 00:00:00 +0000
16+++ cronscripts/scan_branches.py 2010-01-14 23:48:14 +0000
17@@ -0,0 +1,25 @@
18+#!/usr/bin/python2.5
19+#
20+# Copyright 2010 Canonical Ltd. This software is licensed under the
21+# GNU Affero General Public License version 3 (see the file LICENSE).
22+
23+"""Scan branches for new revisions."""
24+
25+__metaclass__ = type
26+
27+import _pythonpath
28+
29+from lp.services.job.runner import JobCronScript
30+from lp.code.interfaces.branchjob import IBranchScanJobSource
31+
32+
33+class RunScanBranches(JobCronScript):
34+ """Run BranchScanJob jobs."""
35+
36+ config_name = 'branchscanner'
37+ source_interface = IBranchScanJobSource
38+
39+
40+if __name__ == '__main__':
41+ script = RunScanBranches()
42+ script.lock_and_run()
43
44=== modified file 'cronscripts/upgrade_branches.py'
45--- cronscripts/upgrade_branches.py 2009-12-10 18:46:14 +0000
46+++ cronscripts/upgrade_branches.py 2010-01-14 23:48:14 +0000
47@@ -14,7 +14,7 @@
48
49
50 class RunUpgradeBranches(JobCronScript):
51- """Run UpdatePreviewDiff jobs."""
52+ """Run UpgradeBranchJob jobs."""
53
54 config_name = 'upgrade_branches'
55 source_interface = IBranchUpgradeJobSource
56
57=== modified file 'lib/lp/code/configure.zcml'
58--- lib/lp/code/configure.zcml 2010-01-11 04:22:01 +0000
59+++ lib/lp/code/configure.zcml 2010-01-14 23:48:14 +0000
60@@ -901,6 +901,15 @@
61 <allow interface="lp.services.job.interfaces.job.IRunnableJob" />
62 </class>
63
64+ <securedutility
65+ component="lp.code.model.branchjob.BranchScanJob"
66+ provides="lp.code.interfaces.branchjob.IBranchScanJobSource">
67+ <allow interface="lp.code.interfaces.branchjob.IBranchScanJobSource"/>
68+ </securedutility>
69+ <class class="lp.code.model.branchjob.BranchScanJob">
70+ <allow interface="lp.services.job.interfaces.job.IRunnableJob" />
71+ </class>
72+
73 <!-- Linked branches -->
74 <adapter factory="lp.code.model.linkedbranch.ProductSeriesLinkedBranch" />
75 <adapter factory="lp.code.model.linkedbranch.ProductLinkedBranch" />
76
77=== modified file 'lib/lp/code/interfaces/branchjob.py'
78--- lib/lp/code/interfaces/branchjob.py 2010-01-13 02:44:21 +0000
79+++ lib/lp/code/interfaces/branchjob.py 2010-01-14 23:48:14 +0000
80@@ -33,7 +33,7 @@
81
82 from canonical.launchpad import _
83 from lp.code.interfaces.branch import IBranch
84-from lp.services.job.interfaces.job import IJob, IRunnableJob
85+from lp.services.job.interfaces.job import IJob, IRunnableJob, IJobSource
86
87
88 class IBranchJob(Interface):
89@@ -76,14 +76,11 @@
90 """
91
92
93-class IBranchScanJob(Interface):
94+class IBranchScanJob(IRunnableJob):
95 """ A job to scan branches."""
96
97- def run():
98- """Scan a branch for new revisions."""
99-
100-
101-class IBranchScanJobSource(Interface):
102+
103+class IBranchScanJobSource(IJobSource):
104
105 def create(branch):
106 """Scan a branch for new revisions.
107@@ -91,18 +88,11 @@
108 :param branch: The database branch to upgrade.
109 """
110
111- def iterReady():
112- """Iterate through all IBranchScanJobs."""
113-
114-
115 class IBranchUpgradeJob(IRunnableJob):
116 """A job to upgrade branches with out-of-date formats."""
117
118- def run():
119- """Upgrade the branch to the format specified."""
120-
121-
122-class IBranchUpgradeJobSource(Interface):
123+
124+class IBranchUpgradeJobSource(IJobSource):
125
126 def create(branch):
127 """Upgrade a branch to a more current format.
128@@ -110,12 +100,6 @@
129 :param branch: The database branch to upgrade.
130 """
131
132- def iterReady():
133- """Iterate through all IBranchUpgradeJobs."""
134-
135- def contextManager():
136- """Get a context for running this kind of job in."""
137-
138
139 class IRevisionMailJob(IRunnableJob):
140 """A Job to send email a revision change in a branch."""
141
142=== modified file 'lib/lp/code/model/branch.py'
143--- lib/lp/code/model/branch.py 2010-01-12 21:37:34 +0000
144+++ lib/lp/code/model/branch.py 2010-01-14 23:48:14 +0000
145@@ -929,6 +929,8 @@
146 self.next_mirror_time = (
147 datetime.now(pytz.timezone('UTC')) + increment)
148 self.last_mirrored_id = last_revision_id
149+ from lp.code.model.branchjob import BranchScanJob
150+ BranchScanJob.create(self)
151
152 def mirrorFailed(self, reason):
153 """See `IBranch`."""
154
155=== modified file 'lib/lp/code/model/branchjob.py'
156--- lib/lp/code/model/branchjob.py 2010-01-13 05:37:02 +0000
157+++ lib/lp/code/model/branchjob.py 2010-01-14 23:48:14 +0000
158@@ -3,6 +3,7 @@
159
160 __all__ = [
161 'BranchJob',
162+ 'BranchScanJob',
163 'BranchUpgradeJob',
164 'RevisionsAddedJob',
165 'RevisionMailJob',
166@@ -275,6 +276,16 @@
167 bzrsync = BzrSync(self.branch)
168 bzrsync.syncBranchAndClose()
169
170+ @staticmethod
171+ @contextlib.contextmanager
172+ def contextManager():
173+ """See `IBranchScanJobSource`."""
174+ errorlog.globalErrorUtility.configure('branchscanner')
175+ server = get_multi_server()
176+ server.setUp()
177+ yield
178+ server.tearDown()
179+
180
181 class BranchUpgradeJob(BranchJobDerived):
182 """A Job that upgrades branches to the current stable format."""
183
184=== modified file 'lib/lp/code/model/tests/test_branch.py'
185--- lib/lp/code/model/tests/test_branch.py 2010-01-07 06:37:14 +0000
186+++ lib/lp/code/model/tests/test_branch.py 2010-01-14 23:48:14 +0000
187@@ -1433,6 +1433,18 @@
188 branch.mirrorComplete(rev_id)
189 self.assertEqual(True, branch.pending_writes)
190
191+ def test_mirrorComplete_creates_scan_job(self):
192+ # After a branch has been pulled, it should have created a
193+ # BranchScanJob to complete the process.
194+ branch = self.factory.makeAnyBranch()
195+ branch.startMirroring()
196+ rev_id = self.factory.getUniqueString('rev-id')
197+ branch.mirrorComplete(rev_id)
198+
199+ store = Store.of(branch)
200+ scan_jobs = store.find(BranchJob, job_type=BranchJobType.SCAN_BRANCH)
201+ self.assertEqual(scan_jobs.count(), 1)
202+
203 def test_pulled_and_scanned(self):
204 # If a branch has been pulled and scanned, then there are no pending
205 # writes.
206
207=== added file 'lib/lp/code/scripts/tests/test_scan_branches.py'
208--- lib/lp/code/scripts/tests/test_scan_branches.py 1970-01-01 00:00:00 +0000
209+++ lib/lp/code/scripts/tests/test_scan_branches.py 2010-01-14 23:48:14 +0000
210@@ -0,0 +1,59 @@
211+#! /usr/bin/python2.5
212+#
213+# Copyright 2010 Canonical Ltd. This software is licensed under the
214+# GNU Affero General Public License version 3 (see the file LICENSE).
215+
216+"""Test the scan_branches script."""
217+
218+
219+import transaction
220+
221+from canonical.testing import ZopelessAppServerLayer
222+from lp.testing import TestCaseWithFactory
223+from canonical.launchpad.scripts.tests import run_script
224+from lp.code.model.branchjob import BranchScanJob
225+
226+
227+class TestScanBranches(TestCaseWithFactory):
228+ """Test the scan_branches script."""
229+
230+ layer = ZopelessAppServerLayer
231+
232+ def make_branch_with_commits_and_scan_job(self, db_branch):
233+ """Create a branch from a db_branch, make commits and a scan job."""
234+ target, target_tree = self.create_branch_and_tree(
235+ db_branch=db_branch)
236+ target_tree.commit('First commit', rev_id='rev1')
237+ target_tree.commit('Second commit', rev_id='rev2')
238+ target_tree.commit('Third commit', rev_id='rev3')
239+ job = BranchScanJob.create(db_branch)
240+ transaction.commit()
241+
242+ def run_script_and_assert_success(self):
243+ """Run the scan_branches script and assert it ran successfully."""
244+ retcode, stdout, stderr = run_script(
245+ 'cronscripts/scan_branches.py', [],
246+ expect_returncode=0)
247+ self.assertEqual('', stdout)
248+ self.assertIn(
249+ 'INFO Ran 1 IBranchScanJobSource jobs.\n', stderr)
250+
251+ def test_scan_branch(self):
252+ """Test that scan branches adds revisions to the database."""
253+ self.useBzrBranches(real_server=True)
254+
255+ db_branch = self.factory.makeAnyBranch()
256+ self.make_branch_with_commits_and_scan_job(db_branch)
257+
258+ self.run_script_and_assert_success()
259+ self.assertEqual(db_branch.revision_count, 3)
260+
261+ def test_scan_branch_packagebranch(self):
262+ """Test that scan_branches can scan package branches."""
263+ self.useBzrBranches(real_server=True)
264+
265+ db_branch = self.factory.makePackageBranch()
266+ self.make_branch_with_commits_and_scan_job(db_branch)
267+
268+ self.run_script_and_assert_success()
269+ self.assertEqual(db_branch.revision_count, 3)
270
271=== modified file 'lib/lp/services/job/interfaces/job.py'
272--- lib/lp/services/job/interfaces/job.py 2010-01-11 22:27:16 +0000
273+++ lib/lp/services/job/interfaces/job.py 2010-01-14 23:48:14 +0000
274@@ -144,3 +144,13 @@
275
276 def run():
277 """Run this job."""
278+
279+
280+class IJobSource(Interface):
281+ """Interface for creating and getting jobs."""
282+
283+ def iterReady():
284+ """Iterate through all jobs."""
285+
286+ def contextManager():
287+ """Get a context for running this kind of job in."""

Subscribers

People subscribed via source and target branches

to status/vote changes: