Merge lp:~jelmer/launchpad/no-code-import-approval into lp:launchpad
- no-code-import-approval
- Merge into devel
Proposed by
Jelmer Vernooij
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~jelmer/launchpad/no-code-import-approval | ||||
Merge into: | lp:launchpad | ||||
Diff against target: |
557 lines (+77/-122) 12 files modified
lib/lp/code/doc/codeimport-event.txt (+5/-5) lib/lp/code/doc/codeimport.txt (+1/-5) lib/lp/code/model/codeimport.py (+4/-8) lib/lp/code/model/tests/test_branch.py (+0/-2) lib/lp/code/model/tests/test_codeimport.py (+12/-40) lib/lp/code/model/tests/test_codeimportjob.py (+16/-11) lib/lp/code/stories/codeimport/xx-admin-codeimport.txt (+3/-20) lib/lp/code/stories/codeimport/xx-create-codeimport.txt (+9/-4) lib/lp/code/stories/codeimport/xx-edit-codeimport.txt (+3/-1) lib/lp/code/stories/webservice/xx-code-import.txt (+2/-2) lib/lp/testing/factory.py (+11/-13) utilities/sourcedeps.cache (+11/-11) |
||||
To merge this branch: | bzr merge lp:~jelmer/launchpad/no-code-import-approval | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Launchpad code reviewers | Pending | ||
Review via email:
|
This proposal has been superseded by a proposal from 2011-08-28.
Commit message
Description of the change
Remove the requirement for svn and cvs imports to be pre-approved by a Launchpad admin, fixing bug #418932.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/code/doc/codeimport-event.txt' | |||
2 | --- lib/lp/code/doc/codeimport-event.txt 2010-10-18 22:24:59 +0000 | |||
3 | +++ lib/lp/code/doc/codeimport-event.txt 2011-08-28 19:23:29 +0000 | |||
4 | @@ -120,7 +120,7 @@ | |||
5 | 120 | >>> print_items(svn_create_event) | 120 | >>> print_items(svn_create_event) |
6 | 121 | CODE_IMPORT <muted> | 121 | CODE_IMPORT <muted> |
7 | 122 | OWNER ... | 122 | OWNER ... |
9 | 123 | REVIEW_STATUS u'NEW' | 123 | REVIEW_STATUS u'REVIEWED' |
10 | 124 | ASSIGNEE None | 124 | ASSIGNEE None |
11 | 125 | UPDATE_INTERVAL None | 125 | UPDATE_INTERVAL None |
12 | 126 | URL u'svn://svn.example.com/trunk' | 126 | URL u'svn://svn.example.com/trunk' |
13 | @@ -144,7 +144,7 @@ | |||
14 | 144 | >>> print_items(cvs_create_event) | 144 | >>> print_items(cvs_create_event) |
15 | 145 | CODE_IMPORT <muted> | 145 | CODE_IMPORT <muted> |
16 | 146 | OWNER ... | 146 | OWNER ... |
18 | 147 | REVIEW_STATUS u'NEW' | 147 | REVIEW_STATUS u'REVIEWED' |
19 | 148 | ASSIGNEE None | 148 | ASSIGNEE None |
20 | 149 | UPDATE_INTERVAL None | 149 | UPDATE_INTERVAL None |
21 | 150 | CVS_ROOT u':pserver:anonymous@cvs.example.com:/cvsroot' | 150 | CVS_ROOT u':pserver:anonymous@cvs.example.com:/cvsroot' |
22 | @@ -206,7 +206,7 @@ | |||
23 | 206 | 206 | ||
24 | 207 | >>> from lp.code.enums import CodeImportReviewStatus | 207 | >>> from lp.code.enums import CodeImportReviewStatus |
25 | 208 | >>> removeSecurityProxy(svn_import).review_status = ( | 208 | >>> removeSecurityProxy(svn_import).review_status = ( |
27 | 209 | ... CodeImportReviewStatus.REVIEWED) | 209 | ... CodeImportReviewStatus.SUSPENDED) |
28 | 210 | 210 | ||
29 | 211 | After applying changes, the newModify method can create an event that | 211 | After applying changes, the newModify method can create an event that |
30 | 212 | details the changes that have been applied. | 212 | details the changes that have been applied. |
31 | @@ -234,8 +234,8 @@ | |||
32 | 234 | >>> print_items(modify_event) | 234 | >>> print_items(modify_event) |
33 | 235 | CODE_IMPORT <muted> | 235 | CODE_IMPORT <muted> |
34 | 236 | OWNER ... | 236 | OWNER ... |
37 | 237 | REVIEW_STATUS u'REVIEWED' | 237 | REVIEW_STATUS u'SUSPENDED' |
38 | 238 | OLD_REVIEW_STATUS u'NEW' | 238 | OLD_REVIEW_STATUS u'REVIEWED' |
39 | 239 | ASSIGNEE None | 239 | ASSIGNEE None |
40 | 240 | UPDATE_INTERVAL None | 240 | UPDATE_INTERVAL None |
41 | 241 | URL u'svn://svn.example.com/trunk' | 241 | URL u'svn://svn.example.com/trunk' |
42 | 242 | 242 | ||
43 | === modified file 'lib/lp/code/doc/codeimport.txt' | |||
44 | --- lib/lp/code/doc/codeimport.txt 2011-06-28 17:13:42 +0000 | |||
45 | +++ lib/lp/code/doc/codeimport.txt 2011-08-28 19:23:29 +0000 | |||
46 | @@ -243,7 +243,7 @@ | |||
47 | 243 | >>> code_import = factory.makeProductCodeImport( | 243 | >>> code_import = factory.makeProductCodeImport( |
48 | 244 | ... svn_branch_url='http://svn.example.com/project') | 244 | ... svn_branch_url='http://svn.example.com/project') |
49 | 245 | >>> print code_import.review_status.title | 245 | >>> print code_import.review_status.title |
51 | 246 | Pending Review | 246 | Reviewed |
52 | 247 | 247 | ||
53 | 248 | When an import operator updates the code import emails are sent out to | 248 | When an import operator updates the code import emails are sent out to |
54 | 249 | the branch subscribers and members of VCS Imports that describe the | 249 | the branch subscribers and members of VCS Imports that describe the |
55 | @@ -275,8 +275,6 @@ | |||
56 | 275 | To: david.allouche@canonical.com, ... | 275 | To: david.allouche@canonical.com, ... |
57 | 276 | Subject: Code import product.../name... status: Reviewed | 276 | Subject: Code import product.../name... status: Reviewed |
58 | 277 | <BLANKLINE> | 277 | <BLANKLINE> |
59 | 278 | The import has been approved and an import will start shortly. | ||
60 | 279 | <BLANKLINE> | ||
61 | 280 | ... is now being imported from: | 278 | ... is now being imported from: |
62 | 281 | http://svn.example.com/project/trunk | 279 | http://svn.example.com/project/trunk |
63 | 282 | instead of: | 280 | instead of: |
64 | @@ -293,8 +291,6 @@ | |||
65 | 293 | To: import@example.com | 291 | To: import@example.com |
66 | 294 | Subject: Code import product.../name... status: Reviewed | 292 | Subject: Code import product.../name... status: Reviewed |
67 | 295 | <BLANKLINE> | 293 | <BLANKLINE> |
68 | 296 | The import has been approved and an import will start shortly. | ||
69 | 297 | <BLANKLINE> | ||
70 | 298 | ... is now being imported from: | 294 | ... is now being imported from: |
71 | 299 | http://svn.example.com/project/trunk | 295 | http://svn.example.com/project/trunk |
72 | 300 | instead of: | 296 | instead of: |
73 | 301 | 297 | ||
74 | === modified file 'lib/lp/code/model/codeimport.py' | |||
75 | --- lib/lp/code/model/codeimport.py 2011-08-24 21:17:35 +0000 | |||
76 | +++ lib/lp/code/model/codeimport.py 2011-08-28 19:23:29 +0000 | |||
77 | @@ -198,7 +198,8 @@ | |||
78 | 198 | setattr(self, name, value) | 198 | setattr(self, name, value) |
79 | 199 | if 'review_status' in data: | 199 | if 'review_status' in data: |
80 | 200 | if data['review_status'] == CodeImportReviewStatus.REVIEWED: | 200 | if data['review_status'] == CodeImportReviewStatus.REVIEWED: |
82 | 201 | CodeImportJobWorkflow().newJob(self) | 201 | if self.import_job is None: |
83 | 202 | CodeImportJobWorkflow().newJob(self) | ||
84 | 202 | else: | 203 | else: |
85 | 203 | self._removeJob() | 204 | self._removeJob() |
86 | 204 | event = event_set.newModify(self, user, token) | 205 | event = event_set.newModify(self, user, token) |
87 | @@ -264,13 +265,8 @@ | |||
88 | 264 | "Don't know how to sanity check source details for unknown " | 265 | "Don't know how to sanity check source details for unknown " |
89 | 265 | "rcs_type %s"%rcs_type) | 266 | "rcs_type %s"%rcs_type) |
90 | 266 | if review_status is None: | 267 | if review_status is None: |
98 | 267 | # Auto approve git and hg imports. | 268 | # Auto approve imports. |
99 | 268 | if rcs_type in ( | 269 | review_status = CodeImportReviewStatus.REVIEWED |
93 | 269 | RevisionControlSystems.GIT, RevisionControlSystems.HG, | ||
94 | 270 | RevisionControlSystems.BZR): | ||
95 | 271 | review_status = CodeImportReviewStatus.REVIEWED | ||
96 | 272 | else: | ||
97 | 273 | review_status = CodeImportReviewStatus.NEW | ||
100 | 274 | if not target.supports_code_imports: | 270 | if not target.supports_code_imports: |
101 | 275 | raise AssertionError("%r doesn't support code imports" % target) | 271 | raise AssertionError("%r doesn't support code imports" % target) |
102 | 276 | if owner is None: | 272 | if owner is None: |
103 | 277 | 273 | ||
104 | === modified file 'lib/lp/code/model/tests/test_branch.py' | |||
105 | --- lib/lp/code/model/tests/test_branch.py 2011-08-24 16:21:07 +0000 | |||
106 | +++ lib/lp/code/model/tests/test_branch.py 2011-08-28 19:23:29 +0000 | |||
107 | @@ -1510,7 +1510,6 @@ | |||
108 | 1510 | """break_links allows deleting a code import branch.""" | 1510 | """break_links allows deleting a code import branch.""" |
109 | 1511 | code_import = self.factory.makeCodeImport() | 1511 | code_import = self.factory.makeCodeImport() |
110 | 1512 | code_import_id = code_import.id | 1512 | code_import_id = code_import.id |
111 | 1513 | self.factory.makeCodeImportJob(code_import) | ||
112 | 1514 | code_import.branch.destroySelf(break_references=True) | 1513 | code_import.branch.destroySelf(break_references=True) |
113 | 1515 | self.assertRaises( | 1514 | self.assertRaises( |
114 | 1516 | SQLObjectNotFound, CodeImport.get, code_import_id) | 1515 | SQLObjectNotFound, CodeImport.get, code_import_id) |
115 | @@ -1575,7 +1574,6 @@ | |||
116 | 1575 | """DeleteCodeImport.__call__ must delete the CodeImport.""" | 1574 | """DeleteCodeImport.__call__ must delete the CodeImport.""" |
117 | 1576 | code_import = self.factory.makeCodeImport() | 1575 | code_import = self.factory.makeCodeImport() |
118 | 1577 | code_import_id = code_import.id | 1576 | code_import_id = code_import.id |
119 | 1578 | self.factory.makeCodeImportJob(code_import) | ||
120 | 1579 | DeleteCodeImport(code_import)() | 1577 | DeleteCodeImport(code_import)() |
121 | 1580 | self.assertRaises( | 1578 | self.assertRaises( |
122 | 1581 | SQLObjectNotFound, CodeImport.get, code_import_id) | 1579 | SQLObjectNotFound, CodeImport.get, code_import_id) |
123 | 1582 | 1580 | ||
124 | === modified file 'lib/lp/code/model/tests/test_codeimport.py' | |||
125 | --- lib/lp/code/model/tests/test_codeimport.py 2011-08-28 08:36:14 +0000 | |||
126 | +++ lib/lp/code/model/tests/test_codeimport.py 2011-08-28 19:23:29 +0000 | |||
127 | @@ -56,20 +56,6 @@ | |||
128 | 56 | 56 | ||
129 | 57 | layer = DatabaseFunctionalLayer | 57 | layer = DatabaseFunctionalLayer |
130 | 58 | 58 | ||
131 | 59 | def test_new_svn_import(self): | ||
132 | 60 | """A new subversion code import should have NEW status.""" | ||
133 | 61 | code_import = CodeImportSet().new( | ||
134 | 62 | registrant=self.factory.makePerson(), | ||
135 | 63 | target=IBranchTarget(self.factory.makeProduct()), | ||
136 | 64 | branch_name='imported', | ||
137 | 65 | rcs_type=RevisionControlSystems.SVN, | ||
138 | 66 | url=self.factory.getUniqueURL()) | ||
139 | 67 | self.assertEqual( | ||
140 | 68 | CodeImportReviewStatus.NEW, | ||
141 | 69 | code_import.review_status) | ||
142 | 70 | # No job is created for the import. | ||
143 | 71 | self.assertIs(None, code_import.import_job) | ||
144 | 72 | |||
145 | 73 | def test_new_svn_import_svn_scheme(self): | 59 | def test_new_svn_import_svn_scheme(self): |
146 | 74 | """A subversion import can use the svn:// scheme.""" | 60 | """A subversion import can use the svn:// scheme.""" |
147 | 75 | code_import = CodeImportSet().new( | 61 | code_import = CodeImportSet().new( |
148 | @@ -79,10 +65,10 @@ | |||
149 | 79 | rcs_type=RevisionControlSystems.SVN, | 65 | rcs_type=RevisionControlSystems.SVN, |
150 | 80 | url=self.factory.getUniqueURL(scheme="svn")) | 66 | url=self.factory.getUniqueURL(scheme="svn")) |
151 | 81 | self.assertEqual( | 67 | self.assertEqual( |
153 | 82 | CodeImportReviewStatus.NEW, | 68 | CodeImportReviewStatus.REVIEWED, |
154 | 83 | code_import.review_status) | 69 | code_import.review_status) |
155 | 84 | # No job is created for the import. | 70 | # No job is created for the import. |
157 | 85 | self.assertIs(None, code_import.import_job) | 71 | self.assertIsNot(None, code_import.import_job) |
158 | 86 | 72 | ||
159 | 87 | def test_reviewed_svn_import(self): | 73 | def test_reviewed_svn_import(self): |
160 | 88 | """A specific review status can be set for a new import.""" | 74 | """A specific review status can be set for a new import.""" |
161 | @@ -92,30 +78,15 @@ | |||
162 | 92 | branch_name='imported', | 78 | branch_name='imported', |
163 | 93 | rcs_type=RevisionControlSystems.SVN, | 79 | rcs_type=RevisionControlSystems.SVN, |
164 | 94 | url=self.factory.getUniqueURL(), | 80 | url=self.factory.getUniqueURL(), |
166 | 95 | review_status=CodeImportReviewStatus.REVIEWED) | 81 | review_status=None) |
167 | 96 | self.assertEqual( | 82 | self.assertEqual( |
168 | 97 | CodeImportReviewStatus.REVIEWED, | 83 | CodeImportReviewStatus.REVIEWED, |
169 | 98 | code_import.review_status) | 84 | code_import.review_status) |
170 | 99 | # A job is created for the import. | 85 | # A job is created for the import. |
171 | 100 | self.assertIsNot(None, code_import.import_job) | 86 | self.assertIsNot(None, code_import.import_job) |
172 | 101 | 87 | ||
190 | 102 | def test_new_cvs_import(self): | 88 | def test_cvs_import_reviewed(self): |
191 | 103 | """A new CVS code import should have NEW status.""" | 89 | """A new CVS code import should have REVIEWED status.""" |
175 | 104 | code_import = CodeImportSet().new( | ||
176 | 105 | registrant=self.factory.makePerson(), | ||
177 | 106 | target=IBranchTarget(self.factory.makeProduct()), | ||
178 | 107 | branch_name='imported', | ||
179 | 108 | rcs_type=RevisionControlSystems.CVS, | ||
180 | 109 | cvs_root=self.factory.getUniqueURL(), | ||
181 | 110 | cvs_module='module') | ||
182 | 111 | self.assertEqual( | ||
183 | 112 | CodeImportReviewStatus.NEW, | ||
184 | 113 | code_import.review_status) | ||
185 | 114 | # No job is created for the import. | ||
186 | 115 | self.assertIs(None, code_import.import_job) | ||
187 | 116 | |||
188 | 117 | def test_reviewed_cvs_import(self): | ||
189 | 118 | """A specific review status can be set for a new import.""" | ||
192 | 119 | code_import = CodeImportSet().new( | 90 | code_import = CodeImportSet().new( |
193 | 120 | registrant=self.factory.makePerson(), | 91 | registrant=self.factory.makePerson(), |
194 | 121 | target=IBranchTarget(self.factory.makeProduct()), | 92 | target=IBranchTarget(self.factory.makeProduct()), |
195 | @@ -123,7 +94,7 @@ | |||
196 | 123 | rcs_type=RevisionControlSystems.CVS, | 94 | rcs_type=RevisionControlSystems.CVS, |
197 | 124 | cvs_root=self.factory.getUniqueURL(), | 95 | cvs_root=self.factory.getUniqueURL(), |
198 | 125 | cvs_module='module', | 96 | cvs_module='module', |
200 | 126 | review_status=CodeImportReviewStatus.REVIEWED) | 97 | review_status=None) |
201 | 127 | self.assertEqual( | 98 | self.assertEqual( |
202 | 128 | CodeImportReviewStatus.REVIEWED, | 99 | CodeImportReviewStatus.REVIEWED, |
203 | 129 | code_import.review_status) | 100 | code_import.review_status) |
204 | @@ -275,8 +246,7 @@ | |||
205 | 275 | """Ensure deleting CodeImport objects deletes associated jobs.""" | 246 | """Ensure deleting CodeImport objects deletes associated jobs.""" |
206 | 276 | code_import = self.factory.makeCodeImport() | 247 | code_import = self.factory.makeCodeImport() |
207 | 277 | login_person(getUtility(ILaunchpadCelebrities).vcs_imports.teamowner) | 248 | login_person(getUtility(ILaunchpadCelebrities).vcs_imports.teamowner) |
210 | 278 | code_import_job = self.factory.makeCodeImportJob(code_import) | 249 | job_id = code_import.import_job.id |
209 | 279 | job_id = code_import_job.id | ||
211 | 280 | CodeImportJobSet().getById(job_id) | 250 | CodeImportJobSet().getById(job_id) |
212 | 281 | job = CodeImportJobSet().getById(job_id) | 251 | job = CodeImportJobSet().getById(job_id) |
213 | 282 | assert job is not None | 252 | assert job is not None |
214 | @@ -644,7 +614,8 @@ | |||
215 | 644 | # tryFailingImportAgain only succeeds for imports that are FAILING. | 614 | # tryFailingImportAgain only succeeds for imports that are FAILING. |
216 | 645 | outcomes = {} | 615 | outcomes = {} |
217 | 646 | for status in CodeImportReviewStatus.items: | 616 | for status in CodeImportReviewStatus.items: |
219 | 647 | code_import = self.factory.makeCodeImport() | 617 | code_import = self.factory.makeCodeImport( |
220 | 618 | review_status=CodeImportReviewStatus.NEW) | ||
221 | 648 | code_import.updateFromData( | 619 | code_import.updateFromData( |
222 | 649 | {'review_status': status}, self.factory.makePerson()) | 620 | {'review_status': status}, self.factory.makePerson()) |
223 | 650 | try: | 621 | try: |
224 | @@ -726,9 +697,10 @@ | |||
225 | 726 | self.assertEqual(requester, e.requesting_user) | 697 | self.assertEqual(requester, e.requesting_user) |
226 | 727 | 698 | ||
227 | 728 | def test_exception_on_disabled(self): | 699 | def test_exception_on_disabled(self): |
229 | 729 | # get an SVN request, which isn't reviewed by default | 700 | # get an SVN request which is suspended |
230 | 730 | code_import = self.factory.makeCodeImport( | 701 | code_import = self.factory.makeCodeImport( |
232 | 731 | svn_branch_url=self.factory.getUniqueURL()) | 702 | svn_branch_url=self.factory.getUniqueURL(), |
233 | 703 | review_status=CodeImportReviewStatus.SUSPENDED) | ||
234 | 732 | requester = self.factory.makePerson() | 704 | requester = self.factory.makePerson() |
235 | 733 | # which leads to an exception if we try and ask for an import | 705 | # which leads to an exception if we try and ask for an import |
236 | 734 | self.assertRaises( | 706 | self.assertRaises( |
237 | 735 | 707 | ||
238 | === modified file 'lib/lp/code/model/tests/test_codeimportjob.py' | |||
239 | --- lib/lp/code/model/tests/test_codeimportjob.py 2011-06-29 12:00:39 +0000 | |||
240 | +++ lib/lp/code/model/tests/test_codeimportjob.py 2011-08-28 19:23:29 +0000 | |||
241 | @@ -115,7 +115,8 @@ | |||
242 | 115 | 115 | ||
243 | 116 | def makeJob(self, state, date_due_delta, requesting_user=None): | 116 | def makeJob(self, state, date_due_delta, requesting_user=None): |
244 | 117 | """Create a CodeImportJob object from a spec.""" | 117 | """Create a CodeImportJob object from a spec.""" |
246 | 118 | code_import = self.factory.makeCodeImport() | 118 | code_import = self.factory.makeCodeImport( |
247 | 119 | review_status=CodeImportReviewStatus.NEW) | ||
248 | 119 | job = self.factory.makeCodeImportJob(code_import) | 120 | job = self.factory.makeCodeImportJob(code_import) |
249 | 120 | if state == CodeImportJobState.RUNNING: | 121 | if state == CodeImportJobState.RUNNING: |
250 | 121 | getUtility(ICodeImportJobWorkflow).startJob(job, self.machine) | 122 | getUtility(ICodeImportJobWorkflow).startJob(job, self.machine) |
251 | @@ -387,11 +388,12 @@ | |||
252 | 387 | def test_wrongReviewStatus(self): | 388 | def test_wrongReviewStatus(self): |
253 | 388 | # CodeImportJobWorkflow.newJob fails if the CodeImport review_status | 389 | # CodeImportJobWorkflow.newJob fails if the CodeImport review_status |
254 | 389 | # is different from REVIEWED. | 390 | # is different from REVIEWED. |
256 | 390 | new_import = self.factory.makeCodeImport() | 391 | new_import = self.factory.makeCodeImport( |
257 | 392 | review_status=CodeImportReviewStatus.SUSPENDED) | ||
258 | 391 | branch_name = new_import.branch.unique_name | 393 | branch_name = new_import.branch.unique_name |
259 | 392 | # Testing newJob failure. | 394 | # Testing newJob failure. |
260 | 393 | self.assertFailure( | 395 | self.assertFailure( |
262 | 394 | "Review status of %s is not REVIEWED: NEW" % (branch_name,), | 396 | "Review status of %s is not REVIEWED: SUSPENDED" % (branch_name,), |
263 | 395 | getUtility(ICodeImportJobWorkflow).newJob, new_import) | 397 | getUtility(ICodeImportJobWorkflow).newJob, new_import) |
264 | 396 | 398 | ||
265 | 397 | def test_existingJob(self): | 399 | def test_existingJob(self): |
266 | @@ -417,14 +419,17 @@ | |||
267 | 417 | # If there is no CodeImportResult for the CodeImport, then the new | 419 | # If there is no CodeImportResult for the CodeImport, then the new |
268 | 418 | # CodeImportJob has date_due set to UTC_NOW. | 420 | # CodeImportJob has date_due set to UTC_NOW. |
269 | 419 | code_import = self.getCodeImportForDateDueTest() | 421 | code_import = self.getCodeImportForDateDueTest() |
272 | 420 | job = getUtility(ICodeImportJobWorkflow).newJob(code_import) | 422 | self.assertSqlAttributeEqualsDate(code_import.import_job, 'date_due', |
273 | 421 | self.assertSqlAttributeEqualsDate(job, 'date_due', UTC_NOW) | 423 | UTC_NOW) |
274 | 422 | 424 | ||
275 | 423 | def test_dateDueRecentPreviousResult(self): | 425 | def test_dateDueRecentPreviousResult(self): |
276 | 424 | # If there is a CodeImportResult for the CodeImport that is more | 426 | # If there is a CodeImportResult for the CodeImport that is more |
277 | 425 | # recent than the effective_update_interval, then the new | 427 | # recent than the effective_update_interval, then the new |
278 | 426 | # CodeImportJob has date_due set in the future. | 428 | # CodeImportJob has date_due set in the future. |
279 | 427 | code_import = self.getCodeImportForDateDueTest() | 429 | code_import = self.getCodeImportForDateDueTest() |
280 | 430 | # A code import job is automatically started when a reviewed code import | ||
281 | 431 | # is created. Remove it, so a "clean" one can be created later. | ||
282 | 432 | removeSecurityProxy(code_import).import_job.destroySelf() | ||
283 | 428 | # Create a CodeImportResult that started a long time ago. This one | 433 | # Create a CodeImportResult that started a long time ago. This one |
284 | 429 | # must be superseded by the more recent one created below. | 434 | # must be superseded by the more recent one created below. |
285 | 430 | machine = self.factory.makeCodeImportMachine() | 435 | machine = self.factory.makeCodeImportMachine() |
286 | @@ -469,8 +474,8 @@ | |||
287 | 469 | date_job_started=datetime(2000, 1, 1, 12, 0, 0, tzinfo=UTC), | 474 | date_job_started=datetime(2000, 1, 1, 12, 0, 0, tzinfo=UTC), |
288 | 470 | date_created=datetime(2000, 1, 1, 12, 5, 0, tzinfo=UTC)) | 475 | date_created=datetime(2000, 1, 1, 12, 5, 0, tzinfo=UTC)) |
289 | 471 | # When we create the job, its date due must be set to UTC_NOW. | 476 | # When we create the job, its date due must be set to UTC_NOW. |
292 | 472 | job = getUtility(ICodeImportJobWorkflow).newJob(code_import) | 477 | self.assertSqlAttributeEqualsDate(code_import.import_job, 'date_due', |
293 | 473 | self.assertSqlAttributeEqualsDate(job, 'date_due', UTC_NOW) | 478 | UTC_NOW) |
294 | 474 | 479 | ||
295 | 475 | 480 | ||
296 | 476 | class TestCodeImportJobWorkflowDeletePendingJob(TestCaseWithFactory, | 481 | class TestCodeImportJobWorkflowDeletePendingJob(TestCaseWithFactory, |
297 | @@ -500,7 +505,8 @@ | |||
298 | 500 | def test_noJob(self): | 505 | def test_noJob(self): |
299 | 501 | # CodeImportJobWorkflow.deletePendingJob fails if the | 506 | # CodeImportJobWorkflow.deletePendingJob fails if the |
300 | 502 | # CodeImport is not associated to a CodeImportJob. | 507 | # CodeImport is not associated to a CodeImportJob. |
302 | 503 | new_import = self.factory.makeCodeImport() | 508 | new_import = self.factory.makeCodeImport( |
303 | 509 | review_status=CodeImportReviewStatus.NEW) | ||
304 | 504 | branch_name = new_import.branch.unique_name | 510 | branch_name = new_import.branch.unique_name |
305 | 505 | # Testing deletePendingJob failure. | 511 | # Testing deletePendingJob failure. |
306 | 506 | self.assertFailure( | 512 | self.assertFailure( |
307 | @@ -578,7 +584,7 @@ | |||
308 | 578 | # CodeImportJobWorkflow.requestJob sets requesting_user and | 584 | # CodeImportJobWorkflow.requestJob sets requesting_user and |
309 | 579 | # date_due if the current date_due is in the future. | 585 | # date_due if the current date_due is in the future. |
310 | 580 | code_import = self.factory.makeCodeImport() | 586 | code_import = self.factory.makeCodeImport() |
312 | 581 | pending_job = self.factory.makeCodeImportJob(code_import) | 587 | pending_job = code_import.import_job |
313 | 582 | person = self.factory.makePerson() | 588 | person = self.factory.makePerson() |
314 | 583 | # Set date_due in the future. ICodeImportJob does not allow setting | 589 | # Set date_due in the future. ICodeImportJob does not allow setting |
315 | 584 | # date_due, so we must use removeSecurityProxy. | 590 | # date_due, so we must use removeSecurityProxy. |
316 | @@ -877,8 +883,7 @@ | |||
317 | 877 | unchecked_result_fields.difference_update(['log_file', 'status']) | 883 | unchecked_result_fields.difference_update(['log_file', 'status']) |
318 | 878 | 884 | ||
319 | 879 | code_import = self.factory.makeCodeImport() | 885 | code_import = self.factory.makeCodeImport() |
322 | 880 | removeSecurityProxy(code_import).review_status = \ | 886 | removeSecurityProxy(code_import).import_job.destroySelf() |
321 | 881 | CodeImportReviewStatus.REVIEWED | ||
323 | 882 | self.assertFinishJobPassesThroughJobField( | 887 | self.assertFinishJobPassesThroughJobField( |
324 | 883 | 'code_import', 'code_import', code_import) | 888 | 'code_import', 'code_import', code_import) |
325 | 884 | unchecked_result_fields.remove('code_import') | 889 | unchecked_result_fields.remove('code_import') |
326 | 885 | 890 | ||
327 | === modified file 'lib/lp/code/stories/codeimport/xx-admin-codeimport.txt' | |||
328 | --- lib/lp/code/stories/codeimport/xx-admin-codeimport.txt 2010-04-28 02:49:58 +0000 | |||
329 | +++ lib/lp/code/stories/codeimport/xx-admin-codeimport.txt 2011-08-28 19:23:29 +0000 | |||
330 | @@ -61,9 +61,11 @@ | |||
331 | 61 | ... print extract_text(div) | 61 | ... print extract_text(div) |
332 | 62 | >>> import_browser.open(svn_import_location) | 62 | >>> import_browser.open(svn_import_location) |
333 | 63 | >>> print_import_details(import_browser) | 63 | >>> print_import_details(import_browser) |
335 | 64 | Import Status: Pending Review | 64 | Import Status: Reviewed |
336 | 65 | This branch is an import of the Subversion branch | 65 | This branch is an import of the Subversion branch |
337 | 66 | from svn://svn.example.com/fooix/trunk. | 66 | from svn://svn.example.com/fooix/trunk. |
338 | 67 | The next import is scheduled to run | ||
339 | 68 | as soon as possible. | ||
340 | 67 | Edit import source or review import | 69 | Edit import source or review import |
341 | 68 | 70 | ||
342 | 69 | 71 | ||
343 | @@ -76,7 +78,6 @@ | |||
344 | 76 | >>> import_browser.getLink('Edit import source or review import').click() | 78 | >>> import_browser.getLink('Edit import source or review import').click() |
345 | 77 | >>> print_submit_buttons(import_browser.contents) | 79 | >>> print_submit_buttons(import_browser.contents) |
346 | 78 | Update | 80 | Update |
347 | 79 | Approve | ||
348 | 80 | Mark Invalid | 81 | Mark Invalid |
349 | 81 | Suspend | 82 | Suspend |
350 | 82 | Mark Failing | 83 | Mark Failing |
351 | @@ -190,24 +191,6 @@ | |||
352 | 190 | The code import has been updated. | 191 | The code import has been updated. |
353 | 191 | 192 | ||
354 | 192 | 193 | ||
355 | 193 | Approving an import | ||
356 | 194 | +++++++++++++++++++ | ||
357 | 195 | |||
358 | 196 | When a code import is approved, a pending job is created for it. | ||
359 | 197 | |||
360 | 198 | >>> import_browser.open(svn_import_location + '/+edit-import') | ||
361 | 199 | >>> import_browser.getControl('Approve').click() | ||
362 | 200 | >>> print_import_details(import_browser) | ||
363 | 201 | Import Status: Reviewed | ||
364 | 202 | ... | ||
365 | 203 | The next import is scheduled to run as soon as possible. | ||
366 | 204 | Edit import source or review import | ||
367 | 205 | |||
368 | 206 | >>> for message in get_feedback_messages(import_browser.contents): | ||
369 | 207 | ... print extract_text(message) | ||
370 | 208 | The code import has been approved. | ||
371 | 209 | |||
372 | 210 | |||
373 | 211 | Invalidating an import | 194 | Invalidating an import |
374 | 212 | ++++++++++++++++++++++ | 195 | ++++++++++++++++++++++ |
375 | 213 | 196 | ||
376 | 214 | 197 | ||
377 | === modified file 'lib/lp/code/stories/codeimport/xx-create-codeimport.txt' | |||
378 | --- lib/lp/code/stories/codeimport/xx-create-codeimport.txt 2010-09-28 19:25:54 +0000 | |||
379 | +++ lib/lp/code/stories/codeimport/xx-create-codeimport.txt 2011-08-28 19:23:29 +0000 | |||
380 | @@ -72,9 +72,11 @@ | |||
381 | 72 | When the user clicks continue, the import branch is created | 72 | When the user clicks continue, the import branch is created |
382 | 73 | 73 | ||
383 | 74 | >>> print extract_text(find_tag_by_id(browser.contents, "import-details")) | 74 | >>> print extract_text(find_tag_by_id(browser.contents, "import-details")) |
385 | 75 | Import Status: Pending Review | 75 | Import Status: Reviewed |
386 | 76 | This branch is an import of the Subversion branch | 76 | This branch is an import of the Subversion branch |
387 | 77 | from http://svn.example.com/firefox/trunk. | 77 | from http://svn.example.com/firefox/trunk. |
388 | 78 | The next import is scheduled to run | ||
389 | 79 | as soon as possible. | ||
390 | 78 | >>> browser.getLink("http://svn.example.com/firefox/trunk") | 80 | >>> browser.getLink("http://svn.example.com/firefox/trunk") |
391 | 79 | <Link text='http://svn.example.com/firefox/trunk' | 81 | <Link text='http://svn.example.com/firefox/trunk' |
392 | 80 | url='http://svn.example.com/firefox/trunk'> | 82 | url='http://svn.example.com/firefox/trunk'> |
393 | @@ -98,9 +100,11 @@ | |||
394 | 98 | >>> browser.getControl('Project').value = "firefox" | 100 | >>> browser.getControl('Project').value = "firefox" |
395 | 99 | >>> browser.getControl('Request Import').click() | 101 | >>> browser.getControl('Request Import').click() |
396 | 100 | >>> print extract_text(find_tag_by_id(browser.contents, "import-details")) | 102 | >>> print extract_text(find_tag_by_id(browser.contents, "import-details")) |
398 | 101 | Import Status: Pending Review | 103 | Import Status: Reviewed |
399 | 102 | This branch is an import of the Subversion branch | 104 | This branch is an import of the Subversion branch |
400 | 103 | from http://user:password@svn.example.com/firefox/trunk. | 105 | from http://user:password@svn.example.com/firefox/trunk. |
401 | 106 | The next import is scheduled to run | ||
402 | 107 | as soon as possible. | ||
403 | 104 | 108 | ||
404 | 105 | 109 | ||
405 | 106 | Requesting a Git import | 110 | Requesting a Git import |
406 | @@ -165,10 +169,11 @@ | |||
407 | 165 | >>> browser.getControl('Request Import').click() | 169 | >>> browser.getControl('Request Import').click() |
408 | 166 | 170 | ||
409 | 167 | >>> print extract_text(find_tag_by_id(browser.contents, "import-details")) | 171 | >>> print extract_text(find_tag_by_id(browser.contents, "import-details")) |
411 | 168 | Import Status: Pending Review | 172 | Import Status: Reviewed |
412 | 169 | This branch is an import of the CVS module firefox from | 173 | This branch is an import of the CVS module firefox from |
413 | 170 | :pserver:anonymous@cvs.example.com:/mozilla/cvs. | 174 | :pserver:anonymous@cvs.example.com:/mozilla/cvs. |
415 | 171 | 175 | The next import is scheduled to run | |
416 | 176 | as soon as possible. | ||
417 | 172 | 177 | ||
418 | 173 | Requesting a CVS import with invalid information | 178 | Requesting a CVS import with invalid information |
419 | 174 | ================================================ | 179 | ================================================ |
420 | 175 | 180 | ||
421 | === modified file 'lib/lp/code/stories/codeimport/xx-edit-codeimport.txt' | |||
422 | --- lib/lp/code/stories/codeimport/xx-edit-codeimport.txt 2010-03-18 15:39:58 +0000 | |||
423 | +++ lib/lp/code/stories/codeimport/xx-edit-codeimport.txt 2011-08-28 19:23:29 +0000 | |||
424 | @@ -43,9 +43,11 @@ | |||
425 | 43 | ... print extract_text(div) | 43 | ... print extract_text(div) |
426 | 44 | >>> anon_browser.open(svn_import_location) | 44 | >>> anon_browser.open(svn_import_location) |
427 | 45 | >>> print_import_details(anon_browser) | 45 | >>> print_import_details(anon_browser) |
429 | 46 | Import Status: Pending Review | 46 | Import Status: Reviewed |
430 | 47 | This branch is an import of the Subversion branch | 47 | This branch is an import of the Subversion branch |
431 | 48 | from svn://svn.example.com/fooix/trunk. | 48 | from svn://svn.example.com/fooix/trunk. |
432 | 49 | The next import is scheduled to run | ||
433 | 50 | as soon as possible. | ||
434 | 49 | 51 | ||
435 | 50 | Because it's an svn:// URL, it doesn't get linkified: | 52 | Because it's an svn:// URL, it doesn't get linkified: |
436 | 51 | 53 | ||
437 | 52 | 54 | ||
438 | === modified file 'lib/lp/code/stories/webservice/xx-code-import.txt' | |||
439 | --- lib/lp/code/stories/webservice/xx-code-import.txt 2010-04-16 05:03:03 +0000 | |||
440 | +++ lib/lp/code/stories/webservice/xx-code-import.txt 2011-08-28 19:23:29 +0000 | |||
441 | @@ -55,7 +55,7 @@ | |||
442 | 55 | >>> print representation['branch_link'] | 55 | >>> print representation['branch_link'] |
443 | 56 | http://.../~import-owner/scruff/import | 56 | http://.../~import-owner/scruff/import |
444 | 57 | >>> print representation['review_status'] | 57 | >>> print representation['review_status'] |
446 | 58 | Pending Review | 58 | Reviewed |
447 | 59 | >>> print representation['rcs_type'] | 59 | >>> print representation['rcs_type'] |
448 | 60 | Subversion via CSCVS | 60 | Subversion via CSCVS |
449 | 61 | >>> print representation['url'] | 61 | >>> print representation['url'] |
450 | @@ -105,7 +105,7 @@ | |||
451 | 105 | >>> print representation['branch_link'] | 105 | >>> print representation['branch_link'] |
452 | 106 | http://.../~import-owner/scruffbuntu/manic/scruff/import | 106 | http://.../~import-owner/scruffbuntu/manic/scruff/import |
453 | 107 | >>> print representation['review_status'] | 107 | >>> print representation['review_status'] |
455 | 108 | Pending Review | 108 | Reviewed |
456 | 109 | >>> print representation['rcs_type'] | 109 | >>> print representation['rcs_type'] |
457 | 110 | Subversion via CSCVS | 110 | Subversion via CSCVS |
458 | 111 | >>> print representation['url'] | 111 | >>> print representation['url'] |
459 | 112 | 112 | ||
460 | === modified file 'lib/lp/testing/factory.py' | |||
461 | --- lib/lp/testing/factory.py 2011-08-27 16:28:52 +0000 | |||
462 | +++ lib/lp/testing/factory.py 2011-08-28 19:23:29 +0000 | |||
463 | @@ -2150,34 +2150,32 @@ | |||
464 | 2150 | else: | 2150 | else: |
465 | 2151 | assert rcs_type in (RevisionControlSystems.SVN, | 2151 | assert rcs_type in (RevisionControlSystems.SVN, |
466 | 2152 | RevisionControlSystems.BZR_SVN) | 2152 | RevisionControlSystems.BZR_SVN) |
468 | 2153 | code_import = code_import_set.new( | 2153 | return code_import_set.new( |
469 | 2154 | registrant, target, branch_name, rcs_type=rcs_type, | 2154 | registrant, target, branch_name, rcs_type=rcs_type, |
471 | 2155 | url=svn_branch_url) | 2155 | url=svn_branch_url, review_status=review_status) |
472 | 2156 | elif git_repo_url is not None: | 2156 | elif git_repo_url is not None: |
473 | 2157 | assert rcs_type in (None, RevisionControlSystems.GIT) | 2157 | assert rcs_type in (None, RevisionControlSystems.GIT) |
475 | 2158 | code_import = code_import_set.new( | 2158 | return code_import_set.new( |
476 | 2159 | registrant, target, branch_name, | 2159 | registrant, target, branch_name, |
477 | 2160 | rcs_type=RevisionControlSystems.GIT, | 2160 | rcs_type=RevisionControlSystems.GIT, |
479 | 2161 | url=git_repo_url) | 2161 | url=git_repo_url, review_status=review_status) |
480 | 2162 | elif hg_repo_url is not None: | 2162 | elif hg_repo_url is not None: |
482 | 2163 | code_import = code_import_set.new( | 2163 | return code_import_set.new( |
483 | 2164 | registrant, target, branch_name, | 2164 | registrant, target, branch_name, |
484 | 2165 | rcs_type=RevisionControlSystems.HG, | 2165 | rcs_type=RevisionControlSystems.HG, |
486 | 2166 | url=hg_repo_url) | 2166 | url=hg_repo_url, review_status=review_status) |
487 | 2167 | elif bzr_branch_url is not None: | 2167 | elif bzr_branch_url is not None: |
489 | 2168 | code_import = code_import_set.new( | 2168 | return code_import_set.new( |
490 | 2169 | registrant, target, branch_name, | 2169 | registrant, target, branch_name, |
491 | 2170 | rcs_type=RevisionControlSystems.BZR, | 2170 | rcs_type=RevisionControlSystems.BZR, |
493 | 2171 | url=bzr_branch_url) | 2171 | url=bzr_branch_url, review_status=review_status) |
494 | 2172 | else: | 2172 | else: |
495 | 2173 | assert rcs_type in (None, RevisionControlSystems.CVS) | 2173 | assert rcs_type in (None, RevisionControlSystems.CVS) |
497 | 2174 | code_import = code_import_set.new( | 2174 | return code_import_set.new( |
498 | 2175 | registrant, target, branch_name, | 2175 | registrant, target, branch_name, |
499 | 2176 | rcs_type=RevisionControlSystems.CVS, | 2176 | rcs_type=RevisionControlSystems.CVS, |
504 | 2177 | cvs_root=cvs_root, cvs_module=cvs_module) | 2177 | cvs_root=cvs_root, cvs_module=cvs_module, |
505 | 2178 | if review_status: | 2178 | review_status=review_status) |
502 | 2179 | removeSecurityProxy(code_import).review_status = review_status | ||
503 | 2180 | return code_import | ||
506 | 2181 | 2179 | ||
507 | 2182 | def makeChangelog(self, spn=None, versions=[]): | 2180 | def makeChangelog(self, spn=None, versions=[]): |
508 | 2183 | """Create and return a LFA of a valid Debian-style changelog.""" | 2181 | """Create and return a LFA of a valid Debian-style changelog.""" |
509 | 2184 | 2182 | ||
510 | === modified file 'utilities/sourcedeps.cache' | |||
511 | --- utilities/sourcedeps.cache 2011-08-19 14:03:25 +0000 | |||
512 | +++ utilities/sourcedeps.cache 2011-08-28 19:23:29 +0000 | |||
513 | @@ -1,8 +1,4 @@ | |||
514 | 1 | { | 1 | { |
515 | 2 | "bzr-builder": [ | ||
516 | 3 | 68, | ||
517 | 4 | "launchpad@pqm.canonical.com-20101123183213-777lz46xgagn1deg" | ||
518 | 5 | ], | ||
519 | 6 | "testresources": [ | 2 | "testresources": [ |
520 | 7 | 16, | 3 | 16, |
521 | 8 | "robertc@robertcollins.net-20050911111209-ee5da49011cf936a" | 4 | "robertc@robertcollins.net-20050911111209-ee5da49011cf936a" |
522 | @@ -31,14 +27,18 @@ | |||
523 | 31 | 24, | 27 | 24, |
524 | 32 | "launchpad@pqm.canonical.com-20100601182722-wo7h2fh0fvyw3aaq" | 28 | "launchpad@pqm.canonical.com-20100601182722-wo7h2fh0fvyw3aaq" |
525 | 33 | ], | 29 | ], |
526 | 34 | "lpreview": [ | ||
527 | 35 | 23, | ||
528 | 36 | "launchpad@pqm.canonical.com-20090720061538-euyh68ifavhy0pi8" | ||
529 | 37 | ], | ||
530 | 38 | "bzr-git": [ | 30 | "bzr-git": [ |
531 | 39 | 259, | 31 | 259, |
532 | 40 | "launchpad@pqm.canonical.com-20110601140035-gl5merbechngjw5s" | 32 | "launchpad@pqm.canonical.com-20110601140035-gl5merbechngjw5s" |
533 | 41 | ], | 33 | ], |
534 | 34 | "loggerhead": [ | ||
535 | 35 | 454, | ||
536 | 36 | "gavin@gromper.net-20110811101303-ka12yvnq2p48e2t8" | ||
537 | 37 | ], | ||
538 | 38 | "bzr-builder": [ | ||
539 | 39 | 68, | ||
540 | 40 | "launchpad@pqm.canonical.com-20101123183213-777lz46xgagn1deg" | ||
541 | 41 | ], | ||
542 | 42 | "bzr-loom": [ | 42 | "bzr-loom": [ |
543 | 43 | 49, | 43 | 49, |
544 | 44 | "launchpad@pqm.canonical.com-20110601122412-54vo3k8yae9i2zve" | 44 | "launchpad@pqm.canonical.com-20110601122412-54vo3k8yae9i2zve" |
545 | @@ -47,9 +47,9 @@ | |||
546 | 47 | 4, | 47 | 4, |
547 | 48 | "sinzui-20090526164636-1swugzupwvjgomo4" | 48 | "sinzui-20090526164636-1swugzupwvjgomo4" |
548 | 49 | ], | 49 | ], |
552 | 50 | "loggerhead": [ | 50 | "lpreview": [ |
553 | 51 | 452, | 51 | 23, |
554 | 52 | "andrew.bennetts@canonical.com-20110628173100-owrifrnckvoi60af" | 52 | "launchpad@pqm.canonical.com-20090720061538-euyh68ifavhy0pi8" |
555 | 53 | ], | 53 | ], |
556 | 54 | "difftacular": [ | 54 | "difftacular": [ |
557 | 55 | 6, | 55 | 6, |