Avoid infinite recursion with topic dependencies
When updating topic dependencies we only consider the current patchset. However, when there are changes that have a git-level dependency to an outdated patchset and those dependencies are in a different topic we can run into max. recursion depth issues. To fix this problem, we will keep a history of topics that we've already processed and not call `getChangesByTopic()` again when we've already seen a topic. Change-Id: I6c15f502cfd593a44d7adda930670692151b6713
This commit is contained in:
@ -2504,6 +2504,37 @@ class TestGerritCircularDependencies(ZuulTestCase):
|
||||
self.assertEqual(C.data["status"], "MERGED")
|
||||
self.assertEqual(D.data["status"], "MERGED")
|
||||
|
||||
@simple_layout('layouts/deps-by-topic.yaml')
|
||||
def test_deps_by_topic_git_needs_outdated_patchset(self):
|
||||
A = self.fake_gerrit.addFakeChange('org/project1', "master", "A",
|
||||
topic='test-topic')
|
||||
B = self.fake_gerrit.addFakeChange('org/project1', "master", "B",
|
||||
topic='other-topic')
|
||||
C = self.fake_gerrit.addFakeChange('org/project2', "master", "C",
|
||||
topic='other-topic')
|
||||
D = self.fake_gerrit.addFakeChange('org/project2', "master", "D",
|
||||
topic='test-topic')
|
||||
|
||||
B.addPatchset()
|
||||
D.addPatchset()
|
||||
# Git level dependency between A and B + C and D on outdated
|
||||
# patchset.
|
||||
A.setDependsOn(B, 1)
|
||||
C.setDependsOn(D, 1)
|
||||
|
||||
self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
|
||||
self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
|
||||
self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
|
||||
self.fake_gerrit.addEvent(D.getPatchsetCreatedEvent(2))
|
||||
self.waitUntilSettled()
|
||||
|
||||
self.assertHistory([
|
||||
dict(name="check-job", result="SUCCESS",
|
||||
changes="4,2 4,1 3,1 2,2 2,1 1,1"),
|
||||
dict(name="check-job", result="SUCCESS",
|
||||
changes="4,2 2,2 2,1 1,1 4,1 3,1"),
|
||||
], ordered=False)
|
||||
|
||||
@simple_layout('layouts/deps-by-topic.yaml')
|
||||
def test_deps_by_topic_new_patchset(self):
|
||||
# Make sure that we correctly update the change cache on new
|
||||
|
@ -145,13 +145,17 @@ class GerritSource(BaseSource):
|
||||
changes.append(change)
|
||||
return changes
|
||||
|
||||
def getChangesByTopic(self, topic, changes=None):
|
||||
def getChangesByTopic(self, topic, changes=None, history=None):
|
||||
if not topic:
|
||||
return []
|
||||
|
||||
if changes is None:
|
||||
changes = {}
|
||||
|
||||
if history is None:
|
||||
history = []
|
||||
history.append(topic)
|
||||
|
||||
query = 'status:open topic:%s' % topic
|
||||
results = self.connection.simpleQuery(query)
|
||||
for result in results:
|
||||
@ -173,9 +177,9 @@ class GerritSource(BaseSource):
|
||||
if change_key in changes:
|
||||
continue
|
||||
git_change = self.getChange(change_key)
|
||||
if not git_change.topic or git_change.topic == topic:
|
||||
if not git_change.topic or git_change.topic in history:
|
||||
continue
|
||||
self.getChangesByTopic(git_change.topic, changes)
|
||||
self.getChangesByTopic(git_change.topic, changes, history)
|
||||
return list(changes.values())
|
||||
|
||||
def getCachedChanges(self):
|
||||
|
Reference in New Issue
Block a user