summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJames E. Blair <jeblair@hp.com>2014-08-06 09:23:52 -0700
committerJames E. Blair <jeblair@openstack.org>2014-08-15 10:38:16 -0700
commitc494d5456bd691c988ae02572612615e358c1e7d (patch)
tree6886c9ac425b3a5d6db95848869f408502b44e44 /tests
parentc0dedf8b3ff39ab90ce5c44acc03ed027851e584 (diff)
downloadzuul-c494d5456bd691c988ae02572612615e358c1e7d.tar.gz
Add a Zuul trigger
This adds the ability for a pipelite to have multiple triggers. This also adds a "Zuul" trigger which is used to generate trigger events based on internal actions Zuul has taken. It supports two event types: * parent-change-enqueued: This can be used so that other pipelines can enqueue children of parents that are enqueued in a different pipeline. Specifically, this lets OpenStack enqueue changes in check when their parents are enqueued in gate (which may be necessary because of our clean check rules). This could be used to replace the internal logic that enqueues children in dependent pipelines (moving that into explicit configuration instead). One can also imagine a future 'change-enqueued' event so that a pipeline could react directly to a change in another. * project-change-merged: This can be used to trigger changes on all open changes for a project when a change is merged to that project. Specifically, this lets us perform light-weight merge checks on all open changes whenever a change is merged. Change-Id: I2a67699dbed92a6b9c143a77795cb126f1f4dd57
Diffstat (limited to 'tests')
-rwxr-xr-xtests/base.py8
-rw-r--r--tests/fixtures/layout-zuultrigger-enqueued.yaml53
-rw-r--r--tests/fixtures/layout-zuultrigger-merged.yaml53
-rwxr-xr-xtests/test_scheduler.py1
-rw-r--r--tests/test_zuultrigger.py104
5 files changed, 219 insertions, 0 deletions
diff --git a/tests/base.py b/tests/base.py
index a86de82d7..1b8294486 100755
--- a/tests/base.py
+++ b/tests/base.py
@@ -52,6 +52,7 @@ import zuul.reporter.gerrit
import zuul.reporter.smtp
import zuul.trigger.gerrit
import zuul.trigger.timer
+import zuul.trigger.zuultrigger
FIXTURE_DIR = os.path.join(os.path.dirname(__file__),
'fixtures')
@@ -401,6 +402,11 @@ class FakeGerrit(object):
return change.query()
return {}
+ def simpleQuery(self, query):
+ # This is currently only used to return all open changes for a
+ # project
+ return [change.query() for change in self.changes.values()]
+
def startWatching(self, *args, **kw):
pass
@@ -906,6 +912,8 @@ class ZuulTestCase(testtools.TestCase):
self.sched.registerTrigger(self.gerrit)
self.timer = zuul.trigger.timer.Timer(self.config, self.sched)
self.sched.registerTrigger(self.timer)
+ self.zuultrigger = zuul.trigger.zuultrigger.ZuulTrigger(self.config, self.sched)
+ self.sched.registerTrigger(self.zuultrigger)
self.sched.registerReporter(
zuul.reporter.gerrit.Reporter(self.gerrit))
diff --git a/tests/fixtures/layout-zuultrigger-enqueued.yaml b/tests/fixtures/layout-zuultrigger-enqueued.yaml
new file mode 100644
index 000000000..8babd9e71
--- /dev/null
+++ b/tests/fixtures/layout-zuultrigger-enqueued.yaml
@@ -0,0 +1,53 @@
+pipelines:
+ - name: check
+ manager: IndependentPipelineManager
+ source: gerrit
+ require:
+ approval:
+ - verified: -1
+ trigger:
+ gerrit:
+ - event: patchset-created
+ zuul:
+ - event: parent-change-enqueued
+ pipeline: gate
+ success:
+ gerrit:
+ verified: 1
+ failure:
+ gerrit:
+ verified: -1
+
+ - name: gate
+ manager: DependentPipelineManager
+ failure-message: Build failed. For information on how to proceed, see http://wiki.example.org/Test_Failures
+ source: gerrit
+ require:
+ approval:
+ - verified: 1
+ trigger:
+ gerrit:
+ - event: comment-added
+ approval:
+ - approved: 1
+ zuul:
+ - event: parent-change-enqueued
+ pipeline: gate
+ success:
+ gerrit:
+ verified: 2
+ submit: true
+ failure:
+ gerrit:
+ verified: -2
+ start:
+ gerrit:
+ verified: 0
+ precedence: high
+
+projects:
+ - name: org/project
+ check:
+ - project-check
+ gate:
+ - project-gate
diff --git a/tests/fixtures/layout-zuultrigger-merged.yaml b/tests/fixtures/layout-zuultrigger-merged.yaml
new file mode 100644
index 000000000..657700dfe
--- /dev/null
+++ b/tests/fixtures/layout-zuultrigger-merged.yaml
@@ -0,0 +1,53 @@
+pipelines:
+ - name: check
+ manager: IndependentPipelineManager
+ source: gerrit
+ trigger:
+ gerrit:
+ - event: patchset-created
+ success:
+ gerrit:
+ verified: 1
+ failure:
+ gerrit:
+ verified: -1
+
+ - name: gate
+ manager: DependentPipelineManager
+ failure-message: Build failed. For information on how to proceed, see http://wiki.example.org/Test_Failures
+ source: gerrit
+ trigger:
+ gerrit:
+ - event: comment-added
+ approval:
+ - approved: 1
+ success:
+ gerrit:
+ verified: 2
+ submit: true
+ failure:
+ gerrit:
+ verified: -2
+ start:
+ gerrit:
+ verified: 0
+ precedence: high
+
+ - name: merge-check
+ manager: IndependentPipelineManager
+ source: gerrit
+ trigger:
+ zuul:
+ - event: project-change-merged
+ merge-failure:
+ gerrit:
+ verified: -1
+
+projects:
+ - name: org/project
+ check:
+ - project-check
+ gate:
+ - project-gate
+ merge-check:
+ - noop
diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py
index fe6a584d1..d22a7cae0 100755
--- a/tests/test_scheduler.py
+++ b/tests/test_scheduler.py
@@ -1737,6 +1737,7 @@ class TestScheduler(ZuulTestCase):
sched = zuul.scheduler.Scheduler()
sched.registerTrigger(None, 'gerrit')
sched.registerTrigger(None, 'timer')
+ sched.registerTrigger(None, 'zuul')
sched.testConfig(self.config.get('zuul', 'layout_config'))
def test_build_description(self):
diff --git a/tests/test_zuultrigger.py b/tests/test_zuultrigger.py
new file mode 100644
index 000000000..eb8fdc533
--- /dev/null
+++ b/tests/test_zuultrigger.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+
+# Copyright 2014 Hewlett-Packard Development Company, L.P.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import logging
+import time
+
+from tests.base import ZuulTestCase
+
+logging.basicConfig(level=logging.DEBUG,
+ format='%(asctime)s %(name)-32s '
+ '%(levelname)-8s %(message)s')
+
+
+class TestZuulTrigger(ZuulTestCase):
+ """Test Zuul Trigger"""
+
+ def test_zuul_trigger_parent_change_enqueued(self):
+ "Test Zuul trigger event: parent-change-enqueued"
+ self.config.set('zuul', 'layout_config',
+ 'tests/fixtures/layout-zuultrigger-enqueued.yaml')
+ self.sched.reconfigure(self.config)
+ self.registerJobs()
+
+ # This test has the following three changes:
+ # B1 -> A; B2 -> A
+ # When A is enqueued in the gate, B1 and B2 should both attempt
+ # to be enqueued in both pipelines. B1 should end up in check
+ # and B2 in gate because of differing pipeline requirements.
+ self.worker.hold_jobs_in_build = True
+ A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
+ B1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'B1')
+ B2 = self.fake_gerrit.addFakeChange('org/project', 'master', 'B2')
+ A.addApproval('CRVW', 2)
+ B1.addApproval('CRVW', 2)
+ B2.addApproval('CRVW', 2)
+ A.addApproval('VRFY', 1) # required by gate
+ B1.addApproval('VRFY', -1) # should go to check
+ B2.addApproval('VRFY', 1) # should go to gate
+ B1.addApproval('APRV', 1)
+ B2.addApproval('APRV', 1)
+ B1.setDependsOn(A, 1)
+ B2.setDependsOn(A, 1)
+ self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
+ # Jobs are being held in build to make sure that 3,1 has time
+ # to enqueue behind 1,1 so that the test is more
+ # deterministic.
+ self.waitUntilSettled()
+ self.worker.hold_jobs_in_build = False
+ self.worker.release()
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.history), 3)
+ for job in self.history:
+ if job.changes == '1,1':
+ self.assertEqual(job.name, 'project-gate')
+ elif job.changes == '2,1':
+ self.assertEqual(job.name, 'project-check')
+ elif job.changes == '1,1 3,1':
+ self.assertEqual(job.name, 'project-gate')
+ else:
+ raise Exception("Unknown job")
+
+ def test_zuul_trigger_project_change_merged(self):
+ "Test Zuul trigger event: project-change-merged"
+ self.config.set('zuul', 'layout_config',
+ 'tests/fixtures/layout-zuultrigger-merged.yaml')
+ self.sched.reconfigure(self.config)
+ self.registerJobs()
+
+ # This test has the following three changes:
+ # A, B, C; B conflicts with A, but C does not.
+ # When A is merged, B and C should be checked for conflicts,
+ # and B should receive a -1.
+ A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
+ B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
+ C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
+ A.addPatchset(['conflict'])
+ B.addPatchset(['conflict'])
+ A.addApproval('CRVW', 2)
+ self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
+ self.waitUntilSettled()
+
+ self.assertEqual(len(self.history), 1)
+ self.assertEqual(self.history[0].name, 'project-gate')
+ self.assertEqual(A.reported, 2)
+ self.assertEqual(B.reported, 1)
+ self.assertEqual(C.reported, 0)
+ self.assertEqual(B.messages[0],
+ "Merge Failed.\n\nThis change was unable to be automatically "
+ "merged with the current state of the repository. Please rebase "
+ "your change and upload a new patchset.")