Remove job trees from pipelines

This was mostly already done when we created 'ProjectConfig' and
'ProjectPipelineConfig' classes.  Clean up the remaining leftover
code and comments.

Story: 2000786
Task: 3310
Change-Id: I8a0bfb2cd148c174bc7e0b5121f8c39ed1d4645b
diff --git a/tests/unit/test_model.py b/tests/unit/test_model.py
index f10a82d..38615a9 100644
--- a/tests/unit/test_model.py
+++ b/tests/unit/test_model.py
@@ -207,7 +207,7 @@
                 ]
             }
         }])
-        layout.addProjectConfig(project_config, update_pipeline=False)
+        layout.addProjectConfig(project_config)
 
         change = model.Change(project)
         # Test master
@@ -416,7 +416,7 @@
                 ]
             }
         }])
-        layout.addProjectConfig(project_config, update_pipeline=False)
+        layout.addProjectConfig(project_config)
 
         change = model.Change(project)
         change.branch = 'master'
@@ -481,7 +481,7 @@
                 ]
             }
         }])
-        layout.addProjectConfig(project_config, update_pipeline=False)
+        layout.addProjectConfig(project_config)
 
         change = model.Change(project)
         change.branch = 'master'
diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py
index 45b2257..ecf8ca5 100755
--- a/tests/unit/test_scheduler.py
+++ b/tests/unit/test_scheduler.py
@@ -251,9 +251,12 @@
         C.addApproval('code-review', 2)
 
         self.fake_gerrit.addEvent(A.addApproval('approved', 1))
-        self.fake_gerrit.addEvent(B.addApproval('approved', 1))
-        self.fake_gerrit.addEvent(C.addApproval('approved', 1))
+        self.waitUntilSettled()
 
+        self.fake_gerrit.addEvent(B.addApproval('approved', 1))
+        self.waitUntilSettled()
+
+        self.fake_gerrit.addEvent(C.addApproval('approved', 1))
         self.waitUntilSettled()
 
         # There should be one merge job at the head of each queue running
diff --git a/zuul/configloader.py b/zuul/configloader.py
index 3dbe2c3..99b84b4 100644
--- a/zuul/configloader.py
+++ b/zuul/configloader.py
@@ -925,5 +925,5 @@
 
         for config_project in config.projects.values():
             layout.addProjectConfig(ProjectParser.fromYaml(
-                tenant, layout, config_project), update_pipeline=False)
+                tenant, layout, config_project))
         return layout
diff --git a/zuul/manager/__init__.py b/zuul/manager/__init__.py
index f0250cf..2e54e5c 100644
--- a/zuul/manager/__init__.py
+++ b/zuul/manager/__init__.py
@@ -91,11 +91,13 @@
                 log_jobs(x, indent + 2)
 
         for project_name in layout.project_configs.keys():
-            project = self.pipeline.source.getProject(project_name)
-            tree = self.pipeline.getJobTree(project)
-            if tree:
-                self.log.info("    %s" % project)
-                log_jobs(tree)
+            project_config = layout.project_configs.get(project_name)
+            if project_config:
+                project_pipeline_config = project_config.pipelines.get(
+                    self.pipeline.name)
+                if project_pipeline_config:
+                    self.log.info("    %s" % project_name)
+                    log_jobs(project_pipeline_config.job_tree)
         self.log.info("  On start:")
         self.log.info("    %s" % self.pipeline.start_actions)
         self.log.info("  On success:")
diff --git a/zuul/manager/dependent.py b/zuul/manager/dependent.py
index 3d006c2..f5fa579 100644
--- a/zuul/manager/dependent.py
+++ b/zuul/manager/dependent.py
@@ -39,10 +39,12 @@
         change_queues = {}
         project_configs = self.pipeline.layout.project_configs
 
-        for project in self.pipeline.getProjects():
-            project_config = project_configs[project.name]
-            project_pipeline_config = project_config.pipelines[
-                self.pipeline.name]
+        for project_config in project_configs.values():
+            project_pipeline_config = project_config.pipelines.get(
+                self.pipeline.name)
+            if project_pipeline_config is None:
+                continue
+            project = self.pipeline.source.getProject(project_config.name)
             queue_name = project_pipeline_config.queue_name
             if queue_name and queue_name in change_queues:
                 change_queue = change_queues[queue_name]
diff --git a/zuul/model.py b/zuul/model.py
index 15529e3..519b294 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -123,7 +123,6 @@
         self.start_message = None
         self.dequeue_on_new_patchset = True
         self.ignore_dependencies = False
-        self.job_trees = {}  # project -> JobTree
         self.manager = None
         self.queues = []
         self.precedence = PRECEDENCE_NORMAL
@@ -160,13 +159,6 @@
     def setManager(self, manager):
         self.manager = manager
 
-    def getProjects(self):
-        # cmp is not in python3, applied idiom from
-        # http://python-future.org/compatible_idioms.html#cmp
-        return sorted(
-            self.job_trees.keys(),
-            key=lambda p: p.name)
-
     def addQueue(self, queue):
         self.queues.append(queue)
 
@@ -179,10 +171,6 @@
     def removeQueue(self, queue):
         self.queues.remove(queue)
 
-    def getJobTree(self, project):
-        tree = self.job_trees.get(project)
-        return tree
-
     def getChangesInQueue(self):
         changes = []
         for shared_queue in self.queues:
@@ -2170,18 +2158,8 @@
     def addProjectTemplate(self, project_template):
         self.project_templates[project_template.name] = project_template
 
-    def addProjectConfig(self, project_config, update_pipeline=True):
+    def addProjectConfig(self, project_config):
         self.project_configs[project_config.name] = project_config
-        # TODOv3(jeblair): tidy up the relationship between pipelines
-        # and projects and projectconfigs.  Specifically, move
-        # job_trees out of the pipeline since they are more dynamic
-        # than pipelines.  Remove the update_pipeline argument
-        if not update_pipeline:
-            return
-        for pipeline_name, pipeline_config in project_config.pipelines.items():
-            pipeline = self.pipelines[pipeline_name]
-            project = pipeline.source.getProject(project_config.name)
-            pipeline.job_trees[project] = pipeline_config.job_tree
 
     def _createJobTree(self, change, job_trees, parent):
         for tree in job_trees: