Support multiple triggers

Add the ability for Zuul to accept inputs from multiple trigger
sources simultaneously.

Pipelines are associated with exactly one trigger, which must now
be named in the configuration file.

Co-Authored-By: Monty Taylor <mordred@inaugust.com>

Change-Id: Ief2b31a7b8d85d30817f2747c1e2635f71ea24b9
diff --git a/tests/fixtures/layout-delayed-repo-init.yaml b/tests/fixtures/layout-delayed-repo-init.yaml
index 79f9898..e0613f1 100644
--- a/tests/fixtures/layout-delayed-repo-init.yaml
+++ b/tests/fixtures/layout-delayed-repo-init.yaml
@@ -2,7 +2,8 @@
   - name: check
     manager: IndependentPipelineManager
     trigger:
-      - event: patchset-created
+      gerrit:
+        - event: patchset-created
     success:
       verified: 1
     failure:
@@ -11,16 +12,18 @@
   - name: post
     manager: IndependentPipelineManager
     trigger:
-      - event: ref-updated
-        ref: ^(?!refs/).*$
+      gerrit:
+        - event: ref-updated
+          ref: ^(?!refs/).*$
 
   - name: gate
     manager: DependentPipelineManager
     failure-message: Build failed.  For information on how to proceed, see http://wiki.example.org/Test_Failures
     trigger:
-      - event: comment-added
-        approval:
-          - approved: 1
+      gerrit:
+        - event: comment-added
+          approval:
+            - approved: 1
     success:
       verified: 2
       submit: true
diff --git a/tests/fixtures/layout.yaml b/tests/fixtures/layout.yaml
index ed63e72..675d351 100644
--- a/tests/fixtures/layout.yaml
+++ b/tests/fixtures/layout.yaml
@@ -5,7 +5,8 @@
   - name: check
     manager: IndependentPipelineManager
     trigger:
-      - event: patchset-created
+      gerrit:
+        - event: patchset-created
     success:
       verified: 1
     failure:
@@ -14,16 +15,18 @@
   - name: post
     manager: IndependentPipelineManager
     trigger:
-      - event: ref-updated
-        ref: ^(?!refs/).*$
+      gerrit:
+        - event: ref-updated
+          ref: ^(?!refs/).*$
 
   - name: gate
     manager: DependentPipelineManager
     failure-message: Build failed.  For information on how to proceed, see http://wiki.example.org/Test_Failures
     trigger:
-      - event: comment-added
-        approval:
-          - approved: 1
+      gerrit:
+        - event: comment-added
+          approval:
+            - approved: 1
     success:
       verified: 2
       submit: true
@@ -37,14 +40,16 @@
     manager: IndependentPipelineManager
     dequeue-on-new-patchset: false
     trigger:
-      - event: comment-added
-        approval:
-          - approved: 1
+      gerrit:
+        - event: comment-added
+          approval:
+            - approved: 1
 
   - name: dup1
     manager: IndependentPipelineManager
     trigger:
-      - event: change-restored
+      gerrit:
+        - event: change-restored
     success:
       verified: 1
     failure:
@@ -53,7 +58,8 @@
   - name: dup2
     manager: IndependentPipelineManager
     trigger:
-      - event: change-restored
+      gerrit:
+        - event: change-restored
     success:
       verified: 1
     failure:
@@ -64,9 +70,10 @@
     manager: DependentPipelineManager
     failure-message: Build failed.  For information on how to proceed, see http://wiki.example.org/Test_Failures
     trigger:
-      - event: comment-added
-        approval:
-          - approved: 1
+      gerrit:
+        - event: comment-added
+          approval:
+            - approved: 1
     success:
       verified: 2
       submit: true
diff --git a/tests/fixtures/layouts/bad_pipelines4.yaml b/tests/fixtures/layouts/bad_pipelines4.yaml
index a99b9e2..7f58024 100644
--- a/tests/fixtures/layouts/bad_pipelines4.yaml
+++ b/tests/fixtures/layouts/bad_pipelines4.yaml
@@ -2,7 +2,8 @@
   - name: check
     manager: IndependentPipelineManager
     trigger:
-      - event: non-event
+      gerrit:
+        - event: non-event
 
 projects:
   - name: foo
diff --git a/tests/fixtures/layouts/bad_pipelines5.yaml b/tests/fixtures/layouts/bad_pipelines5.yaml
index 7db7bd1..929c1a9 100644
--- a/tests/fixtures/layouts/bad_pipelines5.yaml
+++ b/tests/fixtures/layouts/bad_pipelines5.yaml
@@ -2,8 +2,9 @@
   - name: check
     manager: IndependentPipelineManager
     trigger:
-      - approval:
-          - approved: 1
+      gerrit:
+        - approval:
+            - approved: 1
 
 projects:
   - name: foo
diff --git a/tests/fixtures/layouts/bad_pipelines6.yaml b/tests/fixtures/layouts/bad_pipelines6.yaml
index 8d313bc..6dcdaf3 100644
--- a/tests/fixtures/layouts/bad_pipelines6.yaml
+++ b/tests/fixtures/layouts/bad_pipelines6.yaml
@@ -2,8 +2,9 @@
   - name: check
     manager: IndependentPipelineManager
     trigger:
-      - event: comment-added
-        approved: 1
+      gerrit:
+        - event: comment-added
+          approved: 1
 
 projects:
   - name: foo
diff --git a/tests/fixtures/layouts/bad_template1.yaml b/tests/fixtures/layouts/bad_template1.yaml
index 43da793..15822d1 100644
--- a/tests/fixtures/layouts/bad_template1.yaml
+++ b/tests/fixtures/layouts/bad_template1.yaml
@@ -4,7 +4,8 @@
   - name: 'check'
     manager: IndependentPipelineManager
     trigger:
-     - event: patchset-created
+      gerrit:
+        - event: patchset-created
 
 project-templates:
   - name: template-generic
diff --git a/tests/fixtures/layouts/bad_template2.yaml b/tests/fixtures/layouts/bad_template2.yaml
index 0e40d2d..b731543 100644
--- a/tests/fixtures/layouts/bad_template2.yaml
+++ b/tests/fixtures/layouts/bad_template2.yaml
@@ -4,7 +4,8 @@
   - name: 'check'
     manager: IndependentPipelineManager
     trigger:
-     - event: patchset-created
+      gerrit:
+        - event: patchset-created
 
 project-templates:
   - name: template-generic
diff --git a/tests/fixtures/layouts/good_layout.yaml b/tests/fixtures/layouts/good_layout.yaml
index 76a76d9..15be6ef 100644
--- a/tests/fixtures/layouts/good_layout.yaml
+++ b/tests/fixtures/layouts/good_layout.yaml
@@ -5,7 +5,8 @@
   - name: check
     manager: IndependentPipelineManager
     trigger:
-      - event: patchset-created
+      gerrit:
+        - event: patchset-created
     success:
       verified: 1
     failure:
@@ -14,17 +15,19 @@
   - name: post
     manager: IndependentPipelineManager
     trigger:
-      - event: ref-updated
-        ref: ^(?!refs/).*$
+      gerrit:
+        - event: ref-updated
+          ref: ^(?!refs/).*$
 
   - name: gate
     manager: DependentPipelineManager
     success-message: Your change is awesome.
     failure-message: Build failed.  For information on how to proceed, see http://wiki.example.org/Test_Failures
     trigger:
-      - event: comment-added
-        approval:
-          - approved: 1
+      gerrit:
+        - event: comment-added
+          approval:
+            - approved: 1
     success:
       verified: 2
       code-review: 1
diff --git a/tests/fixtures/layouts/good_template1.yaml b/tests/fixtures/layouts/good_template1.yaml
index 1d179f7..ad060a4 100644
--- a/tests/fixtures/layouts/good_template1.yaml
+++ b/tests/fixtures/layouts/good_template1.yaml
@@ -2,7 +2,8 @@
   - name: 'check'
     manager: IndependentPipelineManager
     trigger:
-     - event: patchset-created
+      gerrit:
+        - event: patchset-created
 
 project-templates:
   - name: template-generic
diff --git a/tests/test_layoutvalidator.py b/tests/test_layoutvalidator.py
index f822546..6881bc9 100644
--- a/tests/test_layoutvalidator.py
+++ b/tests/test_layoutvalidator.py
@@ -28,7 +28,7 @@
 LAYOUT_RE = re.compile(r'^(good|bad)_.*\.yaml$')
 
 
-class testScheduler(testtools.TestCase):
+class TestLayoutValidator(testtools.TestCase):
     def test_layouts(self):
         """Test layout file validation"""
         print
diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py
index de000c0..494e1a9 100644
--- a/tests/test_scheduler.py
+++ b/tests/test_scheduler.py
@@ -761,7 +761,7 @@
         self.webapp = zuul.webapp.WebApp(self.sched, port=0)
 
         self.sched.setLauncher(self.launcher)
-        self.sched.setTrigger(self.gerrit)
+        self.sched.registerTrigger(self.gerrit)
 
         self.sched.start()
         self.sched.reconfigure(self.config)
@@ -777,7 +777,7 @@
 
     def assertFinalState(self):
         # Make sure that the change cache is cleared
-        self.assertEqual(len(self.sched.trigger._change_cache.keys()), 0)
+        self.assertEqual(len(self.gerrit._change_cache.keys()), 0)
         self.assertEmptyQueues()
 
     def shutdown(self):
@@ -1440,9 +1440,9 @@
         self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
         self.waitUntilSettled()
 
-        self.log.debug("len %s " % self.sched.trigger._change_cache.keys())
+        self.log.debug("len %s " % self.gerrit._change_cache.keys())
         # there should still be changes in the cache
-        self.assertNotEqual(len(self.sched.trigger._change_cache.keys()), 0)
+        self.assertNotEqual(len(self.gerrit._change_cache.keys()), 0)
 
         self.worker.hold_jobs_in_build = False
         self.worker.release()
@@ -1457,21 +1457,19 @@
         "Test whether a change is ready to merge"
         # TODO: move to test_gerrit (this is a unit test!)
         A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
-        a = self.sched.trigger.getChange(1, 2)
+        trigger = self.sched.layout.pipelines['gate'].trigger
+        a = self.sched.triggers['gerrit'].getChange(1, 2)
         mgr = self.sched.layout.pipelines['gate'].manager
-        self.assertFalse(
-            self.sched.trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
+        self.assertFalse(trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
 
         A.addApproval('CRVW', 2)
-        a = self.sched.trigger.getChange(1, 2, refresh=True)
-        self.assertFalse(
-            self.sched.trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
+        a = trigger.getChange(1, 2, refresh=True)
+        self.assertFalse(trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
 
         A.addApproval('APRV', 1)
-        a = self.sched.trigger.getChange(1, 2, refresh=True)
-        self.assertTrue(
-            self.sched.trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
-        self.sched.trigger.maintainCache([])
+        a = trigger.getChange(1, 2, refresh=True)
+        self.assertTrue(trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
+        trigger.maintainCache([])
 
     def test_build_configuration(self):
         "Test that zuul merges the right commits for testing"
@@ -2347,6 +2345,7 @@
     def test_test_config(self):
         "Test that we can test the config"
         sched = zuul.scheduler.Scheduler()
+        sched.registerTrigger(None, 'gerrit')
         sched.testConfig(CONFIG.get('zuul', 'layout_config'))
 
     def test_build_description(self):