blob: 1f179e6208849813912f8c09ca0c3df32b89ce60 [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
Jamie Lennoxff3e0b92016-11-23 10:38:25 +110019from unittest import skip
James E. Blair9c17dbf2014-06-23 14:21:58 -070020
21from tests.base import ZuulTestCase
22
23logging.basicConfig(level=logging.DEBUG,
24 format='%(asctime)s %(name)-32s '
25 '%(levelname)-8s %(message)s')
26
27
28class TestRequirements(ZuulTestCase):
29 """Test pipeline and trigger requirements"""
30
Jamie Lennoxff3e0b92016-11-23 10:38:25 +110031 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -070032 def test_pipeline_require_approval_newer_than(self):
33 "Test pipeline requirement: approval newer than"
34 return self._test_require_approval_newer_than('org/project1',
35 'project1-pipeline')
36
Jamie Lennoxff3e0b92016-11-23 10:38:25 +110037 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -070038 def test_trigger_require_approval_newer_than(self):
39 "Test trigger requirement: approval newer than"
40 return self._test_require_approval_newer_than('org/project2',
41 'project2-trigger')
42
43 def _test_require_approval_newer_than(self, project, job):
James E. Blairf84026c2015-12-08 16:11:46 -080044 self.updateConfigLayout(
45 'tests/fixtures/layout-requirement-newer-than.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -070046 self.sched.reconfigure(self.config)
47 self.registerJobs()
48
49 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
50 # A comment event that we will keep submitting to trigger
51 comment = A.addApproval('CRVW', 2, username='nobody')
52 self.fake_gerrit.addEvent(comment)
53 self.waitUntilSettled()
54 # No +1 from Jenkins so should not be enqueued
55 self.assertEqual(len(self.history), 0)
56
57 # Add a too-old +1, should not be enqueued
Joshua Hesketh642824b2014-07-01 17:54:59 +100058 A.addApproval('VRFY', 1, username='jenkins',
59 granted_on=time.time() - 72 * 60 * 60)
James E. Blair9c17dbf2014-06-23 14:21:58 -070060 self.fake_gerrit.addEvent(comment)
61 self.waitUntilSettled()
62 self.assertEqual(len(self.history), 0)
63
64 # Add a recent +1
Joshua Hesketh642824b2014-07-01 17:54:59 +100065 self.fake_gerrit.addEvent(A.addApproval('VRFY', 1, username='jenkins'))
James E. Blair9c17dbf2014-06-23 14:21:58 -070066 self.fake_gerrit.addEvent(comment)
67 self.waitUntilSettled()
68 self.assertEqual(len(self.history), 1)
69 self.assertEqual(self.history[0].name, job)
70
Jamie Lennoxff3e0b92016-11-23 10:38:25 +110071 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -070072 def test_pipeline_require_approval_older_than(self):
73 "Test pipeline requirement: approval older than"
74 return self._test_require_approval_older_than('org/project1',
75 'project1-pipeline')
76
Jamie Lennoxff3e0b92016-11-23 10:38:25 +110077 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -070078 def test_trigger_require_approval_older_than(self):
79 "Test trigger requirement: approval older than"
80 return self._test_require_approval_older_than('org/project2',
81 'project2-trigger')
82
83 def _test_require_approval_older_than(self, project, job):
James E. Blairf84026c2015-12-08 16:11:46 -080084 self.updateConfigLayout(
85 'tests/fixtures/layout-requirement-older-than.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -070086 self.sched.reconfigure(self.config)
87 self.registerJobs()
88
89 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
90 # A comment event that we will keep submitting to trigger
91 comment = A.addApproval('CRVW', 2, username='nobody')
92 self.fake_gerrit.addEvent(comment)
93 self.waitUntilSettled()
94 # No +1 from Jenkins so should not be enqueued
95 self.assertEqual(len(self.history), 0)
96
97 # Add a recent +1 which should not be enqueued
98 A.addApproval('VRFY', 1)
99 self.fake_gerrit.addEvent(comment)
100 self.waitUntilSettled()
101 self.assertEqual(len(self.history), 0)
102
103 # Add an old +1 which should be enqueued
Joshua Hesketh642824b2014-07-01 17:54:59 +1000104 A.addApproval('VRFY', 1, username='jenkins',
105 granted_on=time.time() - 72 * 60 * 60)
James E. Blair9c17dbf2014-06-23 14:21:58 -0700106 self.fake_gerrit.addEvent(comment)
107 self.waitUntilSettled()
108 self.assertEqual(len(self.history), 1)
109 self.assertEqual(self.history[0].name, job)
110
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100111 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700112 def test_pipeline_require_approval_username(self):
113 "Test pipeline requirement: approval username"
114 return self._test_require_approval_username('org/project1',
115 'project1-pipeline')
116
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100117 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700118 def test_trigger_require_approval_username(self):
119 "Test trigger requirement: approval username"
120 return self._test_require_approval_username('org/project2',
121 'project2-trigger')
122
123 def _test_require_approval_username(self, project, job):
James E. Blairf84026c2015-12-08 16:11:46 -0800124 self.updateConfigLayout(
125 'tests/fixtures/layout-requirement-username.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700126 self.sched.reconfigure(self.config)
127 self.registerJobs()
128
129 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
130 # A comment event that we will keep submitting to trigger
131 comment = A.addApproval('CRVW', 2, username='nobody')
132 self.fake_gerrit.addEvent(comment)
133 self.waitUntilSettled()
134 # No approval from Jenkins so should not be enqueued
135 self.assertEqual(len(self.history), 0)
136
137 # Add an approval from Jenkins
Joshua Hesketh642824b2014-07-01 17:54:59 +1000138 A.addApproval('VRFY', 1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700139 self.fake_gerrit.addEvent(comment)
140 self.waitUntilSettled()
141 self.assertEqual(len(self.history), 1)
142 self.assertEqual(self.history[0].name, job)
143
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100144 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700145 def test_pipeline_require_approval_email(self):
146 "Test pipeline requirement: approval email"
147 return self._test_require_approval_email('org/project1',
148 'project1-pipeline')
149
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100150 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700151 def test_trigger_require_approval_email(self):
152 "Test trigger requirement: approval email"
153 return self._test_require_approval_email('org/project2',
154 'project2-trigger')
155
156 def _test_require_approval_email(self, project, job):
James E. Blairf84026c2015-12-08 16:11:46 -0800157 self.updateConfigLayout(
158 'tests/fixtures/layout-requirement-email.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700159 self.sched.reconfigure(self.config)
160 self.registerJobs()
161
162 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
163 # A comment event that we will keep submitting to trigger
164 comment = A.addApproval('CRVW', 2, username='nobody')
165 self.fake_gerrit.addEvent(comment)
166 self.waitUntilSettled()
167 # No approval from Jenkins so should not be enqueued
168 self.assertEqual(len(self.history), 0)
169
170 # Add an approval from Jenkins
Joshua Hesketh642824b2014-07-01 17:54:59 +1000171 A.addApproval('VRFY', 1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700172 self.fake_gerrit.addEvent(comment)
173 self.waitUntilSettled()
174 self.assertEqual(len(self.history), 1)
175 self.assertEqual(self.history[0].name, job)
176
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100177 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700178 def test_pipeline_require_approval_vote1(self):
179 "Test pipeline requirement: approval vote with one value"
180 return self._test_require_approval_vote1('org/project1',
181 'project1-pipeline')
182
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100183 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700184 def test_trigger_require_approval_vote1(self):
185 "Test trigger requirement: approval vote with one value"
186 return self._test_require_approval_vote1('org/project2',
187 'project2-trigger')
188
189 def _test_require_approval_vote1(self, project, job):
James E. Blairf84026c2015-12-08 16:11:46 -0800190 self.updateConfigLayout(
191 'tests/fixtures/layout-requirement-vote1.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700192 self.sched.reconfigure(self.config)
193 self.registerJobs()
194
195 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
196 # A comment event that we will keep submitting to trigger
197 comment = A.addApproval('CRVW', 2, username='nobody')
198 self.fake_gerrit.addEvent(comment)
199 self.waitUntilSettled()
200 # No approval from Jenkins so should not be enqueued
201 self.assertEqual(len(self.history), 0)
202
203 # A -1 from jenkins should not cause it to be enqueued
Joshua Hesketh642824b2014-07-01 17:54:59 +1000204 A.addApproval('VRFY', -1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700205 self.fake_gerrit.addEvent(comment)
206 self.waitUntilSettled()
207 self.assertEqual(len(self.history), 0)
208
209 # A +1 should allow it to be enqueued
Joshua Hesketh642824b2014-07-01 17:54:59 +1000210 A.addApproval('VRFY', 1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700211 self.fake_gerrit.addEvent(comment)
212 self.waitUntilSettled()
213 self.assertEqual(len(self.history), 1)
214 self.assertEqual(self.history[0].name, job)
215
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100216 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700217 def test_pipeline_require_approval_vote2(self):
218 "Test pipeline requirement: approval vote with two values"
219 return self._test_require_approval_vote2('org/project1',
220 'project1-pipeline')
221
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100222 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700223 def test_trigger_require_approval_vote2(self):
224 "Test trigger requirement: approval vote with two values"
225 return self._test_require_approval_vote2('org/project2',
226 'project2-trigger')
227
228 def _test_require_approval_vote2(self, project, job):
James E. Blairf84026c2015-12-08 16:11:46 -0800229 self.updateConfigLayout(
230 'tests/fixtures/layout-requirement-vote2.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700231 self.sched.reconfigure(self.config)
232 self.registerJobs()
233
234 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
235 # A comment event that we will keep submitting to trigger
236 comment = A.addApproval('CRVW', 2, username='nobody')
237 self.fake_gerrit.addEvent(comment)
238 self.waitUntilSettled()
239 # No approval from Jenkins so should not be enqueued
240 self.assertEqual(len(self.history), 0)
241
242 # A -1 from jenkins should not cause it to be enqueued
Joshua Hesketh642824b2014-07-01 17:54:59 +1000243 A.addApproval('VRFY', -1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700244 self.fake_gerrit.addEvent(comment)
245 self.waitUntilSettled()
246 self.assertEqual(len(self.history), 0)
247
248 # A -2 from jenkins should not cause it to be enqueued
Joshua Hesketh642824b2014-07-01 17:54:59 +1000249 A.addApproval('VRFY', -2, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700250 self.fake_gerrit.addEvent(comment)
251 self.waitUntilSettled()
252 self.assertEqual(len(self.history), 0)
253
Joshua Hesketh642824b2014-07-01 17:54:59 +1000254 # A +1 from jenkins should allow it to be enqueued
255 A.addApproval('VRFY', 1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700256 self.fake_gerrit.addEvent(comment)
257 self.waitUntilSettled()
258 self.assertEqual(len(self.history), 1)
259 self.assertEqual(self.history[0].name, job)
260
261 # A +2 should allow it to be enqueued
262 B = self.fake_gerrit.addFakeChange(project, 'master', 'B')
263 # A comment event that we will keep submitting to trigger
264 comment = B.addApproval('CRVW', 2, username='nobody')
265 self.fake_gerrit.addEvent(comment)
266 self.waitUntilSettled()
267 self.assertEqual(len(self.history), 1)
268
Joshua Hesketh642824b2014-07-01 17:54:59 +1000269 B.addApproval('VRFY', 2, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700270 self.fake_gerrit.addEvent(comment)
271 self.waitUntilSettled()
272 self.assertEqual(len(self.history), 2)
273 self.assertEqual(self.history[1].name, job)
274
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100275 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700276 def test_pipeline_require_current_patchset(self):
277 "Test pipeline requirement: current-patchset"
James E. Blairf84026c2015-12-08 16:11:46 -0800278 self.updateConfigLayout(
279 'tests/fixtures/layout-requirement-current-patchset.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700280 self.sched.reconfigure(self.config)
281 self.registerJobs()
282 # Create two patchsets and let their tests settle out. Then
283 # comment on first patchset and check that no additional
284 # jobs are run.
285 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
286 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1))
287 self.waitUntilSettled()
288 A.addPatchset()
289 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1))
290 self.waitUntilSettled()
291
292 self.assertEqual(len(self.history), 2) # one job for each ps
293 self.fake_gerrit.addEvent(A.getChangeCommentEvent(1))
294 self.waitUntilSettled()
295
296 # Assert no new jobs ran after event for old patchset.
297 self.assertEqual(len(self.history), 2)
298
299 # Make sure the same event on a new PS will trigger
300 self.fake_gerrit.addEvent(A.getChangeCommentEvent(2))
301 self.waitUntilSettled()
302 self.assertEqual(len(self.history), 3)
303
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100304 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700305 def test_pipeline_require_open(self):
306 "Test pipeline requirement: open"
James E. Blairf84026c2015-12-08 16:11:46 -0800307 self.updateConfigLayout(
308 'tests/fixtures/layout-requirement-open.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700309 self.sched.reconfigure(self.config)
310 self.registerJobs()
311
312 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
313 status='MERGED')
314 self.fake_gerrit.addEvent(A.addApproval('CRVW', 2))
315 self.waitUntilSettled()
316 self.assertEqual(len(self.history), 0)
317
318 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
319 self.fake_gerrit.addEvent(B.addApproval('CRVW', 2))
320 self.waitUntilSettled()
321 self.assertEqual(len(self.history), 1)
322
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100323 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700324 def test_pipeline_require_status(self):
325 "Test pipeline requirement: status"
James E. Blairf84026c2015-12-08 16:11:46 -0800326 self.updateConfigLayout(
327 'tests/fixtures/layout-requirement-status.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700328 self.sched.reconfigure(self.config)
329 self.registerJobs()
330
331 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
332 status='MERGED')
333 self.fake_gerrit.addEvent(A.addApproval('CRVW', 2))
334 self.waitUntilSettled()
335 self.assertEqual(len(self.history), 0)
336
337 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
338 self.fake_gerrit.addEvent(B.addApproval('CRVW', 2))
339 self.waitUntilSettled()
340 self.assertEqual(len(self.history), 1)
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000341
342 def _test_require_reject_username(self, project, job):
343 "Test negative username's match"
344 # Should only trigger if Jenkins hasn't voted.
James E. Blairf84026c2015-12-08 16:11:46 -0800345 self.updateConfigLayout(
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000346 'tests/fixtures/layout-requirement-reject-username.yaml')
347 self.sched.reconfigure(self.config)
348 self.registerJobs()
349
350 # add in a change with no comments
351 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
352 self.waitUntilSettled()
353 self.assertEqual(len(self.history), 0)
354
355 # add in a comment that will trigger
356 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1,
357 username='reviewer'))
358 self.waitUntilSettled()
359 self.assertEqual(len(self.history), 1)
360 self.assertEqual(self.history[0].name, job)
361
362 # add in a comment from jenkins user which shouldn't trigger
363 self.fake_gerrit.addEvent(A.addApproval('VRFY', 1, username='jenkins'))
364 self.waitUntilSettled()
365 self.assertEqual(len(self.history), 1)
366
367 # Check future reviews also won't trigger as a 'jenkins' user has
368 # commented previously
369 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1,
370 username='reviewer'))
371 self.waitUntilSettled()
372 self.assertEqual(len(self.history), 1)
373
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100374 @skip("Disabled for early v3 development")
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000375 def test_pipeline_reject_username(self):
376 "Test negative pipeline requirement: no comment from jenkins"
377 return self._test_require_reject_username('org/project1',
378 'project1-pipeline')
379
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100380 @skip("Disabled for early v3 development")
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000381 def test_trigger_reject_username(self):
382 "Test negative trigger requirement: no comment from jenkins"
383 return self._test_require_reject_username('org/project2',
384 'project2-trigger')
385
386 def _test_require_reject(self, project, job):
387 "Test no approval matches a reject param"
James E. Blairf84026c2015-12-08 16:11:46 -0800388 self.updateConfigLayout(
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000389 'tests/fixtures/layout-requirement-reject.yaml')
390 self.sched.reconfigure(self.config)
391 self.registerJobs()
392
393 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
394 self.waitUntilSettled()
395 self.assertEqual(len(self.history), 0)
396
397 # First positive vote should not queue until jenkins has +1'd
398 comment = A.addApproval('VRFY', 1, username='reviewer_a')
399 self.fake_gerrit.addEvent(comment)
400 self.waitUntilSettled()
401 self.assertEqual(len(self.history), 0)
402
403 # Jenkins should put in a +1 which will also queue
404 comment = A.addApproval('VRFY', 1, username='jenkins')
405 self.fake_gerrit.addEvent(comment)
406 self.waitUntilSettled()
407 self.assertEqual(len(self.history), 1)
408 self.assertEqual(self.history[0].name, job)
409
410 # Negative vote should not queue
411 comment = A.addApproval('VRFY', -1, username='reviewer_b')
412 self.fake_gerrit.addEvent(comment)
413 self.waitUntilSettled()
414 self.assertEqual(len(self.history), 1)
415
416 # Future approvals should do nothing
417 comment = A.addApproval('VRFY', 1, username='reviewer_c')
418 self.fake_gerrit.addEvent(comment)
419 self.waitUntilSettled()
420 self.assertEqual(len(self.history), 1)
421
422 # Change/update negative vote should queue
423 comment = A.addApproval('VRFY', 1, username='reviewer_b')
424 self.fake_gerrit.addEvent(comment)
425 self.waitUntilSettled()
426 self.assertEqual(len(self.history), 2)
427 self.assertEqual(self.history[1].name, job)
428
429 # Future approvals should also queue
430 comment = A.addApproval('VRFY', 1, username='reviewer_d')
431 self.fake_gerrit.addEvent(comment)
432 self.waitUntilSettled()
433 self.assertEqual(len(self.history), 3)
434 self.assertEqual(self.history[2].name, job)
435
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100436 @skip("Disabled for early v3 development")
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000437 def test_pipeline_require_reject(self):
438 "Test pipeline requirement: rejections absent"
439 return self._test_require_reject('org/project1', 'project1-pipeline')
440
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100441 @skip("Disabled for early v3 development")
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000442 def test_trigger_require_reject(self):
443 "Test trigger requirement: rejections absent"
444 return self._test_require_reject('org/project2', 'project2-trigger')