Always create foreign projects if needed
If Zuul encounters a project it does not know about via a
cross-repo dependency (CRD), it creates a record of it in memory
and refers to it as a foreign project. In some cases, if Zuul
received an event for a change in a project *before* it processed
a CRD reference for the project, it would cache that change with
the associated project set to None, and the subsequent CRD
processing would fail to create the foreign project.
Resolve this by simply always creating a foreign project if it is
needed. It's not obvious why we would ever not want to do that.
Change-Id: I4e6d5cb1f17e80879c23414ce45c66572dbc1d3e
diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py
index 628775d..335f987 100755
--- a/tests/test_scheduler.py
+++ b/tests/test_scheduler.py
@@ -4267,6 +4267,25 @@
self.waitUntilSettled()
self.assertEqual(self.history[-1].changes, '3,2 2,1 1,2')
+ def test_crd_check_unknown(self):
+ "Test unknown projects in independent pipeline"
+ self.init_repo("org/unknown")
+ A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
+ B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'D')
+ # A Depends-On: B
+ A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
+ A.subject, B.data['id'])
+
+ # Make sure zuul has seen an event on B.
+ self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
+ self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
+ self.waitUntilSettled()
+
+ self.assertEqual(A.data['status'], 'NEW')
+ self.assertEqual(A.reported, 1)
+ self.assertEqual(B.data['status'], 'NEW')
+ self.assertEqual(B.reported, 0)
+
def test_crd_cycle_join(self):
"Test an updated change creates a cycle"
A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A')
diff --git a/zuul/scheduler.py b/zuul/scheduler.py
index b974762..b52931e 100644
--- a/zuul/scheduler.py
+++ b/zuul/scheduler.py
@@ -625,12 +625,12 @@
def setMerger(self, merger):
self.merger = merger
- def getProject(self, name, create_foreign=False):
+ def getProject(self, name):
self.layout_lock.acquire()
p = None
try:
p = self.layout.projects.get(name)
- if p is None and create_foreign:
+ if p is None:
self.log.info("Registering foreign project: %s" % name)
p = Project(name, foreign=True)
self.layout.projects[name] = p
diff --git a/zuul/source/gerrit.py b/zuul/source/gerrit.py
index 73cf726..463f315 100644
--- a/zuul/source/gerrit.py
+++ b/zuul/source/gerrit.py
@@ -243,11 +243,7 @@
if 'project' not in data:
raise exceptions.ChangeNotFound(change.number, change.patchset)
- # If updated changed came as a dependent on
- # and its project is not defined,
- # then create a 'foreign' project for it in layout
- change.project = self.sched.getProject(data['project'],
- create_foreign=bool(history))
+ change.project = self.sched.getProject(data['project'])
change.branch = data['branch']
change.url = data['url']
max_ps = 0