diff --git a/tests/fixtures/layouts/supercedent-promote.yaml b/tests/fixtures/layouts/supercedent-promote.yaml new file mode 100644 index 0000000000..54db6c7d0c --- /dev/null +++ b/tests/fixtures/layouts/supercedent-promote.yaml @@ -0,0 +1,20 @@ +- pipeline: + name: promote + manager: supercedent + trigger: + gerrit: + - event: change-merged + +- job: + name: base + parent: null + run: playbooks/base.yaml + +- job: + name: promote-job + +- project: + name: org/project + promote: + jobs: + - promote-job diff --git a/tests/unit/test_supercedent.py b/tests/unit/test_supercedent.py index 4ea943598d..7505c0779d 100644 --- a/tests/unit/test_supercedent.py +++ b/tests/unit/test_supercedent.py @@ -81,3 +81,36 @@ class TestSupercedent(ZuulTestCase): dict(name='post-job', result='SUCCESS', newrev=arev), dict(name='post-job', result='SUCCESS', newrev=brev), ], ordered=False) + + @simple_layout('layouts/supercedent-promote.yaml') + def test_supercedent_promote(self): + self.executor_server.hold_jobs_in_build = True + A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A') + A.setMerged() + self.fake_gerrit.addEvent(A.getChangeMergedEvent()) + self.waitUntilSettled() + + # We should never run jobs for more than one change at a time + self.assertEqual(len(self.builds), 1) + + # This change should be superceded by the next + B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B') + B.setMerged() + self.fake_gerrit.addEvent(B.getChangeMergedEvent()) + self.waitUntilSettled() + + self.assertEqual(len(self.builds), 1) + + C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C') + C.setMerged() + self.fake_gerrit.addEvent(C.getChangeMergedEvent()) + self.waitUntilSettled() + + self.assertEqual(len(self.builds), 1) + + self.executor_server.hold_jobs_in_build = True + self.orderedRelease() + self.assertHistory([ + dict(name='promote-job', result='SUCCESS', changes='1,1'), + dict(name='promote-job', result='SUCCESS', changes='3,1'), + ], ordered=False) diff --git a/zuul/manager/supercedent.py b/zuul/manager/supercedent.py index a63fcb7979..73932484b8 100644 --- a/zuul/manager/supercedent.py +++ b/zuul/manager/supercedent.py @@ -26,10 +26,13 @@ class SupercedentPipelineManager(PipelineManager): return DynamicChangeQueueContextManager(existing) # Don't use Pipeline.getQueue to find an existing queue - # because we're matching project and ref. + # because we're matching project and (branch or ref). for queue in self.pipeline.queues: if (queue.queue[-1].change.project == change.project and - queue.queue[-1].change.ref == change.ref): + ((hasattr(change, 'branch') and + hasattr(queue.queue[-1].change, 'branch') and + queue.queue[-1].change.branch == change.branch) or + queue.queue[-1].change.ref == change.ref)): self.log.debug("Found existing queue %s", queue) return DynamicChangeQueueContextManager(queue) change_queue = model.ChangeQueue(