Don't generate layouts on non live items
Non live items in Zuul queues never run jobs. They are dependency tree markers to ensure that we contruct the correct final git states that do run jobs. Previously we were generating layouts (necessary for running jobs) on all of the non live items in queues which generated (n^2+n)/2 layouts when we only need a single layout for the terminal item. Fix this by only generating layouts on live items. This introduces a slightly new process for getting the correct layout on a child item. The live child item can: Use pipeline layout when itself and items ahead do not modify layout Use its parent layout if parent item is live Generate its own layout if parent item is not live The result is some cases where zuul would treat the parent items as having syntax errors as a merge error in the child item now become syntax errors in the child item. This is due to waiting to generate that layout in the child rather than step by step. The test that checked the old behavior described above has been updated to reflect the new behavior introduced by this change. Change-Id: I0d650eef9f7d1d0af46afcbabd76a1f2baf74efa
This commit is contained in:
parent
75f3478ed1
commit
4419672188
|
@ -1876,7 +1876,8 @@ class TestInRepoConfig(ZuulTestCase):
|
|||
|
||||
self.assertEqual(C.reported, 1,
|
||||
"C should report failure")
|
||||
self.assertIn('depends on a change that failed to merge',
|
||||
self.assertIn('Zuul encountered a syntax error while parsing '
|
||||
'its configuration',
|
||||
C.messages[0],
|
||||
"C should have an error reported")
|
||||
|
||||
|
|
|
@ -477,13 +477,24 @@ class PipelineManager(object):
|
|||
return None
|
||||
return layout
|
||||
|
||||
def _queueUpdatesConfig(self, item):
|
||||
while item:
|
||||
if item.change.updatesConfig():
|
||||
return True
|
||||
item = item.item_ahead
|
||||
return False
|
||||
|
||||
def getLayout(self, item):
|
||||
if not item.change.updatesConfig():
|
||||
if item.item_ahead:
|
||||
return item.item_ahead.layout
|
||||
else:
|
||||
return item.queue.pipeline.layout
|
||||
# This item updates the config, ask the merger for the result.
|
||||
if not self._queueUpdatesConfig(item):
|
||||
# No config updates in queue. Use existing pipeline layout
|
||||
return item.queue.pipeline.layout
|
||||
elif (not item.change.updatesConfig() and
|
||||
item.item_ahead and item.item_ahead.live):
|
||||
# Current change does not update layout, use its parent if parent
|
||||
# has a layout.
|
||||
return item.item_ahead.layout
|
||||
# Else this item or a non live parent updates the config,
|
||||
# ask the merger for the result.
|
||||
build_set = item.current_build_set
|
||||
if build_set.merge_state == build_set.PENDING:
|
||||
return None
|
||||
|
@ -531,7 +542,12 @@ class PipelineManager(object):
|
|||
def prepareJobs(self, item):
|
||||
# This only runs once the item is in the pipeline's action window
|
||||
# Returns True if the item is ready, false otherwise
|
||||
if not item.layout:
|
||||
if not item.live:
|
||||
# Short circuit as non live items don't need layouts.
|
||||
# We also don't need to take further ready actions in
|
||||
# _processOneItem() so we return false.
|
||||
return False
|
||||
elif not item.layout:
|
||||
item.layout = self.getLayout(item)
|
||||
if not item.layout:
|
||||
return False
|
||||
|
|
Loading…
Reference in New Issue