blob: 732bc3d600670d94f7d95a1515ca578eeae729ff [file] [log] [blame]
James E. Blair1c2023c2018-01-08 09:42:22 -08001#!/usr/bin/env python
2
3# Copyright 2012 Hewlett-Packard Development Company, L.P.
4# Copyright 2018 Red Hat, Inc.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
18from tests.base import (
19 ZuulTestCase,
20 simple_layout,
21)
22
23
24class TestGerritCRD(ZuulTestCase):
25 tenant_config_file = 'config/single-tenant/main.yaml'
26
James E. Blair1c2023c2018-01-08 09:42:22 -080027 def test_crd_gate(self):
28 "Test cross-repo dependencies"
29 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
30 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
31 A.addApproval('Code-Review', 2)
32 B.addApproval('Code-Review', 2)
33
34 AM2 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM2')
35 AM1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM1')
36 AM2.setMerged()
37 AM1.setMerged()
38
39 BM2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM2')
40 BM1 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM1')
41 BM2.setMerged()
42 BM1.setMerged()
43
44 # A -> AM1 -> AM2
45 # B -> BM1 -> BM2
46 # A Depends-On: B
47 # M2 is here to make sure it is never queried. If it is, it
48 # means zuul is walking down the entire history of merged
49 # changes.
50
51 B.setDependsOn(BM1, 1)
52 BM1.setDependsOn(BM2, 1)
53
54 A.setDependsOn(AM1, 1)
55 AM1.setDependsOn(AM2, 1)
56
57 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
58 A.subject, B.data['url'])
59
60 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
61 self.waitUntilSettled()
62
63 self.assertEqual(A.data['status'], 'NEW')
64 self.assertEqual(B.data['status'], 'NEW')
65
66 for connection in self.connections.connections.values():
67 connection.maintainCache([])
68
69 self.executor_server.hold_jobs_in_build = True
70 B.addApproval('Approved', 1)
71 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
72 self.waitUntilSettled()
73
74 self.executor_server.release('.*-merge')
75 self.waitUntilSettled()
76 self.executor_server.release('.*-merge')
77 self.waitUntilSettled()
78 self.executor_server.hold_jobs_in_build = False
79 self.executor_server.release()
80 self.waitUntilSettled()
81
82 self.assertEqual(AM2.queried, 0)
83 self.assertEqual(BM2.queried, 0)
84 self.assertEqual(A.data['status'], 'MERGED')
85 self.assertEqual(B.data['status'], 'MERGED')
86 self.assertEqual(A.reported, 2)
87 self.assertEqual(B.reported, 2)
88
89 changes = self.getJobFromHistory(
90 'project-merge', 'org/project1').changes
91 self.assertEqual(changes, '2,1 1,1')
92
93 def test_crd_branch(self):
94 "Test cross-repo dependencies in multiple branches"
95
96 self.create_branch('org/project2', 'mp')
97 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
98 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
99 C1 = self.fake_gerrit.addFakeChange('org/project2', 'mp', 'C1')
James E. Blair1c2023c2018-01-08 09:42:22 -0800100
101 A.addApproval('Code-Review', 2)
102 B.addApproval('Code-Review', 2)
103 C1.addApproval('Code-Review', 2)
104
105 # A Depends-On: B+C1
James E. Blair0e4c7912018-01-02 14:20:17 -0800106 A.data['commitMessage'] = '%s\n\nDepends-On: %s\nDepends-On: %s\n' % (
107 A.subject, B.data['url'], C1.data['url'])
James E. Blair1c2023c2018-01-08 09:42:22 -0800108
109 self.executor_server.hold_jobs_in_build = True
110 B.addApproval('Approved', 1)
111 C1.addApproval('Approved', 1)
112 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
113 self.waitUntilSettled()
114
115 self.executor_server.release('.*-merge')
116 self.waitUntilSettled()
117 self.executor_server.release('.*-merge')
118 self.waitUntilSettled()
119 self.executor_server.release('.*-merge')
120 self.waitUntilSettled()
121 self.executor_server.hold_jobs_in_build = False
122 self.executor_server.release()
123 self.waitUntilSettled()
124
125 self.assertEqual(A.data['status'], 'MERGED')
126 self.assertEqual(B.data['status'], 'MERGED')
127 self.assertEqual(C1.data['status'], 'MERGED')
128 self.assertEqual(A.reported, 2)
129 self.assertEqual(B.reported, 2)
130 self.assertEqual(C1.reported, 2)
131
132 changes = self.getJobFromHistory(
133 'project-merge', 'org/project1').changes
134 self.assertEqual(changes, '2,1 3,1 1,1')
135
136 def test_crd_multiline(self):
137 "Test multiple depends-on lines in commit"
138 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
139 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
140 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
141 A.addApproval('Code-Review', 2)
142 B.addApproval('Code-Review', 2)
143 C.addApproval('Code-Review', 2)
144
145 # A Depends-On: B+C
146 A.data['commitMessage'] = '%s\n\nDepends-On: %s\nDepends-On: %s\n' % (
147 A.subject, B.data['url'], C.data['url'])
148
149 self.executor_server.hold_jobs_in_build = True
150 B.addApproval('Approved', 1)
151 C.addApproval('Approved', 1)
152 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
153 self.waitUntilSettled()
154
155 self.executor_server.release('.*-merge')
156 self.waitUntilSettled()
157 self.executor_server.release('.*-merge')
158 self.waitUntilSettled()
159 self.executor_server.release('.*-merge')
160 self.waitUntilSettled()
161 self.executor_server.hold_jobs_in_build = False
162 self.executor_server.release()
163 self.waitUntilSettled()
164
165 self.assertEqual(A.data['status'], 'MERGED')
166 self.assertEqual(B.data['status'], 'MERGED')
167 self.assertEqual(C.data['status'], 'MERGED')
168 self.assertEqual(A.reported, 2)
169 self.assertEqual(B.reported, 2)
170 self.assertEqual(C.reported, 2)
171
172 changes = self.getJobFromHistory(
173 'project-merge', 'org/project1').changes
174 self.assertEqual(changes, '2,1 3,1 1,1')
175
176 def test_crd_unshared_gate(self):
177 "Test cross-repo dependencies in unshared gate queues"
178 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
179 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
180 A.addApproval('Code-Review', 2)
181 B.addApproval('Code-Review', 2)
182
183 # A Depends-On: B
184 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
185 A.subject, B.data['url'])
186
187 # A and B do not share a queue, make sure that A is unable to
188 # enqueue B (and therefore, A is unable to be enqueued).
189 B.addApproval('Approved', 1)
190 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
191 self.waitUntilSettled()
192
193 self.assertEqual(A.data['status'], 'NEW')
194 self.assertEqual(B.data['status'], 'NEW')
195 self.assertEqual(A.reported, 0)
196 self.assertEqual(B.reported, 0)
197 self.assertEqual(len(self.history), 0)
198
199 # Enqueue and merge B alone.
200 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
201 self.waitUntilSettled()
202
203 self.assertEqual(B.data['status'], 'MERGED')
204 self.assertEqual(B.reported, 2)
205
206 # Now that B is merged, A should be able to be enqueued and
207 # merged.
208 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
209 self.waitUntilSettled()
210
211 self.assertEqual(A.data['status'], 'MERGED')
212 self.assertEqual(A.reported, 2)
213
214 def test_crd_gate_reverse(self):
215 "Test reverse cross-repo dependencies"
216 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
217 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
218 A.addApproval('Code-Review', 2)
219 B.addApproval('Code-Review', 2)
220
221 # A Depends-On: B
222
223 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
224 A.subject, B.data['url'])
225
226 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
227 self.waitUntilSettled()
228
229 self.assertEqual(A.data['status'], 'NEW')
230 self.assertEqual(B.data['status'], 'NEW')
231
232 self.executor_server.hold_jobs_in_build = True
233 A.addApproval('Approved', 1)
234 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
235 self.waitUntilSettled()
236
237 self.executor_server.release('.*-merge')
238 self.waitUntilSettled()
239 self.executor_server.release('.*-merge')
240 self.waitUntilSettled()
241 self.executor_server.hold_jobs_in_build = False
242 self.executor_server.release()
243 self.waitUntilSettled()
244
245 self.assertEqual(A.data['status'], 'MERGED')
246 self.assertEqual(B.data['status'], 'MERGED')
247 self.assertEqual(A.reported, 2)
248 self.assertEqual(B.reported, 2)
249
250 changes = self.getJobFromHistory(
251 'project-merge', 'org/project1').changes
252 self.assertEqual(changes, '2,1 1,1')
253
254 def test_crd_cycle(self):
255 "Test cross-repo dependency cycles"
256 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
257 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
258 A.addApproval('Code-Review', 2)
259 B.addApproval('Code-Review', 2)
260
261 # A -> B -> A (via commit-depends)
262
263 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
264 A.subject, B.data['url'])
265 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
266 B.subject, A.data['url'])
267
268 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
269 self.waitUntilSettled()
270
271 self.assertEqual(A.reported, 0)
272 self.assertEqual(B.reported, 0)
273 self.assertEqual(A.data['status'], 'NEW')
274 self.assertEqual(B.data['status'], 'NEW')
275
276 def test_crd_gate_unknown(self):
277 "Test unknown projects in dependent pipeline"
278 self.init_repo("org/unknown", tag='init')
279 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
280 B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'B')
281 A.addApproval('Code-Review', 2)
282 B.addApproval('Code-Review', 2)
283
284 # A Depends-On: B
285 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
286 A.subject, B.data['url'])
287
288 B.addApproval('Approved', 1)
289 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
290 self.waitUntilSettled()
291
292 # Unknown projects cannot share a queue with any other
293 # since they don't have common jobs with any other (they have no jobs).
294 # Changes which depend on unknown project changes
295 # should not be processed in dependent pipeline
296 self.assertEqual(A.data['status'], 'NEW')
297 self.assertEqual(B.data['status'], 'NEW')
298 self.assertEqual(A.reported, 0)
299 self.assertEqual(B.reported, 0)
300 self.assertEqual(len(self.history), 0)
301
302 # Simulate change B being gated outside this layout Set the
303 # change merged before submitting the event so that when the
304 # event triggers a gerrit query to update the change, we get
305 # the information that it was merged.
306 B.setMerged()
307 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
308 self.waitUntilSettled()
309 self.assertEqual(len(self.history), 0)
310
311 # Now that B is merged, A should be able to be enqueued and
312 # merged.
313 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
314 self.waitUntilSettled()
315
316 self.assertEqual(A.data['status'], 'MERGED')
317 self.assertEqual(A.reported, 2)
318 self.assertEqual(B.data['status'], 'MERGED')
319 self.assertEqual(B.reported, 0)
320
321 def test_crd_check(self):
322 "Test cross-repo dependencies in independent pipelines"
323
324 self.executor_server.hold_jobs_in_build = True
325 self.gearman_server.hold_jobs_in_queue = True
326 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
327 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
328
329 # A Depends-On: B
330 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
331 A.subject, B.data['url'])
332
333 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
334 self.waitUntilSettled()
335
336 self.gearman_server.hold_jobs_in_queue = False
337 self.gearman_server.release()
338 self.waitUntilSettled()
339
340 self.executor_server.release('.*-merge')
341 self.waitUntilSettled()
342
343 self.assertTrue(self.builds[0].hasChanges(A, B))
344
345 self.executor_server.hold_jobs_in_build = False
346 self.executor_server.release()
347 self.waitUntilSettled()
348
349 self.assertEqual(A.data['status'], 'NEW')
350 self.assertEqual(B.data['status'], 'NEW')
351 self.assertEqual(A.reported, 1)
352 self.assertEqual(B.reported, 0)
353
354 self.assertEqual(self.history[0].changes, '2,1 1,1')
355 tenant = self.sched.abide.tenants.get('tenant-one')
356 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
357
358 def test_crd_check_git_depends(self):
359 "Test single-repo dependencies in independent pipelines"
360 self.gearman_server.hold_jobs_in_build = True
361 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
362 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
363
364 # Add two git-dependent changes and make sure they both report
365 # success.
366 B.setDependsOn(A, 1)
367 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
368 self.waitUntilSettled()
369 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
370 self.waitUntilSettled()
371
372 self.orderedRelease()
373 self.gearman_server.hold_jobs_in_build = False
374 self.waitUntilSettled()
375
376 self.assertEqual(A.data['status'], 'NEW')
377 self.assertEqual(B.data['status'], 'NEW')
378 self.assertEqual(A.reported, 1)
379 self.assertEqual(B.reported, 1)
380
381 self.assertEqual(self.history[0].changes, '1,1')
382 self.assertEqual(self.history[-1].changes, '1,1 2,1')
383 tenant = self.sched.abide.tenants.get('tenant-one')
384 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
385
386 self.assertIn('Build succeeded', A.messages[0])
387 self.assertIn('Build succeeded', B.messages[0])
388
389 def test_crd_check_duplicate(self):
390 "Test duplicate check in independent pipelines"
391 self.executor_server.hold_jobs_in_build = True
392 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
393 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
394 tenant = self.sched.abide.tenants.get('tenant-one')
395 check_pipeline = tenant.layout.pipelines['check']
396
397 # Add two git-dependent changes...
398 B.setDependsOn(A, 1)
399 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
400 self.waitUntilSettled()
401 self.assertEqual(len(check_pipeline.getAllItems()), 2)
402
403 # ...make sure the live one is not duplicated...
404 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
405 self.waitUntilSettled()
406 self.assertEqual(len(check_pipeline.getAllItems()), 2)
407
408 # ...but the non-live one is able to be.
409 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
410 self.waitUntilSettled()
411 self.assertEqual(len(check_pipeline.getAllItems()), 3)
412
413 # Release jobs in order to avoid races with change A jobs
414 # finishing before change B jobs.
415 self.orderedRelease()
416 self.executor_server.hold_jobs_in_build = False
417 self.executor_server.release()
418 self.waitUntilSettled()
419
420 self.assertEqual(A.data['status'], 'NEW')
421 self.assertEqual(B.data['status'], 'NEW')
422 self.assertEqual(A.reported, 1)
423 self.assertEqual(B.reported, 1)
424
425 self.assertEqual(self.history[0].changes, '1,1 2,1')
426 self.assertEqual(self.history[1].changes, '1,1')
427 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
428
429 self.assertIn('Build succeeded', A.messages[0])
430 self.assertIn('Build succeeded', B.messages[0])
431
432 def _test_crd_check_reconfiguration(self, project1, project2):
433 "Test cross-repo dependencies re-enqueued in independent pipelines"
434
435 self.gearman_server.hold_jobs_in_queue = True
436 A = self.fake_gerrit.addFakeChange(project1, 'master', 'A')
437 B = self.fake_gerrit.addFakeChange(project2, 'master', 'B')
438
439 # A Depends-On: B
440 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
441 A.subject, B.data['url'])
442
443 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
444 self.waitUntilSettled()
445
446 self.sched.reconfigure(self.config)
447
448 # Make sure the items still share a change queue, and the
449 # first one is not live.
450 tenant = self.sched.abide.tenants.get('tenant-one')
451 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 1)
452 queue = tenant.layout.pipelines['check'].queues[0]
453 first_item = queue.queue[0]
454 for item in queue.queue:
455 self.assertEqual(item.queue, first_item.queue)
456 self.assertFalse(first_item.live)
457 self.assertTrue(queue.queue[1].live)
458
459 self.gearman_server.hold_jobs_in_queue = False
460 self.gearman_server.release()
461 self.waitUntilSettled()
462
463 self.assertEqual(A.data['status'], 'NEW')
464 self.assertEqual(B.data['status'], 'NEW')
465 self.assertEqual(A.reported, 1)
466 self.assertEqual(B.reported, 0)
467
468 self.assertEqual(self.history[0].changes, '2,1 1,1')
469 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
470
471 def test_crd_check_reconfiguration(self):
472 self._test_crd_check_reconfiguration('org/project1', 'org/project2')
473
474 def test_crd_undefined_project(self):
475 """Test that undefined projects in dependencies are handled for
476 independent pipelines"""
477 # It's a hack for fake gerrit,
478 # as it implies repo creation upon the creation of any change
479 self.init_repo("org/unknown", tag='init')
480 self._test_crd_check_reconfiguration('org/project1', 'org/unknown')
481
482 @simple_layout('layouts/ignore-dependencies.yaml')
483 def test_crd_check_ignore_dependencies(self):
484 "Test cross-repo dependencies can be ignored"
485
486 self.gearman_server.hold_jobs_in_queue = True
487 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
488 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
489 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
490
491 # A Depends-On: B
492 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
493 A.subject, B.data['url'])
494 # C git-depends on B
495 C.setDependsOn(B, 1)
496 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
497 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
498 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
499 self.waitUntilSettled()
500
501 # Make sure none of the items share a change queue, and all
502 # are live.
503 tenant = self.sched.abide.tenants.get('tenant-one')
504 check_pipeline = tenant.layout.pipelines['check']
505 self.assertEqual(len(check_pipeline.queues), 3)
506 self.assertEqual(len(check_pipeline.getAllItems()), 3)
507 for item in check_pipeline.getAllItems():
508 self.assertTrue(item.live)
509
510 self.gearman_server.hold_jobs_in_queue = False
511 self.gearman_server.release()
512 self.waitUntilSettled()
513
514 self.assertEqual(A.data['status'], 'NEW')
515 self.assertEqual(B.data['status'], 'NEW')
516 self.assertEqual(C.data['status'], 'NEW')
517 self.assertEqual(A.reported, 1)
518 self.assertEqual(B.reported, 1)
519 self.assertEqual(C.reported, 1)
520
521 # Each job should have tested exactly one change
522 for job in self.history:
523 self.assertEqual(len(job.changes.split()), 1)
524
525 @simple_layout('layouts/three-projects.yaml')
526 def test_crd_check_transitive(self):
527 "Test transitive cross-repo dependencies"
528 # Specifically, if A -> B -> C, and C gets a new patchset and
529 # A gets a new patchset, ensure the test of A,2 includes B,1
530 # and C,2 (not C,1 which would indicate stale data in the
531 # cache for B).
532 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
533 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
534 C = self.fake_gerrit.addFakeChange('org/project3', 'master', 'C')
535
536 # A Depends-On: B
537 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
538 A.subject, B.data['url'])
539
540 # B Depends-On: C
541 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
542 B.subject, C.data['url'])
543
544 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
545 self.waitUntilSettled()
546 self.assertEqual(self.history[-1].changes, '3,1 2,1 1,1')
547
548 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
549 self.waitUntilSettled()
550 self.assertEqual(self.history[-1].changes, '3,1 2,1')
551
552 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
553 self.waitUntilSettled()
554 self.assertEqual(self.history[-1].changes, '3,1')
555
556 C.addPatchset()
557 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(2))
558 self.waitUntilSettled()
559 self.assertEqual(self.history[-1].changes, '3,2')
560
561 A.addPatchset()
562 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
563 self.waitUntilSettled()
564 self.assertEqual(self.history[-1].changes, '3,2 2,1 1,2')
565
566 def test_crd_check_unknown(self):
567 "Test unknown projects in independent pipeline"
568 self.init_repo("org/unknown", tag='init')
569 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
570 B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'D')
571 # A Depends-On: B
572 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
573 A.subject, B.data['url'])
574
575 # Make sure zuul has seen an event on B.
576 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
577 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
578 self.waitUntilSettled()
579
580 self.assertEqual(A.data['status'], 'NEW')
581 self.assertEqual(A.reported, 1)
582 self.assertEqual(B.data['status'], 'NEW')
583 self.assertEqual(B.reported, 0)
584
585 def test_crd_cycle_join(self):
586 "Test an updated change creates a cycle"
587 A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A')
588
589 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
590 self.waitUntilSettled()
591 self.assertEqual(A.reported, 1)
592
593 # Create B->A
594 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
595 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
596 B.subject, A.data['url'])
597 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
598 self.waitUntilSettled()
599
600 # Dep is there so zuul should have reported on B
601 self.assertEqual(B.reported, 1)
602
603 # Update A to add A->B (a cycle).
604 A.addPatchset()
605 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
606 A.subject, B.data['url'])
607 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
608 self.waitUntilSettled()
609
610 # Dependency cycle injected so zuul should not have reported again on A
611 self.assertEqual(A.reported, 1)
612
613 # Now if we update B to remove the depends-on, everything
614 # should be okay. B; A->B
615
616 B.addPatchset()
617 B.data['commitMessage'] = '%s\n' % (B.subject,)
618 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
619 self.waitUntilSettled()
620
621 # Cycle was removed so now zuul should have reported again on A
622 self.assertEqual(A.reported, 2)
623
624 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
625 self.waitUntilSettled()
626 self.assertEqual(B.reported, 2)