Merge "Handle dependency limit errors more gracefully"
This commit is contained in:
commit
3bcd923a68
|
@ -0,0 +1 @@
|
||||||
|
test
|
|
@ -0,0 +1,26 @@
|
||||||
|
- queue:
|
||||||
|
name: integrated-topic
|
||||||
|
allow-circular-dependencies: True
|
||||||
|
dependencies-by-topic: True
|
||||||
|
|
||||||
|
- project:
|
||||||
|
queue: integrated-topic
|
||||||
|
check:
|
||||||
|
jobs:
|
||||||
|
- project-merge
|
||||||
|
- project-test1:
|
||||||
|
dependencies: project-merge
|
||||||
|
- project-test2:
|
||||||
|
dependencies: project-merge
|
||||||
|
gate:
|
||||||
|
jobs:
|
||||||
|
- project-merge
|
||||||
|
- project-test1:
|
||||||
|
dependencies: project-merge
|
||||||
|
- project-test2:
|
||||||
|
dependencies: project-merge
|
||||||
|
- project-testfile:
|
||||||
|
dependencies: project-merge
|
||||||
|
post:
|
||||||
|
jobs:
|
||||||
|
- project-post
|
|
@ -9,3 +9,4 @@
|
||||||
- org/project
|
- org/project
|
||||||
- org/project1
|
- org/project1
|
||||||
- org/project2
|
- org/project2
|
||||||
|
- org/project4
|
||||||
|
|
|
@ -9869,3 +9869,29 @@ class TestMaxDeps(ZuulTestCase):
|
||||||
dict(name='project-test1', result='SUCCESS', changes='1,1 2,1'),
|
dict(name='project-test1', result='SUCCESS', changes='1,1 2,1'),
|
||||||
dict(name='project-test2', result='SUCCESS', changes='1,1 2,1'),
|
dict(name='project-test2', result='SUCCESS', changes='1,1 2,1'),
|
||||||
], ordered=False)
|
], ordered=False)
|
||||||
|
|
||||||
|
def test_max_deps_extended(self):
|
||||||
|
self.executor_server.hold_jobs_in_build = True
|
||||||
|
# max_dependencies for the connection is 1, so this is okay
|
||||||
|
A = self.fake_gerrit.addFakeChange('org/project4', 'master', 'A')
|
||||||
|
B = self.fake_gerrit.addFakeChange('org/project4', 'master', 'B',
|
||||||
|
topic='test-topic')
|
||||||
|
B.setDependsOn(A, 1)
|
||||||
|
|
||||||
|
self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
|
||||||
|
self.waitUntilSettled()
|
||||||
|
|
||||||
|
# Increase the number of dependencies for B by adding a
|
||||||
|
# change with the same topic (dependencies-by-topic is enabled).
|
||||||
|
# With this C should not be enqueued and A is removed.
|
||||||
|
C = self.fake_gerrit.addFakeChange('org/project4', 'master', 'C',
|
||||||
|
topic='test-topic')
|
||||||
|
self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
|
||||||
|
|
||||||
|
self.executor_server.hold_jobs_in_build = True
|
||||||
|
self.executor_server.release()
|
||||||
|
self.waitUntilSettled()
|
||||||
|
|
||||||
|
self.assertHistory([
|
||||||
|
dict(name='project-merge', result='SUCCESS', changes='1,1 2,1'),
|
||||||
|
], ordered=False)
|
||||||
|
|
|
@ -50,6 +50,10 @@ class StreamingError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DependencyLimitExceededError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Authentication Exceptions
|
# Authentication Exceptions
|
||||||
|
|
||||||
class AuthTokenException(Exception):
|
class AuthTokenException(Exception):
|
||||||
|
|
|
@ -596,8 +596,11 @@ class PipelineManager(metaclass=ABCMeta):
|
||||||
change, self.pipeline)
|
change, self.pipeline)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.getDependencyGraph(change, dependency_graph, event,
|
try:
|
||||||
update_deps=True)
|
self.getDependencyGraph(change, dependency_graph, event,
|
||||||
|
update_deps=True)
|
||||||
|
except exceptions.DependencyLimitExceededError:
|
||||||
|
return False
|
||||||
|
|
||||||
with self.getChangeQueue(change, event, change_queue) as change_queue:
|
with self.getChangeQueue(change, event, change_queue) as change_queue:
|
||||||
if not change_queue:
|
if not change_queue:
|
||||||
|
@ -808,9 +811,10 @@ class PipelineManager(metaclass=ABCMeta):
|
||||||
if (self.pipeline.tenant.max_dependencies is not None and
|
if (self.pipeline.tenant.max_dependencies is not None and
|
||||||
(len(dependency_graph) >
|
(len(dependency_graph) >
|
||||||
self.pipeline.tenant.max_dependencies)):
|
self.pipeline.tenant.max_dependencies)):
|
||||||
log.debug("%sDependency graph for change %s is too large",
|
log.info("%sDependency graph for change %s is too large",
|
||||||
indent, change)
|
indent, change)
|
||||||
raise Exception("Dependency graph is too large")
|
raise exceptions.DependencyLimitExceededError(
|
||||||
|
"Dependency graph is too large")
|
||||||
|
|
||||||
node = dependency_graph.setdefault(change, [])
|
node = dependency_graph.setdefault(change, [])
|
||||||
if needed_change not in node:
|
if needed_change not in node:
|
||||||
|
@ -1619,8 +1623,12 @@ class PipelineManager(metaclass=ABCMeta):
|
||||||
|
|
||||||
meets_reqs = self.areChangesReadyToBeEnqueued(item.changes, item.event)
|
meets_reqs = self.areChangesReadyToBeEnqueued(item.changes, item.event)
|
||||||
dependency_graph = collections.OrderedDict()
|
dependency_graph = collections.OrderedDict()
|
||||||
self.getDependencyGraph(item.changes[0], dependency_graph, item.event,
|
try:
|
||||||
quiet=True)
|
self.getDependencyGraph(item.changes[0], dependency_graph,
|
||||||
|
item.event, quiet=True)
|
||||||
|
except exceptions.DependencyLimitExceededError:
|
||||||
|
self.removeItem(item)
|
||||||
|
return True, nnfi
|
||||||
|
|
||||||
# Verify that the cycle dependency graph is correct
|
# Verify that the cycle dependency graph is correct
|
||||||
cycle = self.cycleForChange(
|
cycle = self.cycleForChange(
|
||||||
|
|
Loading…
Reference in New Issue