Merge lp:~abentley/launchpad/incremental-diff-job into lp:launchpad/db-devel
- incremental-diff-job
- Merge into db-devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Graham Binns | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 9950 | ||||
Proposed branch: | lp:~abentley/launchpad/incremental-diff-job | ||||
Merge into: | lp:launchpad/db-devel | ||||
Prerequisite: | lp:~abentley/launchpad/display-incremental | ||||
Diff against target: |
673 lines (+301/-66) 9 files modified
lib/lp/code/configure.zcml (+5/-0) lib/lp/code/interfaces/branchmergeproposal.py (+20/-0) lib/lp/code/model/branch.py (+12/-4) lib/lp/code/model/branchmergeproposal.py (+11/-0) lib/lp/code/model/branchmergeproposaljob.py (+93/-14) lib/lp/code/model/tests/test_branchmergeproposaljobs.py (+69/-3) lib/lp/code/model/tests/test_diff.py (+45/-44) lib/lp/code/scripts/tests/test_merge_proposal_jobs.py (+12/-1) lib/lp/codehosting/scanner/tests/test_bzrsync.py (+34/-0) |
||||
To merge this branch: | bzr merge lp:~abentley/launchpad/incremental-diff-job | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Graham Binns (community) | code | Approve | |
Review via email: mp+36881@code.launchpad.net |
Commit message
Implement jobs for generating incremental diffs.
Description of the change
= Summary =
Implement jobs for generating incremental diffs for merge proposals, and create
these jobs when the merge proposal source banch tip changes.
== Proposed fix ==
See above
== Pre-implementation notes ==
Discussed with Thumper
== Implementation details ==
As a driveby, I extracted commit_file and create_
could be reused more easily, without necessarily deriving from DiffTestCase.
I also added a job_type parameter to BranchMergeProp
make testing easier.
There were also a few lint fixes, like removing a semicolon.
== Tests ==
bin/test -t TestGenerateInc
== Demo and Q/A ==
Create a merge proposal. After the initial diff has been generated, push new
changes to the source branch. As well as updating the diff, this should show a
diff from the old branch tip to the new branch tip.
= Launchpad lint =
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
utilities/
lib/lp/
lib/lp/
./lib/lp/
618: E202 whitespace before ')'
635: E231 missing whitespace after ','
./lib/lp/
192: E231 missing whitespace after ','
194: E231 missing whitespace after ','
./lib/lp/
15: E202 whitespace before ')'
./lib/lp/
166: E301 expected 1 blank line, found 0
./lib/lp/
5: E303 too many blank lines (3)
292: E202 whitespace before ')'
./lib/lp/
168: E301 expected 1 blank line, found 0
178: E301 expected 1 blank line, found 0
201: E202 whitespace before '}'
1471: E301 expected 1 blank line, found 0
Brad Crittenden (bac) wrote : | # |
Is this approved branch ready to land or are you blocked? If you have abandoned the work please change the MP status to "Rejected."
Aaron Bentley (abentley) wrote : | # |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 11/04/2010 11:09 PM, Brad Crittenden wrote:
> Is this approved branch ready to land or are you blocked? If you have abandoned the work please change the MP status to "Rejected."
This branch was blocked. See my "Mysterious storm bug" post. Then Jamu
and I found a solution. Then there was another bug relating to test
isolation with feature flags, which Tim was able to solve. I merged
Tim's changes from devel, but those brought with them actual windmill
failures introduced by Ian Booth. When those were resolved, I merged
again and attempted to land, only to discover we were in testfix mode
due to spurious windmill failures on db-devel. I forced a build and
when it passed, I attempted to land the branch, but the landing failed
due to conflicts. That was after EOD yesterday. Today I plan to
resolve the conflicts and land it.
Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://
iEYEARECAAYFAkz
6LQAn2JpFS1GQaq
=KAU9
-----END PGP SIGNATURE-----
Aaron Bentley (abentley) wrote : | # |
I tried to land once again, and once again we are in testfix mode due to the same spurious windmill failure.
Preview Diff
1 | === modified file 'lib/lp/code/configure.zcml' | |||
2 | --- lib/lp/code/configure.zcml 2010-11-05 14:03:28 +0000 | |||
3 | +++ lib/lp/code/configure.zcml 2010-11-05 14:03:38 +0000 | |||
4 | @@ -307,6 +307,11 @@ | |||
5 | 307 | <allow interface="lp.code.interfaces.branchmergeproposal.IBranchMergeProposalJobSource"/> | 307 | <allow interface="lp.code.interfaces.branchmergeproposal.IBranchMergeProposalJobSource"/> |
6 | 308 | </securedutility> | 308 | </securedutility> |
7 | 309 | 309 | ||
8 | 310 | <class | ||
9 | 311 | class="lp.code.model.branchmergeproposaljob.GenerateIncrementalDiffJob"> | ||
10 | 312 | <allow interface="lp.code.interfaces.branchmergeproposal.IGenerateIncrementalDiffJob"/> | ||
11 | 313 | <allow interface="lp.code.interfaces.branchmergeproposal.IBranchMergeProposalJob" /> | ||
12 | 314 | </class> | ||
13 | 310 | <class class="lp.code.model.branchmergeproposaljob.UpdatePreviewDiffJob"> | 315 | <class class="lp.code.model.branchmergeproposaljob.UpdatePreviewDiffJob"> |
14 | 311 | <allow interface="lp.code.interfaces.branchmergeproposal.IUpdatePreviewDiffJob" /> | 316 | <allow interface="lp.code.interfaces.branchmergeproposal.IUpdatePreviewDiffJob" /> |
15 | 312 | <allow interface="lp.code.interfaces.branchmergeproposal.IBranchMergeProposalJob" /> | 317 | <allow interface="lp.code.interfaces.branchmergeproposal.IBranchMergeProposalJob" /> |
16 | 313 | 318 | ||
17 | === modified file 'lib/lp/code/interfaces/branchmergeproposal.py' | |||
18 | --- lib/lp/code/interfaces/branchmergeproposal.py 2010-10-25 05:33:20 +0000 | |||
19 | +++ lib/lp/code/interfaces/branchmergeproposal.py 2010-11-05 14:03:38 +0000 | |||
20 | @@ -17,6 +17,8 @@ | |||
21 | 17 | 'ICodeReviewCommentEmailJobSource', | 17 | 'ICodeReviewCommentEmailJobSource', |
22 | 18 | 'ICreateMergeProposalJob', | 18 | 'ICreateMergeProposalJob', |
23 | 19 | 'ICreateMergeProposalJobSource', | 19 | 'ICreateMergeProposalJobSource', |
24 | 20 | 'IGenerateIncrementalDiffJob', | ||
25 | 21 | 'IGenerateIncrementalDiffJobSource', | ||
26 | 20 | 'IMergeProposalNeedsReviewEmailJob', | 22 | 'IMergeProposalNeedsReviewEmailJob', |
27 | 21 | 'IMergeProposalNeedsReviewEmailJobSource', | 23 | 'IMergeProposalNeedsReviewEmailJobSource', |
28 | 22 | 'IMergeProposalUpdatedEmailJob', | 24 | 'IMergeProposalUpdatedEmailJob', |
29 | @@ -556,6 +558,10 @@ | |||
30 | 556 | """A job source that will get all supported merge proposal jobs.""" | 558 | """A job source that will get all supported merge proposal jobs.""" |
31 | 557 | 559 | ||
32 | 558 | 560 | ||
33 | 561 | class IBranchMergeProposalJobSource(IJobSource): | ||
34 | 562 | """A job source that will get all supported merge proposal jobs.""" | ||
35 | 563 | |||
36 | 564 | |||
37 | 559 | class IBranchMergeProposalListingBatchNavigator(ITableBatchNavigator): | 565 | class IBranchMergeProposalListingBatchNavigator(ITableBatchNavigator): |
38 | 560 | """A marker interface for registering the appropriate listings.""" | 566 | """A marker interface for registering the appropriate listings.""" |
39 | 561 | 567 | ||
40 | @@ -661,6 +667,20 @@ | |||
41 | 661 | """Return the UpdatePreviewDiffJob with this id.""" | 667 | """Return the UpdatePreviewDiffJob with this id.""" |
42 | 662 | 668 | ||
43 | 663 | 669 | ||
44 | 670 | class IGenerateIncrementalDiffJob(IRunnableJob): | ||
45 | 671 | """Interface for the job to update the diff for a merge proposal.""" | ||
46 | 672 | |||
47 | 673 | |||
48 | 674 | class IGenerateIncrementalDiffJobSource(Interface): | ||
49 | 675 | """Create or retrieve jobs that update preview diffs.""" | ||
50 | 676 | |||
51 | 677 | def create(bmp, old_revision_id, new_revision_id): | ||
52 | 678 | """Create job to generate incremental diff for this merge proposal.""" | ||
53 | 679 | |||
54 | 680 | def get(id): | ||
55 | 681 | """Return the GenerateIncrementalDiffJob with this id.""" | ||
56 | 682 | |||
57 | 683 | |||
58 | 664 | class ICodeReviewCommentEmailJob(IRunnableJob): | 684 | class ICodeReviewCommentEmailJob(IRunnableJob): |
59 | 665 | """Interface for the job to send code review comment email.""" | 685 | """Interface for the job to send code review comment email.""" |
60 | 666 | 686 | ||
61 | 667 | 687 | ||
62 | === modified file 'lib/lp/code/model/branch.py' | |||
63 | --- lib/lp/code/model/branch.py 2010-11-04 19:59:02 +0000 | |||
64 | +++ lib/lp/code/model/branch.py 2010-11-05 14:03:38 +0000 | |||
65 | @@ -471,10 +471,18 @@ | |||
66 | 471 | 471 | ||
67 | 472 | def scheduleDiffUpdates(self): | 472 | def scheduleDiffUpdates(self): |
68 | 473 | """See `IBranch`.""" | 473 | """See `IBranch`.""" |
73 | 474 | from lp.code.model.branchmergeproposaljob import UpdatePreviewDiffJob | 474 | from lp.code.model.branchmergeproposaljob import ( |
74 | 475 | jobs = [UpdatePreviewDiffJob.create(target) | 475 | GenerateIncrementalDiffJob, |
75 | 476 | for target in self.active_landing_targets | 476 | UpdatePreviewDiffJob, |
76 | 477 | if target.target_branch.last_scanned_id is not None] | 477 | ) |
77 | 478 | jobs = [] | ||
78 | 479 | for merge_proposal in self.active_landing_targets: | ||
79 | 480 | if merge_proposal.target_branch.last_scanned_id is None: | ||
80 | 481 | continue | ||
81 | 482 | jobs.append(UpdatePreviewDiffJob.create(merge_proposal)) | ||
82 | 483 | for old, new in merge_proposal.getMissingIncrementalDiffs(): | ||
83 | 484 | GenerateIncrementalDiffJob.create( | ||
84 | 485 | merge_proposal, old.revision_id, new.revision_id) | ||
85 | 478 | return jobs | 486 | return jobs |
86 | 479 | 487 | ||
87 | 480 | def addToLaunchBag(self, launchbag): | 488 | def addToLaunchBag(self, launchbag): |
88 | 481 | 489 | ||
89 | === modified file 'lib/lp/code/model/branchmergeproposal.py' | |||
90 | --- lib/lp/code/model/branchmergeproposal.py 2010-11-05 14:03:28 +0000 | |||
91 | +++ lib/lp/code/model/branchmergeproposal.py 2010-11-05 14:03:38 +0000 | |||
92 | @@ -785,6 +785,12 @@ | |||
93 | 785 | Store.of(self).flush() | 785 | Store.of(self).flush() |
94 | 786 | return self.preview_diff | 786 | return self.preview_diff |
95 | 787 | 787 | ||
96 | 788 | def getIncrementalDiffRanges(self): | ||
97 | 789 | groups = self.getRevisionsSinceReviewStart() | ||
98 | 790 | return [ | ||
99 | 791 | (group[0].revision.getLefthandParent(), group[-1].revision) | ||
100 | 792 | for group in groups] | ||
101 | 793 | |||
102 | 788 | def generateIncrementalDiff(self, old_revision, new_revision, diff=None): | 794 | def generateIncrementalDiff(self, old_revision, new_revision, diff=None): |
103 | 789 | """Generate an incremental diff for the merge proposal. | 795 | """Generate an incremental diff for the merge proposal. |
104 | 790 | 796 | ||
105 | @@ -870,6 +876,11 @@ | |||
106 | 870 | if current_group != []: | 876 | if current_group != []: |
107 | 871 | yield current_group | 877 | yield current_group |
108 | 872 | 878 | ||
109 | 879 | def getMissingIncrementalDiffs(self): | ||
110 | 880 | ranges = self.getIncrementalDiffRanges() | ||
111 | 881 | diffs = self.getIncrementalDiffs(ranges) | ||
112 | 882 | return [range_ for range_, diff in zip(ranges, diffs) if diff is None] | ||
113 | 883 | |||
114 | 873 | 884 | ||
115 | 874 | class BranchMergeProposalGetter: | 885 | class BranchMergeProposalGetter: |
116 | 875 | """See `IBranchMergeProposalGetter`.""" | 886 | """See `IBranchMergeProposalGetter`.""" |
117 | 876 | 887 | ||
118 | === modified file 'lib/lp/code/model/branchmergeproposaljob.py' | |||
119 | --- lib/lp/code/model/branchmergeproposaljob.py 2010-10-26 15:47:24 +0000 | |||
120 | +++ lib/lp/code/model/branchmergeproposaljob.py 2010-11-05 14:03:38 +0000 | |||
121 | @@ -19,6 +19,8 @@ | |||
122 | 19 | 'BranchMergeProposalJobType', | 19 | 'BranchMergeProposalJobType', |
123 | 20 | 'CodeReviewCommentEmailJob', | 20 | 'CodeReviewCommentEmailJob', |
124 | 21 | 'CreateMergeProposalJob', | 21 | 'CreateMergeProposalJob', |
125 | 22 | 'GenerateIncrementalDiffJob', | ||
126 | 23 | 'MergeProposalCreatedJob', | ||
127 | 22 | 'MergeProposalNeedsReviewEmailJob', | 24 | 'MergeProposalNeedsReviewEmailJob', |
128 | 23 | 'MergeProposalUpdatedEmailJob', | 25 | 'MergeProposalUpdatedEmailJob', |
129 | 24 | 'ReviewRequestedEmailJob', | 26 | 'ReviewRequestedEmailJob', |
130 | @@ -83,6 +85,8 @@ | |||
131 | 83 | ICodeReviewCommentEmailJobSource, | 85 | ICodeReviewCommentEmailJobSource, |
132 | 84 | ICreateMergeProposalJob, | 86 | ICreateMergeProposalJob, |
133 | 85 | ICreateMergeProposalJobSource, | 87 | ICreateMergeProposalJobSource, |
134 | 88 | IGenerateIncrementalDiffJob, | ||
135 | 89 | IGenerateIncrementalDiffJobSource, | ||
136 | 86 | IMergeProposalNeedsReviewEmailJob, | 90 | IMergeProposalNeedsReviewEmailJob, |
137 | 87 | IMergeProposalNeedsReviewEmailJobSource, | 91 | IMergeProposalNeedsReviewEmailJobSource, |
138 | 88 | IMergeProposalUpdatedEmailJob, | 92 | IMergeProposalUpdatedEmailJob, |
139 | @@ -92,6 +96,7 @@ | |||
140 | 92 | IUpdatePreviewDiffJob, | 96 | IUpdatePreviewDiffJob, |
141 | 93 | IUpdatePreviewDiffJobSource, | 97 | IUpdatePreviewDiffJobSource, |
142 | 94 | ) | 98 | ) |
143 | 99 | from lp.code.interfaces.revision import IRevisionSet | ||
144 | 95 | from lp.code.mail.branch import RecipientReason | 100 | from lp.code.mail.branch import RecipientReason |
145 | 96 | from lp.code.mail.branchmergeproposal import BMPMailer | 101 | from lp.code.mail.branchmergeproposal import BMPMailer |
146 | 97 | from lp.code.mail.codereviewcomment import CodeReviewCommentMailer | 102 | from lp.code.mail.codereviewcomment import CodeReviewCommentMailer |
147 | @@ -144,6 +149,11 @@ | |||
148 | 144 | that have been changed on the merge proposal itself. | 149 | that have been changed on the merge proposal itself. |
149 | 145 | """) | 150 | """) |
150 | 146 | 151 | ||
151 | 152 | GENERATE_INCREMENTAL_DIFF = DBItem(5, """ | ||
152 | 153 | Generate incremental diff | ||
153 | 154 | |||
154 | 155 | This job generates an incremental diff for a merge proposal.""") | ||
155 | 156 | |||
156 | 147 | 157 | ||
157 | 148 | class BranchMergeProposalJob(Storm): | 158 | class BranchMergeProposalJob(Storm): |
158 | 149 | """Base class for jobs related to branch merge proposals.""" | 159 | """Base class for jobs related to branch merge proposals.""" |
159 | @@ -282,7 +292,7 @@ | |||
160 | 282 | 292 | ||
161 | 283 | def getOopsVars(self): | 293 | def getOopsVars(self): |
162 | 284 | """See `IRunnableJob`.""" | 294 | """See `IRunnableJob`.""" |
164 | 285 | vars = BaseRunnableJob.getOopsVars(self) | 295 | vars = BaseRunnableJob.getOopsVars(self) |
165 | 286 | bmp = self.context.branch_merge_proposal | 296 | bmp = self.context.branch_merge_proposal |
166 | 287 | vars.extend([ | 297 | vars.extend([ |
167 | 288 | ('branchmergeproposal_job_id', self.context.id), | 298 | ('branchmergeproposal_job_id', self.context.id), |
168 | @@ -490,7 +500,7 @@ | |||
169 | 490 | 500 | ||
170 | 491 | def getOopsVars(self): | 501 | def getOopsVars(self): |
171 | 492 | """See `IRunnableJob`.""" | 502 | """See `IRunnableJob`.""" |
173 | 493 | vars = BranchMergeProposalJobDerived.getOopsVars(self) | 503 | vars = BranchMergeProposalJobDerived.getOopsVars(self) |
174 | 494 | vars.extend([ | 504 | vars.extend([ |
175 | 495 | ('code_review_comment', self.metadata['code_review_comment']), | 505 | ('code_review_comment', self.metadata['code_review_comment']), |
176 | 496 | ]) | 506 | ]) |
177 | @@ -552,7 +562,7 @@ | |||
178 | 552 | 562 | ||
179 | 553 | def getOopsVars(self): | 563 | def getOopsVars(self): |
180 | 554 | """See `IRunnableJob`.""" | 564 | """See `IRunnableJob`.""" |
182 | 555 | vars = BranchMergeProposalJobDerived.getOopsVars(self) | 565 | vars = BranchMergeProposalJobDerived.getOopsVars(self) |
183 | 556 | vars.extend([ | 566 | vars.extend([ |
184 | 557 | ('reviewer', self.metadata['reviewer']), | 567 | ('reviewer', self.metadata['reviewer']), |
185 | 558 | ('requester', self.metadata['requester']), | 568 | ('requester', self.metadata['requester']), |
186 | @@ -601,7 +611,7 @@ | |||
187 | 601 | def getMetadata(delta_text, editor): | 611 | def getMetadata(delta_text, editor): |
188 | 602 | metadata = {'delta_text': delta_text} | 612 | metadata = {'delta_text': delta_text} |
189 | 603 | if editor is not None: | 613 | if editor is not None: |
191 | 604 | metadata['editor'] = editor.name; | 614 | metadata['editor'] = editor.name |
192 | 605 | return metadata | 615 | return metadata |
193 | 606 | 616 | ||
194 | 607 | @property | 617 | @property |
195 | @@ -620,7 +630,7 @@ | |||
196 | 620 | 630 | ||
197 | 621 | def getOopsVars(self): | 631 | def getOopsVars(self): |
198 | 622 | """See `IRunnableJob`.""" | 632 | """See `IRunnableJob`.""" |
200 | 623 | vars = BranchMergeProposalJobDerived.getOopsVars(self) | 633 | vars = BranchMergeProposalJobDerived.getOopsVars(self) |
201 | 624 | vars.extend([ | 634 | vars.extend([ |
202 | 625 | ('editor', self.metadata.get('editor', '(not set)')), | 635 | ('editor', self.metadata.get('editor', '(not set)')), |
203 | 626 | ('delta_text', self.metadata['delta_text']), | 636 | ('delta_text', self.metadata['delta_text']), |
204 | @@ -638,6 +648,70 @@ | |||
205 | 638 | return 'emailing subscribers about merge proposal changes' | 648 | return 'emailing subscribers about merge proposal changes' |
206 | 639 | 649 | ||
207 | 640 | 650 | ||
208 | 651 | class GenerateIncrementalDiffJob(BranchMergeProposalJobDerived): | ||
209 | 652 | """A job to generate an incremental diff for a branch merge proposal. | ||
210 | 653 | |||
211 | 654 | Provides class methods to create and retrieve such jobs. | ||
212 | 655 | """ | ||
213 | 656 | |||
214 | 657 | implements(IGenerateIncrementalDiffJob) | ||
215 | 658 | |||
216 | 659 | classProvides(IGenerateIncrementalDiffJobSource) | ||
217 | 660 | |||
218 | 661 | class_job_type = BranchMergeProposalJobType.GENERATE_INCREMENTAL_DIFF | ||
219 | 662 | |||
220 | 663 | def acquireLease(self, duration=600): | ||
221 | 664 | return self.job.acquireLease(duration) | ||
222 | 665 | |||
223 | 666 | def run(self): | ||
224 | 667 | revision_set = getUtility(IRevisionSet) | ||
225 | 668 | old_revision = revision_set.getByRevisionId(self.old_revision_id) | ||
226 | 669 | new_revision = revision_set.getByRevisionId(self.new_revision_id) | ||
227 | 670 | diff = self.branch_merge_proposal.generateIncrementalDiff( | ||
228 | 671 | old_revision, new_revision) | ||
229 | 672 | |||
230 | 673 | @classmethod | ||
231 | 674 | def create(cls, merge_proposal, old_revision_id, new_revision_id): | ||
232 | 675 | metadata = cls.getMetadata(old_revision_id, new_revision_id) | ||
233 | 676 | job = BranchMergeProposalJob( | ||
234 | 677 | merge_proposal, cls.class_job_type, metadata) | ||
235 | 678 | return cls(job) | ||
236 | 679 | |||
237 | 680 | @staticmethod | ||
238 | 681 | def getMetadata(old_revision_id, new_revision_id): | ||
239 | 682 | return { | ||
240 | 683 | 'old_revision_id': old_revision_id, | ||
241 | 684 | 'new_revision_id': new_revision_id, | ||
242 | 685 | } | ||
243 | 686 | |||
244 | 687 | @property | ||
245 | 688 | def old_revision_id(self): | ||
246 | 689 | """The old revision id for the diff.""" | ||
247 | 690 | return self.metadata['old_revision_id'] | ||
248 | 691 | |||
249 | 692 | @property | ||
250 | 693 | def new_revision_id(self): | ||
251 | 694 | """The new revision id for the diff.""" | ||
252 | 695 | return self.metadata['new_revision_id'] | ||
253 | 696 | |||
254 | 697 | def getOopsVars(self): | ||
255 | 698 | """See `IRunnableJob`.""" | ||
256 | 699 | vars = BranchMergeProposalJobDerived.getOopsVars(self) | ||
257 | 700 | vars.extend([ | ||
258 | 701 | ('old_revision_id', self.metadata['old_revision_id']), | ||
259 | 702 | ('new_revision_id', self.metadata['new_revision_id']), | ||
260 | 703 | ]) | ||
261 | 704 | return vars | ||
262 | 705 | |||
263 | 706 | def getOperationDescription(self): | ||
264 | 707 | return ('generating an incremental diff for a merge proposal') | ||
265 | 708 | |||
266 | 709 | def getErrorRecipients(self): | ||
267 | 710 | """Return a list of email-ids to notify about user errors.""" | ||
268 | 711 | registrant = self.branch_merge_proposal.registrant | ||
269 | 712 | return format_address_for_person(registrant) | ||
270 | 713 | |||
271 | 714 | |||
272 | 641 | class BranchMergeProposalJobFactory: | 715 | class BranchMergeProposalJobFactory: |
273 | 642 | """Construct a derived merge proposal job for a BranchMergeProposalJob.""" | 716 | """Construct a derived merge proposal job for a BranchMergeProposalJob.""" |
274 | 643 | 717 | ||
275 | @@ -652,6 +726,8 @@ | |||
276 | 652 | ReviewRequestedEmailJob, | 726 | ReviewRequestedEmailJob, |
277 | 653 | BranchMergeProposalJobType.MERGE_PROPOSAL_UPDATED: | 727 | BranchMergeProposalJobType.MERGE_PROPOSAL_UPDATED: |
278 | 654 | MergeProposalUpdatedEmailJob, | 728 | MergeProposalUpdatedEmailJob, |
279 | 729 | BranchMergeProposalJobType.GENERATE_INCREMENTAL_DIFF: | ||
280 | 730 | GenerateIncrementalDiffJob, | ||
281 | 655 | } | 731 | } |
282 | 656 | 732 | ||
283 | 657 | @classmethod | 733 | @classmethod |
284 | @@ -692,21 +768,24 @@ | |||
285 | 692 | return BranchMergeProposalJobFactory.create(job) | 768 | return BranchMergeProposalJobFactory.create(job) |
286 | 693 | 769 | ||
287 | 694 | @staticmethod | 770 | @staticmethod |
289 | 695 | def iterReady(): | 771 | def iterReady(job_type=None): |
290 | 696 | from lp.code.model.branch import Branch | 772 | from lp.code.model.branch import Branch |
291 | 697 | store = getUtility(IStoreSelector).get(MAIN_STORE, MASTER_FLAVOR) | 773 | store = getUtility(IStoreSelector).get(MAIN_STORE, MASTER_FLAVOR) |
292 | 698 | SourceBranch = ClassAlias(Branch) | 774 | SourceBranch = ClassAlias(Branch) |
293 | 699 | TargetBranch = ClassAlias(Branch) | 775 | TargetBranch = ClassAlias(Branch) |
294 | 776 | clauses = [ | ||
295 | 777 | BranchMergeProposalJob.job == Job.id, | ||
296 | 778 | Job._status.is_in([JobStatus.WAITING, JobStatus.RUNNING]), | ||
297 | 779 | BranchMergeProposalJob.branch_merge_proposal == | ||
298 | 780 | BranchMergeProposal.id, BranchMergeProposal.source_branch == | ||
299 | 781 | SourceBranch.id, BranchMergeProposal.target_branch == | ||
300 | 782 | TargetBranch.id, | ||
301 | 783 | ] | ||
302 | 784 | if job_type is not None: | ||
303 | 785 | clauses.append(BranchMergeProposalJob.job_type == job_type) | ||
304 | 700 | jobs = store.find( | 786 | jobs = store.find( |
305 | 701 | (BranchMergeProposalJob, Job, BranchMergeProposal, | 787 | (BranchMergeProposalJob, Job, BranchMergeProposal, |
314 | 702 | SourceBranch, TargetBranch), | 788 | SourceBranch, TargetBranch), And(*clauses)) |
307 | 703 | And(BranchMergeProposalJob.job == Job.id, | ||
308 | 704 | Job._status.is_in([JobStatus.WAITING, JobStatus.RUNNING]), | ||
309 | 705 | BranchMergeProposalJob.branch_merge_proposal | ||
310 | 706 | == BranchMergeProposal.id, | ||
311 | 707 | BranchMergeProposal.source_branch == SourceBranch.id, | ||
312 | 708 | BranchMergeProposal.target_branch == TargetBranch.id, | ||
313 | 709 | )) | ||
315 | 710 | # Order by the job status first (to get running before waiting), then | 789 | # Order by the job status first (to get running before waiting), then |
316 | 711 | # the date_created, then job type. This should give us all creation | 790 | # the date_created, then job type. This should give us all creation |
317 | 712 | # jobs before comment jobs. | 791 | # jobs before comment jobs. |
318 | 713 | 792 | ||
319 | === modified file 'lib/lp/code/model/tests/test_branchmergeproposaljobs.py' | |||
320 | --- lib/lp/code/model/tests/test_branchmergeproposaljobs.py 2010-10-28 22:31:48 +0000 | |||
321 | +++ lib/lp/code/model/tests/test_branchmergeproposaljobs.py 2010-11-05 14:03:38 +0000 | |||
322 | @@ -32,6 +32,8 @@ | |||
323 | 32 | IBranchMergeProposalJobSource, | 32 | IBranchMergeProposalJobSource, |
324 | 33 | ICodeReviewCommentEmailJob, | 33 | ICodeReviewCommentEmailJob, |
325 | 34 | ICodeReviewCommentEmailJobSource, | 34 | ICodeReviewCommentEmailJobSource, |
326 | 35 | IGenerateIncrementalDiffJob, | ||
327 | 36 | IGenerateIncrementalDiffJobSource, | ||
328 | 35 | IMergeProposalNeedsReviewEmailJob, | 37 | IMergeProposalNeedsReviewEmailJob, |
329 | 36 | IMergeProposalUpdatedEmailJob, | 38 | IMergeProposalUpdatedEmailJob, |
330 | 37 | IMergeProposalUpdatedEmailJobSource, | 39 | IMergeProposalUpdatedEmailJobSource, |
331 | @@ -45,12 +47,13 @@ | |||
332 | 45 | BranchMergeProposalJobDerived, | 47 | BranchMergeProposalJobDerived, |
333 | 46 | BranchMergeProposalJobType, | 48 | BranchMergeProposalJobType, |
334 | 47 | CodeReviewCommentEmailJob, | 49 | CodeReviewCommentEmailJob, |
335 | 50 | GenerateIncrementalDiffJob, | ||
336 | 48 | MergeProposalNeedsReviewEmailJob, | 51 | MergeProposalNeedsReviewEmailJob, |
337 | 49 | MergeProposalUpdatedEmailJob, | 52 | MergeProposalUpdatedEmailJob, |
338 | 50 | ReviewRequestedEmailJob, | 53 | ReviewRequestedEmailJob, |
339 | 51 | UpdatePreviewDiffJob, | 54 | UpdatePreviewDiffJob, |
340 | 52 | ) | 55 | ) |
342 | 53 | from lp.code.model.tests.test_diff import DiffTestCase | 56 | from lp.code.model.tests.test_diff import DiffTestCase, create_example_merge |
343 | 54 | from lp.code.subscribers.branchmergeproposal import merge_proposal_modified | 57 | from lp.code.subscribers.branchmergeproposal import merge_proposal_modified |
344 | 55 | from lp.services.job.model.job import Job | 58 | from lp.services.job.model.job import Job |
345 | 56 | from lp.services.job.runner import JobRunner | 59 | from lp.services.job.runner import JobRunner |
346 | @@ -192,7 +195,7 @@ | |||
347 | 192 | 195 | ||
348 | 193 | def test_run(self): | 196 | def test_run(self): |
349 | 194 | self.useBzrBranches(direct_database=True) | 197 | self.useBzrBranches(direct_database=True) |
351 | 195 | bmp = self.createExampleMerge()[0] | 198 | bmp = create_example_merge(self)[0] |
352 | 196 | job = UpdatePreviewDiffJob.create(bmp) | 199 | job = UpdatePreviewDiffJob.create(bmp) |
353 | 197 | self.factory.makeRevisionsForBranch(bmp.source_branch, count=1) | 200 | self.factory.makeRevisionsForBranch(bmp.source_branch, count=1) |
354 | 198 | bmp.source_branch.next_mirror_time = None | 201 | bmp.source_branch.next_mirror_time = None |
355 | @@ -226,13 +229,76 @@ | |||
356 | 226 | 229 | ||
357 | 227 | def test_10_minute_lease(self): | 230 | def test_10_minute_lease(self): |
358 | 228 | self.useBzrBranches(direct_database=True) | 231 | self.useBzrBranches(direct_database=True) |
360 | 229 | bmp = self.createExampleMerge()[0] | 232 | bmp = create_example_merge(self)[0] |
361 | 230 | job = UpdatePreviewDiffJob.create(bmp) | 233 | job = UpdatePreviewDiffJob.create(bmp) |
362 | 231 | job.acquireLease() | 234 | job.acquireLease() |
363 | 232 | expiry_delta = job.lease_expires - datetime.now(pytz.UTC) | 235 | expiry_delta = job.lease_expires - datetime.now(pytz.UTC) |
364 | 233 | self.assertTrue(500 <= expiry_delta.seconds, expiry_delta) | 236 | self.assertTrue(500 <= expiry_delta.seconds, expiry_delta) |
365 | 234 | 237 | ||
366 | 235 | 238 | ||
367 | 239 | def make_runnable_incremental_diff_job(test_case): | ||
368 | 240 | test_case.useBzrBranches(direct_database=True) | ||
369 | 241 | bmp, source_rev_id, target_rev_id = create_example_merge(test_case) | ||
370 | 242 | repository = bmp.source_branch.getBzrBranch().repository | ||
371 | 243 | parent_id = repository.get_revision(source_rev_id).parent_ids[0] | ||
372 | 244 | test_case.factory.makeRevision(rev_id=source_rev_id) | ||
373 | 245 | test_case.factory.makeRevision(rev_id=parent_id) | ||
374 | 246 | return GenerateIncrementalDiffJob.create(bmp, parent_id, source_rev_id) | ||
375 | 247 | |||
376 | 248 | |||
377 | 249 | class TestGenerateIncrementalDiffJob(DiffTestCase): | ||
378 | 250 | |||
379 | 251 | layer = LaunchpadZopelessLayer | ||
380 | 252 | |||
381 | 253 | def test_implement_interface(self): | ||
382 | 254 | """GenerateIncrementalDiffJob implements its interface.""" | ||
383 | 255 | verifyObject( | ||
384 | 256 | IGenerateIncrementalDiffJobSource, GenerateIncrementalDiffJob) | ||
385 | 257 | |||
386 | 258 | def test_providesInterface(self): | ||
387 | 259 | """MergeProposalCreatedJob provides the expected interfaces.""" | ||
388 | 260 | bmp = self.factory.makeBranchMergeProposal() | ||
389 | 261 | job = GenerateIncrementalDiffJob.create(bmp, 'old', 'new') | ||
390 | 262 | verifyObject(IGenerateIncrementalDiffJob, job) | ||
391 | 263 | verifyObject(IBranchMergeProposalJob, job) | ||
392 | 264 | |||
393 | 265 | def test_getOperationDescription(self): | ||
394 | 266 | """The description of the job is sane.""" | ||
395 | 267 | bmp = self.factory.makeBranchMergeProposal() | ||
396 | 268 | job = GenerateIncrementalDiffJob.create(bmp, 'old', 'new') | ||
397 | 269 | self.assertEqual( | ||
398 | 270 | 'generating an incremental diff for a merge proposal', | ||
399 | 271 | job.getOperationDescription()) | ||
400 | 272 | |||
401 | 273 | def test_run(self): | ||
402 | 274 | """The job runs successfully, and its results can be committed.""" | ||
403 | 275 | job = make_runnable_incremental_diff_job(self) | ||
404 | 276 | transaction.commit() | ||
405 | 277 | self.layer.switchDbUser(config.merge_proposal_jobs.dbuser) | ||
406 | 278 | job.run() | ||
407 | 279 | transaction.commit() | ||
408 | 280 | |||
409 | 281 | def test_run_all(self): | ||
410 | 282 | """The job can be run under the JobRunner successfully.""" | ||
411 | 283 | job = make_runnable_incremental_diff_job(self) | ||
412 | 284 | transaction.commit() | ||
413 | 285 | self.layer.switchDbUser(config.merge_proposal_jobs.dbuser) | ||
414 | 286 | runner = JobRunner([job]) | ||
415 | 287 | runner.runAll() | ||
416 | 288 | self.assertEqual([job], runner.completed_jobs) | ||
417 | 289 | |||
418 | 290 | def test_10_minute_lease(self): | ||
419 | 291 | """Newly-created jobs have a ten-minute lease.""" | ||
420 | 292 | self.useBzrBranches(direct_database=True) | ||
421 | 293 | bmp = create_example_merge(self)[0] | ||
422 | 294 | job = GenerateIncrementalDiffJob.create(bmp, 'old', 'new') | ||
423 | 295 | transaction.commit() | ||
424 | 296 | self.layer.switchDbUser(config.merge_proposal_jobs.dbuser) | ||
425 | 297 | job.acquireLease() | ||
426 | 298 | expiry_delta = job.lease_expires - datetime.now(pytz.UTC) | ||
427 | 299 | self.assertTrue(500 <= expiry_delta.seconds, expiry_delta) | ||
428 | 300 | |||
429 | 301 | |||
430 | 236 | class TestBranchMergeProposalJobSource(TestCaseWithFactory): | 302 | class TestBranchMergeProposalJobSource(TestCaseWithFactory): |
431 | 237 | 303 | ||
432 | 238 | layer = LaunchpadZopelessLayer | 304 | layer = LaunchpadZopelessLayer |
433 | 239 | 305 | ||
434 | === modified file 'lib/lp/code/model/tests/test_diff.py' | |||
435 | --- lib/lp/code/model/tests/test_diff.py 2010-11-05 14:03:28 +0000 | |||
436 | +++ lib/lp/code/model/tests/test_diff.py 2010-11-05 14:03:38 +0000 | |||
437 | @@ -54,37 +54,41 @@ | |||
438 | 54 | self.records.append(record) | 54 | self.records.append(record) |
439 | 55 | 55 | ||
440 | 56 | 56 | ||
441 | 57 | def commit_file(branch, path, contents, merge_parents=None): | ||
442 | 58 | """Create a commit that updates a file to specified contents. | ||
443 | 59 | |||
444 | 60 | This will create or modify the file, as needed. | ||
445 | 61 | """ | ||
446 | 62 | committer = DirectBranchCommit( | ||
447 | 63 | removeSecurityProxy(branch), no_race_check=True, | ||
448 | 64 | merge_parents=merge_parents) | ||
449 | 65 | committer.writeFile(path, contents) | ||
450 | 66 | try: | ||
451 | 67 | return committer.commit('committing') | ||
452 | 68 | finally: | ||
453 | 69 | committer.unlock() | ||
454 | 70 | |||
455 | 71 | |||
456 | 72 | def create_example_merge(test_case): | ||
457 | 73 | """Create a merge proposal with conflicts and updates.""" | ||
458 | 74 | bmp = test_case.factory.makeBranchMergeProposal() | ||
459 | 75 | # Make the branches of the merge proposal look good as far as the | ||
460 | 76 | # model is concerned. | ||
461 | 77 | test_case.factory.makeRevisionsForBranch(bmp.source_branch) | ||
462 | 78 | test_case.factory.makeRevisionsForBranch(bmp.target_branch) | ||
463 | 79 | bzr_target = test_case.createBzrBranch(bmp.target_branch) | ||
464 | 80 | commit_file(bmp.target_branch, 'foo', 'a\n') | ||
465 | 81 | test_case.createBzrBranch(bmp.source_branch, bzr_target) | ||
466 | 82 | source_rev_id = commit_file(bmp.source_branch, 'foo', 'd\na\nb\n') | ||
467 | 83 | target_rev_id = commit_file(bmp.target_branch, 'foo', 'c\na\n') | ||
468 | 84 | return bmp, source_rev_id, target_rev_id | ||
469 | 85 | |||
470 | 86 | |||
471 | 57 | class DiffTestCase(TestCaseWithFactory): | 87 | class DiffTestCase(TestCaseWithFactory): |
472 | 58 | 88 | ||
473 | 59 | @staticmethod | ||
474 | 60 | def commitFile(branch, path, contents, merge_parents=None): | ||
475 | 61 | """Create a commit that updates a file to specified contents. | ||
476 | 62 | |||
477 | 63 | This will create or modify the file, as needed. | ||
478 | 64 | """ | ||
479 | 65 | committer = DirectBranchCommit( | ||
480 | 66 | removeSecurityProxy(branch), no_race_check=True, | ||
481 | 67 | merge_parents=merge_parents) | ||
482 | 68 | committer.writeFile(path, contents) | ||
483 | 69 | try: | ||
484 | 70 | return committer.commit('committing') | ||
485 | 71 | finally: | ||
486 | 72 | committer.unlock() | ||
487 | 73 | |||
488 | 74 | def createExampleMerge(self): | 89 | def createExampleMerge(self): |
489 | 75 | """Create a merge proposal with conflicts and updates.""" | ||
490 | 76 | self.useBzrBranches(direct_database=True) | 90 | self.useBzrBranches(direct_database=True) |
502 | 77 | bmp = self.factory.makeBranchMergeProposal() | 91 | return create_example_merge(self) |
492 | 78 | # Make the branches of the merge proposal look good as far as the | ||
493 | 79 | # model is concerned. | ||
494 | 80 | self.factory.makeRevisionsForBranch(bmp.source_branch) | ||
495 | 81 | self.factory.makeRevisionsForBranch(bmp.target_branch) | ||
496 | 82 | bzr_target = self.createBzrBranch(bmp.target_branch) | ||
497 | 83 | self.commitFile(bmp.target_branch, 'foo', 'a\n') | ||
498 | 84 | self.createBzrBranch(bmp.source_branch, bzr_target) | ||
499 | 85 | source_rev_id = self.commitFile(bmp.source_branch, 'foo', 'd\na\nb\n') | ||
500 | 86 | target_rev_id = self.commitFile(bmp.target_branch, 'foo', 'c\na\n') | ||
501 | 87 | return bmp, source_rev_id, target_rev_id | ||
503 | 88 | 92 | ||
504 | 89 | def checkExampleMerge(self, diff_text): | 93 | def checkExampleMerge(self, diff_text): |
505 | 90 | """Ensure the diff text matches the values for ExampleMerge.""" | 94 | """Ensure the diff text matches the values for ExampleMerge.""" |
506 | @@ -111,12 +115,12 @@ | |||
507 | 111 | source = bmp.source_branch | 115 | source = bmp.source_branch |
508 | 112 | prerequisite = bmp.prerequisite_branch | 116 | prerequisite = bmp.prerequisite_branch |
509 | 113 | target_bzr = self.createBzrBranch(target) | 117 | target_bzr = self.createBzrBranch(target) |
511 | 114 | self.commitFile(target, 'file', 'target text\n') | 118 | commit_file(target, 'file', 'target text\n') |
512 | 115 | prerequisite_bzr = self.createBzrBranch(prerequisite, target_bzr) | 119 | prerequisite_bzr = self.createBzrBranch(prerequisite, target_bzr) |
514 | 116 | self.commitFile( | 120 | commit_file( |
515 | 117 | prerequisite, 'file', 'target text\nprerequisite text\n') | 121 | prerequisite, 'file', 'target text\nprerequisite text\n') |
516 | 118 | source_bzr = self.createBzrBranch(source, prerequisite_bzr) | 122 | source_bzr = self.createBzrBranch(source, prerequisite_bzr) |
518 | 119 | source_rev_id = self.commitFile( | 123 | source_rev_id = commit_file( |
519 | 120 | source, 'file', | 124 | source, 'file', |
520 | 121 | 'target text\nprerequisite text\nsource text\n') | 125 | 'target text\nprerequisite text\nsource text\n') |
521 | 122 | return (source_bzr, source_rev_id, target_bzr, prerequisite_bzr, | 126 | return (source_bzr, source_rev_id, target_bzr, prerequisite_bzr, |
522 | @@ -243,7 +247,7 @@ | |||
523 | 243 | # affect the diff. | 247 | # affect the diff. |
524 | 244 | (source_bzr, source_rev_id, target_bzr, prerequisite_bzr, | 248 | (source_bzr, source_rev_id, target_bzr, prerequisite_bzr, |
525 | 245 | prerequisite) = self.preparePrerequisiteMerge() | 249 | prerequisite) = self.preparePrerequisiteMerge() |
527 | 246 | self.commitFile( | 250 | commit_file( |
528 | 247 | prerequisite, 'file', 'prerequisite text2\n') | 251 | prerequisite, 'file', 'prerequisite text2\n') |
529 | 248 | diff, conflicts = Diff.mergePreviewFromBranches( | 252 | diff, conflicts = Diff.mergePreviewFromBranches( |
530 | 249 | source_bzr, source_rev_id, target_bzr, prerequisite_bzr) | 253 | source_bzr, source_rev_id, target_bzr, prerequisite_bzr) |
531 | @@ -459,10 +463,10 @@ | |||
532 | 459 | self.useBzrBranches(direct_database=True) | 463 | self.useBzrBranches(direct_database=True) |
533 | 460 | bmp = self.factory.makeBranchMergeProposal() | 464 | bmp = self.factory.makeBranchMergeProposal() |
534 | 461 | bzr_target = self.createBzrBranch(bmp.target_branch) | 465 | bzr_target = self.createBzrBranch(bmp.target_branch) |
536 | 462 | self.commitFile(bmp.target_branch, 'foo', 'a\n') | 466 | commit_file(bmp.target_branch, 'foo', 'a\n') |
537 | 463 | self.createBzrBranch(bmp.source_branch, bzr_target) | 467 | self.createBzrBranch(bmp.source_branch, bzr_target) |
540 | 464 | source_rev_id = self.commitFile(bmp.source_branch, 'foo', 'a\nb\n') | 468 | source_rev_id = commit_file(bmp.source_branch, 'foo', 'a\nb\n') |
541 | 465 | target_rev_id = self.commitFile(bmp.target_branch, 'foo', 'c\na\n') | 469 | target_rev_id = commit_file(bmp.target_branch, 'foo', 'c\na\n') |
542 | 466 | diff = PreviewDiff.fromBranchMergeProposal(bmp) | 470 | diff = PreviewDiff.fromBranchMergeProposal(bmp) |
543 | 467 | self.assertEqual('', diff.conflicts) | 471 | self.assertEqual('', diff.conflicts) |
544 | 468 | self.assertFalse(diff.has_conflicts) | 472 | self.assertFalse(diff.has_conflicts) |
545 | @@ -575,25 +579,22 @@ | |||
546 | 575 | bmp = self.factory.makeBranchMergeProposal( | 579 | bmp = self.factory.makeBranchMergeProposal( |
547 | 576 | prerequisite_branch=prerequisite_branch) | 580 | prerequisite_branch=prerequisite_branch) |
548 | 577 | target_branch = self.createBzrBranch(bmp.target_branch) | 581 | target_branch = self.createBzrBranch(bmp.target_branch) |
551 | 578 | old_revision_id = self.commitFile( | 582 | old_revision_id = commit_file(bmp.target_branch, 'foo', 'a\nb\ne\n') |
550 | 579 | bmp.target_branch, 'foo', 'a\nb\ne\n') | ||
552 | 580 | old_revision = self.factory.makeRevision(rev_id=old_revision_id) | 583 | old_revision = self.factory.makeRevision(rev_id=old_revision_id) |
553 | 581 | source_branch = self.createBzrBranch( | 584 | source_branch = self.createBzrBranch( |
554 | 582 | bmp.source_branch, target_branch) | 585 | bmp.source_branch, target_branch) |
556 | 583 | self.commitFile(bmp.source_branch, 'foo', 'a\nc\ne\n') | 586 | commit_file(bmp.source_branch, 'foo', 'a\nc\ne\n') |
557 | 584 | prerequisite = self.createBzrBranch( | 587 | prerequisite = self.createBzrBranch( |
558 | 585 | bmp.prerequisite_branch, target_branch) | 588 | bmp.prerequisite_branch, target_branch) |
563 | 586 | prerequisite_revision = self.commitFile(bmp.prerequisite_branch, | 589 | prerequisite_revision = commit_file( |
564 | 587 | 'foo', 'd\na\nb\ne\n') | 590 | bmp.prerequisite_branch, 'foo', 'd\na\nb\ne\n') |
565 | 588 | merge_parent = self.commitFile(bmp.target_branch, 'foo', | 591 | merge_parent = commit_file(bmp.target_branch, 'foo', 'a\nb\ne\nf\n') |
562 | 589 | 'a\nb\ne\nf\n') | ||
566 | 590 | source_branch.repository.fetch(target_branch.repository, | 592 | source_branch.repository.fetch(target_branch.repository, |
567 | 591 | revision_id=merge_parent) | 593 | revision_id=merge_parent) |
570 | 592 | self.commitFile( | 594 | commit_file(bmp.source_branch, 'foo', 'a\nc\ne\nf\n', [merge_parent]) |
569 | 593 | bmp.source_branch, 'foo', 'a\nc\ne\nf\n', [merge_parent]) | ||
571 | 594 | source_branch.repository.fetch(prerequisite.repository, | 595 | source_branch.repository.fetch(prerequisite.repository, |
572 | 595 | revision_id=prerequisite_revision) | 596 | revision_id=prerequisite_revision) |
574 | 596 | new_revision_id = self.commitFile( | 597 | new_revision_id = commit_file( |
575 | 597 | bmp.source_branch, 'foo', 'd\na\nc\ne\nf\n', | 598 | bmp.source_branch, 'foo', 'd\na\nc\ne\nf\n', |
576 | 598 | [prerequisite_revision]) | 599 | [prerequisite_revision]) |
577 | 599 | new_revision = self.factory.makeRevision(rev_id=new_revision_id) | 600 | new_revision = self.factory.makeRevision(rev_id=new_revision_id) |
578 | 600 | 601 | ||
579 | === modified file 'lib/lp/code/scripts/tests/test_merge_proposal_jobs.py' | |||
580 | --- lib/lp/code/scripts/tests/test_merge_proposal_jobs.py 2010-10-04 19:50:45 +0000 | |||
581 | +++ lib/lp/code/scripts/tests/test_merge_proposal_jobs.py 2010-11-05 14:03:38 +0000 | |||
582 | @@ -7,8 +7,14 @@ | |||
583 | 7 | 7 | ||
584 | 8 | import unittest | 8 | import unittest |
585 | 9 | 9 | ||
586 | 10 | import transaction | ||
587 | 11 | |||
588 | 10 | from canonical.launchpad.scripts.tests import run_script | 12 | from canonical.launchpad.scripts.tests import run_script |
589 | 11 | from canonical.testing.layers import ZopelessAppServerLayer | 13 | from canonical.testing.layers import ZopelessAppServerLayer |
590 | 14 | from lp.code.model.tests.test_branchmergeproposaljobs import ( | ||
591 | 15 | make_runnable_incremental_diff_job | ||
592 | 16 | ) | ||
593 | 17 | from lp.services.job.interfaces.job import JobStatus | ||
594 | 12 | from lp.testing import TestCaseWithFactory | 18 | from lp.testing import TestCaseWithFactory |
595 | 13 | 19 | ||
596 | 14 | 20 | ||
597 | @@ -18,6 +24,8 @@ | |||
598 | 18 | 24 | ||
599 | 19 | def test_script_runs(self): | 25 | def test_script_runs(self): |
600 | 20 | """Ensure merge-proposal-jobs script runs.""" | 26 | """Ensure merge-proposal-jobs script runs.""" |
601 | 27 | job = make_runnable_incremental_diff_job(self) | ||
602 | 28 | transaction.commit() | ||
603 | 21 | retcode, stdout, stderr = run_script( | 29 | retcode, stdout, stderr = run_script( |
604 | 22 | 'cronscripts/merge-proposal-jobs.py', []) | 30 | 'cronscripts/merge-proposal-jobs.py', []) |
605 | 23 | self.assertEqual(0, retcode) | 31 | self.assertEqual(0, retcode) |
606 | @@ -25,7 +33,10 @@ | |||
607 | 25 | self.assertEqual( | 33 | self.assertEqual( |
608 | 26 | 'INFO Creating lockfile:' | 34 | 'INFO Creating lockfile:' |
609 | 27 | ' /var/lock/launchpad-merge-proposal-jobs.lock\n' | 35 | ' /var/lock/launchpad-merge-proposal-jobs.lock\n' |
611 | 28 | 'INFO Running through Twisted.\n', stderr) | 36 | 'INFO Running through Twisted.\n' |
612 | 37 | 'INFO Ran 1 GenerateIncrementalDiffJob jobs.\n', stderr) | ||
613 | 38 | self.assertEqual(JobStatus.COMPLETED, job.status) | ||
614 | 39 | |||
615 | 29 | 40 | ||
616 | 30 | def test_suite(): | 41 | def test_suite(): |
617 | 31 | return unittest.TestLoader().loadTestsFromName(__name__) | 42 | return unittest.TestLoader().loadTestsFromName(__name__) |
618 | 32 | 43 | ||
619 | === modified file 'lib/lp/codehosting/scanner/tests/test_bzrsync.py' | |||
620 | --- lib/lp/codehosting/scanner/tests/test_bzrsync.py 2010-10-26 15:47:24 +0000 | |||
621 | +++ lib/lp/codehosting/scanner/tests/test_bzrsync.py 2010-11-05 14:03:38 +0000 | |||
622 | @@ -31,11 +31,14 @@ | |||
623 | 31 | from lp.code.interfaces.branchlookup import IBranchLookup | 31 | from lp.code.interfaces.branchlookup import IBranchLookup |
624 | 32 | from lp.code.interfaces.revision import IRevisionSet | 32 | from lp.code.interfaces.revision import IRevisionSet |
625 | 33 | from lp.code.model.branchrevision import BranchRevision | 33 | from lp.code.model.branchrevision import BranchRevision |
626 | 34 | from lp.code.model.branchmergeproposaljob import ( | ||
627 | 35 | BranchMergeProposalJobSource, BranchMergeProposalJobType) | ||
628 | 34 | from lp.code.model.revision import ( | 36 | from lp.code.model.revision import ( |
629 | 35 | Revision, | 37 | Revision, |
630 | 36 | RevisionAuthor, | 38 | RevisionAuthor, |
631 | 37 | RevisionParent, | 39 | RevisionParent, |
632 | 38 | ) | 40 | ) |
633 | 41 | from lp.code.model.tests.test_diff import commit_file | ||
634 | 39 | from lp.codehosting.bzrutils import write_locked | 42 | from lp.codehosting.bzrutils import write_locked |
635 | 40 | from lp.codehosting.scanner.bzrsync import BzrSync | 43 | from lp.codehosting.scanner.bzrsync import BzrSync |
636 | 41 | from lp.services.osutils import override_environ | 44 | from lp.services.osutils import override_environ |
637 | @@ -654,6 +657,37 @@ | |||
638 | 654 | self.assertIsNot(None, bmp.next_preview_diff_job) | 657 | self.assertIsNot(None, bmp.next_preview_diff_job) |
639 | 655 | 658 | ||
640 | 656 | 659 | ||
641 | 660 | class TestGenerateIncrementalDiffJob(BzrSyncTestCase): | ||
642 | 661 | """Test the scheduling of GenerateIncrementalDiffJobs.""" | ||
643 | 662 | |||
644 | 663 | def getPending(self): | ||
645 | 664 | return list( | ||
646 | 665 | BranchMergeProposalJobSource.iterReady( | ||
647 | 666 | BranchMergeProposalJobType.GENERATE_INCREMENTAL_DIFF | ||
648 | 667 | ) | ||
649 | 668 | ) | ||
650 | 669 | |||
651 | 670 | @run_as_db_user(config.launchpad.dbuser) | ||
652 | 671 | def test_create_on_new_revision(self): | ||
653 | 672 | """When branch tip changes, a job is created.""" | ||
654 | 673 | parent_id = commit_file(self.db_branch, 'foo', 'bar') | ||
655 | 674 | self.factory.makeBranchRevision(self.db_branch, parent_id, | ||
656 | 675 | revision_date=self.factory.getUniqueDate()) | ||
657 | 676 | self.db_branch.last_scanned_id = parent_id | ||
658 | 677 | bmp = self.factory.makeBranchMergeProposal( | ||
659 | 678 | source_branch=self.db_branch, | ||
660 | 679 | date_created=self.factory.getUniqueDate()) | ||
661 | 680 | revision_id = commit_file(self.db_branch, 'foo', 'baz') | ||
662 | 681 | removeSecurityProxy(bmp).target_branch.last_scanned_id = 'rev' | ||
663 | 682 | self.assertEqual([], self.getPending()) | ||
664 | 683 | transaction.commit() | ||
665 | 684 | LaunchpadZopelessLayer.switchDbUser(config.branchscanner.dbuser) | ||
666 | 685 | self.makeBzrSync(self.db_branch).syncBranchAndClose() | ||
667 | 686 | (job,) = self.getPending() | ||
668 | 687 | self.assertEqual(revision_id, job.new_revision_id) | ||
669 | 688 | self.assertEqual(parent_id, job.old_revision_id) | ||
670 | 689 | |||
671 | 690 | |||
672 | 657 | class TestSetRecipeStale(BzrSyncTestCase): | 691 | class TestSetRecipeStale(BzrSyncTestCase): |
673 | 658 | """Test recipes associated with the branch are marked stale.""" | 692 | """Test recipes associated with the branch are marked stale.""" |
674 | 659 | 693 |
Hi Aaron,
Nice branch, just a few things that need fixing before it lands:
* On line 94 of the diff, you need to indent the closing parenthesis by 4 more spaces. rementalDiffJob .
* On line 302 you need to add a \n after the opening bracket of the clauses list. You also need to fix the indentation of the list items so that they're four-spaces in from clauses = [ line.
* You need to add docstrings / comments for the last four tests in TestGenerateInc