blob: 120e37e0f850ce3e58b4e353375bd0d4fb475ffd [file] [log] [blame]
James E. Blair9c17dbf2014-06-23 14:21:58 -07001#!/usr/bin/env python
2
3# Copyright 2012-2014 Hewlett-Packard Development Company, L.P.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16
17import logging
18import time
19
20from tests.base import ZuulTestCase
21
22logging.basicConfig(level=logging.DEBUG,
23 format='%(asctime)s %(name)-32s '
24 '%(levelname)-8s %(message)s')
25
26
27class TestRequirements(ZuulTestCase):
28 """Test pipeline and trigger requirements"""
29
30 def test_pipeline_require_approval_newer_than(self):
31 "Test pipeline requirement: approval newer than"
32 return self._test_require_approval_newer_than('org/project1',
33 'project1-pipeline')
34
35 def test_trigger_require_approval_newer_than(self):
36 "Test trigger requirement: approval newer than"
37 return self._test_require_approval_newer_than('org/project2',
38 'project2-trigger')
39
40 def _test_require_approval_newer_than(self, project, job):
41 self.config.set('zuul', 'layout_config',
42 'tests/fixtures/layout-requirement-newer-than.yaml')
43 self.sched.reconfigure(self.config)
44 self.registerJobs()
45
46 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
47 # A comment event that we will keep submitting to trigger
48 comment = A.addApproval('CRVW', 2, username='nobody')
49 self.fake_gerrit.addEvent(comment)
50 self.waitUntilSettled()
51 # No +1 from Jenkins so should not be enqueued
52 self.assertEqual(len(self.history), 0)
53
54 # Add a too-old +1, should not be enqueued
55 A.addApproval('VRFY', 1, granted_on=time.time() - 72 * 60 * 60)
56 self.fake_gerrit.addEvent(comment)
57 self.waitUntilSettled()
58 self.assertEqual(len(self.history), 0)
59
60 # Add a recent +1
61 self.fake_gerrit.addEvent(A.addApproval('VRFY', 1))
62 self.fake_gerrit.addEvent(comment)
63 self.waitUntilSettled()
64 self.assertEqual(len(self.history), 1)
65 self.assertEqual(self.history[0].name, job)
66
67 def test_pipeline_require_approval_older_than(self):
68 "Test pipeline requirement: approval older than"
69 return self._test_require_approval_older_than('org/project1',
70 'project1-pipeline')
71
72 def test_trigger_require_approval_older_than(self):
73 "Test trigger requirement: approval older than"
74 return self._test_require_approval_older_than('org/project2',
75 'project2-trigger')
76
77 def _test_require_approval_older_than(self, project, job):
78 self.config.set('zuul', 'layout_config',
79 'tests/fixtures/layout-requirement-older-than.yaml')
80 self.sched.reconfigure(self.config)
81 self.registerJobs()
82
83 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
84 # A comment event that we will keep submitting to trigger
85 comment = A.addApproval('CRVW', 2, username='nobody')
86 self.fake_gerrit.addEvent(comment)
87 self.waitUntilSettled()
88 # No +1 from Jenkins so should not be enqueued
89 self.assertEqual(len(self.history), 0)
90
91 # Add a recent +1 which should not be enqueued
92 A.addApproval('VRFY', 1)
93 self.fake_gerrit.addEvent(comment)
94 self.waitUntilSettled()
95 self.assertEqual(len(self.history), 0)
96
97 # Add an old +1 which should be enqueued
98 A.addApproval('VRFY', 1, granted_on=time.time() - 72 * 60 * 60)
99 self.fake_gerrit.addEvent(comment)
100 self.waitUntilSettled()
101 self.assertEqual(len(self.history), 1)
102 self.assertEqual(self.history[0].name, job)
103
104 def test_pipeline_require_approval_username(self):
105 "Test pipeline requirement: approval username"
106 return self._test_require_approval_username('org/project1',
107 'project1-pipeline')
108
109 def test_trigger_require_approval_username(self):
110 "Test trigger requirement: approval username"
111 return self._test_require_approval_username('org/project2',
112 'project2-trigger')
113
114 def _test_require_approval_username(self, project, job):
115 self.config.set('zuul', 'layout_config',
116 'tests/fixtures/layout-requirement-username.yaml')
117 self.sched.reconfigure(self.config)
118 self.registerJobs()
119
120 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
121 # A comment event that we will keep submitting to trigger
122 comment = A.addApproval('CRVW', 2, username='nobody')
123 self.fake_gerrit.addEvent(comment)
124 self.waitUntilSettled()
125 # No approval from Jenkins so should not be enqueued
126 self.assertEqual(len(self.history), 0)
127
128 # Add an approval from Jenkins
129 A.addApproval('VRFY', 1)
130 self.fake_gerrit.addEvent(comment)
131 self.waitUntilSettled()
132 self.assertEqual(len(self.history), 1)
133 self.assertEqual(self.history[0].name, job)
134
135 def test_pipeline_require_approval_email(self):
136 "Test pipeline requirement: approval email"
137 return self._test_require_approval_email('org/project1',
138 'project1-pipeline')
139
140 def test_trigger_require_approval_email(self):
141 "Test trigger requirement: approval email"
142 return self._test_require_approval_email('org/project2',
143 'project2-trigger')
144
145 def _test_require_approval_email(self, project, job):
146 self.config.set('zuul', 'layout_config',
147 'tests/fixtures/layout-requirement-email.yaml')
148 self.sched.reconfigure(self.config)
149 self.registerJobs()
150
151 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
152 # A comment event that we will keep submitting to trigger
153 comment = A.addApproval('CRVW', 2, username='nobody')
154 self.fake_gerrit.addEvent(comment)
155 self.waitUntilSettled()
156 # No approval from Jenkins so should not be enqueued
157 self.assertEqual(len(self.history), 0)
158
159 # Add an approval from Jenkins
160 A.addApproval('VRFY', 1)
161 self.fake_gerrit.addEvent(comment)
162 self.waitUntilSettled()
163 self.assertEqual(len(self.history), 1)
164 self.assertEqual(self.history[0].name, job)
165
166 def test_pipeline_require_approval_vote1(self):
167 "Test pipeline requirement: approval vote with one value"
168 return self._test_require_approval_vote1('org/project1',
169 'project1-pipeline')
170
171 def test_trigger_require_approval_vote1(self):
172 "Test trigger requirement: approval vote with one value"
173 return self._test_require_approval_vote1('org/project2',
174 'project2-trigger')
175
176 def _test_require_approval_vote1(self, project, job):
177 self.config.set('zuul', 'layout_config',
178 'tests/fixtures/layout-requirement-vote1.yaml')
179 self.sched.reconfigure(self.config)
180 self.registerJobs()
181
182 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
183 # A comment event that we will keep submitting to trigger
184 comment = A.addApproval('CRVW', 2, username='nobody')
185 self.fake_gerrit.addEvent(comment)
186 self.waitUntilSettled()
187 # No approval from Jenkins so should not be enqueued
188 self.assertEqual(len(self.history), 0)
189
190 # A -1 from jenkins should not cause it to be enqueued
191 A.addApproval('VRFY', -1)
192 self.fake_gerrit.addEvent(comment)
193 self.waitUntilSettled()
194 self.assertEqual(len(self.history), 0)
195
196 # A +1 should allow it to be enqueued
197 A.addApproval('VRFY', 1)
198 self.fake_gerrit.addEvent(comment)
199 self.waitUntilSettled()
200 self.assertEqual(len(self.history), 1)
201 self.assertEqual(self.history[0].name, job)
202
203 def test_pipeline_require_approval_vote2(self):
204 "Test pipeline requirement: approval vote with two values"
205 return self._test_require_approval_vote2('org/project1',
206 'project1-pipeline')
207
208 def test_trigger_require_approval_vote2(self):
209 "Test trigger requirement: approval vote with two values"
210 return self._test_require_approval_vote2('org/project2',
211 'project2-trigger')
212
213 def _test_require_approval_vote2(self, project, job):
214 self.config.set('zuul', 'layout_config',
215 'tests/fixtures/layout-requirement-vote2.yaml')
216 self.sched.reconfigure(self.config)
217 self.registerJobs()
218
219 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
220 # A comment event that we will keep submitting to trigger
221 comment = A.addApproval('CRVW', 2, username='nobody')
222 self.fake_gerrit.addEvent(comment)
223 self.waitUntilSettled()
224 # No approval from Jenkins so should not be enqueued
225 self.assertEqual(len(self.history), 0)
226
227 # A -1 from jenkins should not cause it to be enqueued
228 A.addApproval('VRFY', -1)
229 self.fake_gerrit.addEvent(comment)
230 self.waitUntilSettled()
231 self.assertEqual(len(self.history), 0)
232
233 # A -2 from jenkins should not cause it to be enqueued
234 A.addApproval('VRFY', -2)
235 self.fake_gerrit.addEvent(comment)
236 self.waitUntilSettled()
237 self.assertEqual(len(self.history), 0)
238
239 # A +1 should allow it to be enqueued
240 A.addApproval('VRFY', 1)
241 self.fake_gerrit.addEvent(comment)
242 self.waitUntilSettled()
243 self.assertEqual(len(self.history), 1)
244 self.assertEqual(self.history[0].name, job)
245
246 # A +2 should allow it to be enqueued
247 B = self.fake_gerrit.addFakeChange(project, 'master', 'B')
248 # A comment event that we will keep submitting to trigger
249 comment = B.addApproval('CRVW', 2, username='nobody')
250 self.fake_gerrit.addEvent(comment)
251 self.waitUntilSettled()
252 self.assertEqual(len(self.history), 1)
253
254 B.addApproval('VRFY', 2)
255 self.fake_gerrit.addEvent(comment)
256 self.waitUntilSettled()
257 self.assertEqual(len(self.history), 2)
258 self.assertEqual(self.history[1].name, job)
259
260 def test_pipeline_require_current_patchset(self):
261 "Test pipeline requirement: current-patchset"
262 self.config.set('zuul', 'layout_config',
263 'tests/fixtures/layout-requirement-'
264 'current-patchset.yaml')
265 self.sched.reconfigure(self.config)
266 self.registerJobs()
267 # Create two patchsets and let their tests settle out. Then
268 # comment on first patchset and check that no additional
269 # jobs are run.
270 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
271 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1))
272 self.waitUntilSettled()
273 A.addPatchset()
274 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1))
275 self.waitUntilSettled()
276
277 self.assertEqual(len(self.history), 2) # one job for each ps
278 self.fake_gerrit.addEvent(A.getChangeCommentEvent(1))
279 self.waitUntilSettled()
280
281 # Assert no new jobs ran after event for old patchset.
282 self.assertEqual(len(self.history), 2)
283
284 # Make sure the same event on a new PS will trigger
285 self.fake_gerrit.addEvent(A.getChangeCommentEvent(2))
286 self.waitUntilSettled()
287 self.assertEqual(len(self.history), 3)
288
289 def test_pipeline_require_open(self):
290 "Test pipeline requirement: open"
291 self.config.set('zuul', 'layout_config',
292 'tests/fixtures/layout-requirement-open.yaml')
293 self.sched.reconfigure(self.config)
294 self.registerJobs()
295
296 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
297 status='MERGED')
298 self.fake_gerrit.addEvent(A.addApproval('CRVW', 2))
299 self.waitUntilSettled()
300 self.assertEqual(len(self.history), 0)
301
302 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
303 self.fake_gerrit.addEvent(B.addApproval('CRVW', 2))
304 self.waitUntilSettled()
305 self.assertEqual(len(self.history), 1)
306
307 def test_pipeline_require_status(self):
308 "Test pipeline requirement: status"
309 self.config.set('zuul', 'layout_config',
310 'tests/fixtures/layout-requirement-status.yaml')
311 self.sched.reconfigure(self.config)
312 self.registerJobs()
313
314 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
315 status='MERGED')
316 self.fake_gerrit.addEvent(A.addApproval('CRVW', 2))
317 self.waitUntilSettled()
318 self.assertEqual(len(self.history), 0)
319
320 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
321 self.fake_gerrit.addEvent(B.addApproval('CRVW', 2))
322 self.waitUntilSettled()
323 self.assertEqual(len(self.history), 1)