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