Allow duplicate queue definitions on same project branches
Just like secrets and semaphores, queues can be defined in-repo in unstrusted projects with multiple branches. To aid the branching workflow in these cases, we will now ignore duplicate queue definitions on multiple branches of the same project if they are identical. Change-Id: Ib74e71f425f8e2835ac0000fd76fde478b9d1653
This commit is contained in:
parent
d6d592f5a7
commit
6caba8e057
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Duplicate :attr:`queue` configuration items are now permitted on
|
||||
multiple branches of the same project as long as their
|
||||
configuration is identical. Similar to secrets and semaphores,
|
||||
this can help avoid spurious configuration errors when branching a
|
||||
project with in-repo configuration.
|
|
@ -6732,6 +6732,44 @@ class TestChangeQueues(ZuulTestCase):
|
|||
"""
|
||||
self._test_dependent_queues_per_branch('org/project4')
|
||||
|
||||
def test_duplicate_definition_on_branches(self):
|
||||
project = 'org/project3'
|
||||
self.create_branch(project, 'stable')
|
||||
self.fake_gerrit.addEvent(
|
||||
self.fake_gerrit.getFakeBranchCreatedEvent(project, 'stable'))
|
||||
self.waitUntilSettled()
|
||||
tenant = self.scheds.first.sched.abide.tenants.get('tenant-one')
|
||||
self.assertEquals(
|
||||
len(tenant.layout.loading_errors), 1,
|
||||
"No error should have been accumulated")
|
||||
# This error is expected and unrelated to this test (the
|
||||
# ignored configuration is used by other tests in this class):
|
||||
self.assertIn('Queue integrated already defined',
|
||||
tenant.layout.loading_errors[0].error)
|
||||
|
||||
# At this point we've verified that we can have identical
|
||||
# queue definitions on multiple branches without conflict.
|
||||
# Next, let's try to change the queue def on one branch so it
|
||||
# doesn't match (flip the per-branch boolean):
|
||||
conf = textwrap.dedent(
|
||||
"""
|
||||
- queue:
|
||||
name: integrated-untrusted
|
||||
per-branch: false
|
||||
""")
|
||||
|
||||
file_dict = {'zuul.d/queue.yaml': conf}
|
||||
A = self.fake_gerrit.addFakeChange(project, 'stable', 'A',
|
||||
files=file_dict)
|
||||
A.addApproval('Code-Review', 2)
|
||||
self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
|
||||
self.waitUntilSettled()
|
||||
self.assertEqual(len(A.messages), 1)
|
||||
self.assertTrue(
|
||||
'Queue integrated-untrusted does not match '
|
||||
'existing definition in branch master' in A.messages[0])
|
||||
self.assertEqual(A.data['status'], 'NEW')
|
||||
|
||||
|
||||
class TestJobUpdateBrokenConfig(ZuulTestCase):
|
||||
tenant_config_file = 'config/job-update-broken/main.yaml'
|
||||
|
|
|
@ -7898,10 +7898,24 @@ class Layout(object):
|
|||
return semaphore
|
||||
|
||||
def addQueue(self, queue):
|
||||
# Change queues must be unique and cannot be overridden.
|
||||
if queue.name in self.queues:
|
||||
raise Exception('Queue %s is already defined' % queue.name)
|
||||
|
||||
# It's ok to have a duplicate queue definition, but only if
|
||||
# they are in different branches of the same repo, and have
|
||||
# the same values.
|
||||
other = self.queues.get(queue.name)
|
||||
if other is not None:
|
||||
if not queue.source_context.isSameProject(other.source_context):
|
||||
raise Exception(
|
||||
"Queue %s already defined in project %s" %
|
||||
(queue.name, other.source_context.project_name))
|
||||
if queue.source_context.branch == other.source_context.branch:
|
||||
raise Exception("Queue %s already defined" % (queue.name,))
|
||||
if queue != other:
|
||||
raise Exception("Queue %s does not match existing definition"
|
||||
" in branch %s" %
|
||||
(queue.name, other.source_context.branch))
|
||||
# Identical data in a different branch of the same project;
|
||||
# ignore the duplicate definition
|
||||
return
|
||||
self.queues[queue.name] = queue
|
||||
|
||||
def addPipeline(self, pipeline):
|
||||
|
|
Loading…
Reference in New Issue