Merge "Allow duplicate queue definitions on same project branches"

This commit is contained in:
Zuul 2023-05-22 10:53:55 +00:00 committed by Gerrit Code Review
commit ad532eb3d0
3 changed files with 64 additions and 4 deletions

View File

@ -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.

View File

@ -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'

View File

@ -7912,10 +7912,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):