blob: a73493fa356a58962ca59fc4f2cdfee1f8ba08e3 [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
Jamie Lennoxb59a73f2016-11-23 14:27:18 +110028class TestRequirementsApprovalNewerThan(ZuulTestCase):
29 """Requirements with a newer-than comment requirement"""
James E. Blair9c17dbf2014-06-23 14:21:58 -070030
Jamie Lennoxb59a73f2016-11-23 14:27:18 +110031 tenant_config_file = 'config/requirements/newer-than/main.yaml'
32
James E. Blair9c17dbf2014-06-23 14:21:58 -070033 def test_pipeline_require_approval_newer_than(self):
34 "Test pipeline requirement: approval newer than"
35 return self._test_require_approval_newer_than('org/project1',
Jamie Lennoxb59a73f2016-11-23 14:27:18 +110036 'project1-job')
James E. Blair9c17dbf2014-06-23 14:21:58 -070037
38 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',
Jamie Lennoxb59a73f2016-11-23 14:27:18 +110041 'project2-job')
James E. Blair9c17dbf2014-06-23 14:21:58 -070042
43 def _test_require_approval_newer_than(self, project, job):
James E. Blair9c17dbf2014-06-23 14:21:58 -070044 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
45 # A comment event that we will keep submitting to trigger
Jamie Lennoxb59a73f2016-11-23 14:27:18 +110046 comment = A.addApproval('code-review', 2, username='nobody')
James E. Blair9c17dbf2014-06-23 14:21:58 -070047 self.fake_gerrit.addEvent(comment)
48 self.waitUntilSettled()
49 # No +1 from Jenkins so should not be enqueued
50 self.assertEqual(len(self.history), 0)
51
52 # Add a too-old +1, should not be enqueued
Jamie Lennoxb59a73f2016-11-23 14:27:18 +110053 A.addApproval('verified', 1, username='jenkins',
Joshua Hesketh642824b2014-07-01 17:54:59 +100054 granted_on=time.time() - 72 * 60 * 60)
James E. Blair9c17dbf2014-06-23 14:21:58 -070055 self.fake_gerrit.addEvent(comment)
56 self.waitUntilSettled()
57 self.assertEqual(len(self.history), 0)
58
59 # Add a recent +1
Jamie Lennoxb59a73f2016-11-23 14:27:18 +110060 self.fake_gerrit.addEvent(A.addApproval('verified', 1,
61 username='jenkins'))
James E. Blair9c17dbf2014-06-23 14:21:58 -070062 self.fake_gerrit.addEvent(comment)
63 self.waitUntilSettled()
64 self.assertEqual(len(self.history), 1)
65 self.assertEqual(self.history[0].name, job)
66
Jamie Lennoxb59a73f2016-11-23 14:27:18 +110067
68class TestRequirements(ZuulTestCase):
69 """Test pipeline and trigger requirements"""
70
71 tenant_config_file = 'config/requirements/main.yaml'
72
Jamie Lennoxff3e0b92016-11-23 10:38:25 +110073 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -070074 def test_pipeline_require_approval_older_than(self):
75 "Test pipeline requirement: approval older than"
76 return self._test_require_approval_older_than('org/project1',
77 'project1-pipeline')
78
Jamie Lennoxff3e0b92016-11-23 10:38:25 +110079 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -070080 def test_trigger_require_approval_older_than(self):
81 "Test trigger requirement: approval older than"
82 return self._test_require_approval_older_than('org/project2',
83 'project2-trigger')
84
85 def _test_require_approval_older_than(self, project, job):
James E. Blairf84026c2015-12-08 16:11:46 -080086 self.updateConfigLayout(
87 'tests/fixtures/layout-requirement-older-than.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -070088 self.sched.reconfigure(self.config)
89 self.registerJobs()
90
91 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
92 # A comment event that we will keep submitting to trigger
93 comment = A.addApproval('CRVW', 2, username='nobody')
94 self.fake_gerrit.addEvent(comment)
95 self.waitUntilSettled()
96 # No +1 from Jenkins so should not be enqueued
97 self.assertEqual(len(self.history), 0)
98
99 # Add a recent +1 which should not be enqueued
100 A.addApproval('VRFY', 1)
101 self.fake_gerrit.addEvent(comment)
102 self.waitUntilSettled()
103 self.assertEqual(len(self.history), 0)
104
105 # Add an old +1 which should be enqueued
Joshua Hesketh642824b2014-07-01 17:54:59 +1000106 A.addApproval('VRFY', 1, username='jenkins',
107 granted_on=time.time() - 72 * 60 * 60)
James E. Blair9c17dbf2014-06-23 14:21:58 -0700108 self.fake_gerrit.addEvent(comment)
109 self.waitUntilSettled()
110 self.assertEqual(len(self.history), 1)
111 self.assertEqual(self.history[0].name, job)
112
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100113 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700114 def test_pipeline_require_approval_username(self):
115 "Test pipeline requirement: approval username"
116 return self._test_require_approval_username('org/project1',
117 'project1-pipeline')
118
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100119 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700120 def test_trigger_require_approval_username(self):
121 "Test trigger requirement: approval username"
122 return self._test_require_approval_username('org/project2',
123 'project2-trigger')
124
125 def _test_require_approval_username(self, project, job):
James E. Blairf84026c2015-12-08 16:11:46 -0800126 self.updateConfigLayout(
127 'tests/fixtures/layout-requirement-username.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700128 self.sched.reconfigure(self.config)
129 self.registerJobs()
130
131 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
132 # A comment event that we will keep submitting to trigger
133 comment = A.addApproval('CRVW', 2, username='nobody')
134 self.fake_gerrit.addEvent(comment)
135 self.waitUntilSettled()
136 # No approval from Jenkins so should not be enqueued
137 self.assertEqual(len(self.history), 0)
138
139 # Add an approval from Jenkins
Joshua Hesketh642824b2014-07-01 17:54:59 +1000140 A.addApproval('VRFY', 1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700141 self.fake_gerrit.addEvent(comment)
142 self.waitUntilSettled()
143 self.assertEqual(len(self.history), 1)
144 self.assertEqual(self.history[0].name, job)
145
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100146 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700147 def test_pipeline_require_approval_email(self):
148 "Test pipeline requirement: approval email"
149 return self._test_require_approval_email('org/project1',
150 'project1-pipeline')
151
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100152 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700153 def test_trigger_require_approval_email(self):
154 "Test trigger requirement: approval email"
155 return self._test_require_approval_email('org/project2',
156 'project2-trigger')
157
158 def _test_require_approval_email(self, project, job):
James E. Blairf84026c2015-12-08 16:11:46 -0800159 self.updateConfigLayout(
160 'tests/fixtures/layout-requirement-email.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700161 self.sched.reconfigure(self.config)
162 self.registerJobs()
163
164 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
165 # A comment event that we will keep submitting to trigger
166 comment = A.addApproval('CRVW', 2, username='nobody')
167 self.fake_gerrit.addEvent(comment)
168 self.waitUntilSettled()
169 # No approval from Jenkins so should not be enqueued
170 self.assertEqual(len(self.history), 0)
171
172 # Add an approval from Jenkins
Joshua Hesketh642824b2014-07-01 17:54:59 +1000173 A.addApproval('VRFY', 1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700174 self.fake_gerrit.addEvent(comment)
175 self.waitUntilSettled()
176 self.assertEqual(len(self.history), 1)
177 self.assertEqual(self.history[0].name, job)
178
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100179 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700180 def test_pipeline_require_approval_vote1(self):
181 "Test pipeline requirement: approval vote with one value"
182 return self._test_require_approval_vote1('org/project1',
183 'project1-pipeline')
184
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100185 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700186 def test_trigger_require_approval_vote1(self):
187 "Test trigger requirement: approval vote with one value"
188 return self._test_require_approval_vote1('org/project2',
189 'project2-trigger')
190
191 def _test_require_approval_vote1(self, project, job):
James E. Blairf84026c2015-12-08 16:11:46 -0800192 self.updateConfigLayout(
193 'tests/fixtures/layout-requirement-vote1.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700194 self.sched.reconfigure(self.config)
195 self.registerJobs()
196
197 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
198 # A comment event that we will keep submitting to trigger
199 comment = A.addApproval('CRVW', 2, username='nobody')
200 self.fake_gerrit.addEvent(comment)
201 self.waitUntilSettled()
202 # No approval from Jenkins so should not be enqueued
203 self.assertEqual(len(self.history), 0)
204
205 # A -1 from jenkins should not cause it to be enqueued
Joshua Hesketh642824b2014-07-01 17:54:59 +1000206 A.addApproval('VRFY', -1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700207 self.fake_gerrit.addEvent(comment)
208 self.waitUntilSettled()
209 self.assertEqual(len(self.history), 0)
210
211 # A +1 should allow it to be enqueued
Joshua Hesketh642824b2014-07-01 17:54:59 +1000212 A.addApproval('VRFY', 1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700213 self.fake_gerrit.addEvent(comment)
214 self.waitUntilSettled()
215 self.assertEqual(len(self.history), 1)
216 self.assertEqual(self.history[0].name, job)
217
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100218 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700219 def test_pipeline_require_approval_vote2(self):
220 "Test pipeline requirement: approval vote with two values"
221 return self._test_require_approval_vote2('org/project1',
222 'project1-pipeline')
223
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100224 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700225 def test_trigger_require_approval_vote2(self):
226 "Test trigger requirement: approval vote with two values"
227 return self._test_require_approval_vote2('org/project2',
228 'project2-trigger')
229
230 def _test_require_approval_vote2(self, project, job):
James E. Blairf84026c2015-12-08 16:11:46 -0800231 self.updateConfigLayout(
232 'tests/fixtures/layout-requirement-vote2.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700233 self.sched.reconfigure(self.config)
234 self.registerJobs()
235
236 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
237 # A comment event that we will keep submitting to trigger
238 comment = A.addApproval('CRVW', 2, username='nobody')
239 self.fake_gerrit.addEvent(comment)
240 self.waitUntilSettled()
241 # No approval from Jenkins so should not be enqueued
242 self.assertEqual(len(self.history), 0)
243
244 # A -1 from jenkins should not cause it to be enqueued
Joshua Hesketh642824b2014-07-01 17:54:59 +1000245 A.addApproval('VRFY', -1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700246 self.fake_gerrit.addEvent(comment)
247 self.waitUntilSettled()
248 self.assertEqual(len(self.history), 0)
249
250 # A -2 from jenkins should not cause it to be enqueued
Joshua Hesketh642824b2014-07-01 17:54:59 +1000251 A.addApproval('VRFY', -2, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700252 self.fake_gerrit.addEvent(comment)
253 self.waitUntilSettled()
254 self.assertEqual(len(self.history), 0)
255
Joshua Hesketh642824b2014-07-01 17:54:59 +1000256 # A +1 from jenkins should allow it to be enqueued
257 A.addApproval('VRFY', 1, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700258 self.fake_gerrit.addEvent(comment)
259 self.waitUntilSettled()
260 self.assertEqual(len(self.history), 1)
261 self.assertEqual(self.history[0].name, job)
262
263 # A +2 should allow it to be enqueued
264 B = self.fake_gerrit.addFakeChange(project, 'master', 'B')
265 # A comment event that we will keep submitting to trigger
266 comment = B.addApproval('CRVW', 2, username='nobody')
267 self.fake_gerrit.addEvent(comment)
268 self.waitUntilSettled()
269 self.assertEqual(len(self.history), 1)
270
Joshua Hesketh642824b2014-07-01 17:54:59 +1000271 B.addApproval('VRFY', 2, username='jenkins')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700272 self.fake_gerrit.addEvent(comment)
273 self.waitUntilSettled()
274 self.assertEqual(len(self.history), 2)
275 self.assertEqual(self.history[1].name, job)
276
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100277 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700278 def test_pipeline_require_current_patchset(self):
279 "Test pipeline requirement: current-patchset"
James E. Blairf84026c2015-12-08 16:11:46 -0800280 self.updateConfigLayout(
281 'tests/fixtures/layout-requirement-current-patchset.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700282 self.sched.reconfigure(self.config)
283 self.registerJobs()
284 # Create two patchsets and let their tests settle out. Then
285 # comment on first patchset and check that no additional
286 # jobs are run.
287 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
288 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1))
289 self.waitUntilSettled()
290 A.addPatchset()
291 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1))
292 self.waitUntilSettled()
293
294 self.assertEqual(len(self.history), 2) # one job for each ps
295 self.fake_gerrit.addEvent(A.getChangeCommentEvent(1))
296 self.waitUntilSettled()
297
298 # Assert no new jobs ran after event for old patchset.
299 self.assertEqual(len(self.history), 2)
300
301 # Make sure the same event on a new PS will trigger
302 self.fake_gerrit.addEvent(A.getChangeCommentEvent(2))
303 self.waitUntilSettled()
304 self.assertEqual(len(self.history), 3)
305
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100306 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700307 def test_pipeline_require_open(self):
308 "Test pipeline requirement: open"
James E. Blairf84026c2015-12-08 16:11:46 -0800309 self.updateConfigLayout(
310 'tests/fixtures/layout-requirement-open.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700311 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)
324
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100325 @skip("Disabled for early v3 development")
James E. Blair9c17dbf2014-06-23 14:21:58 -0700326 def test_pipeline_require_status(self):
327 "Test pipeline requirement: status"
James E. Blairf84026c2015-12-08 16:11:46 -0800328 self.updateConfigLayout(
329 'tests/fixtures/layout-requirement-status.yaml')
James E. Blair9c17dbf2014-06-23 14:21:58 -0700330 self.sched.reconfigure(self.config)
331 self.registerJobs()
332
333 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
334 status='MERGED')
335 self.fake_gerrit.addEvent(A.addApproval('CRVW', 2))
336 self.waitUntilSettled()
337 self.assertEqual(len(self.history), 0)
338
339 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
340 self.fake_gerrit.addEvent(B.addApproval('CRVW', 2))
341 self.waitUntilSettled()
342 self.assertEqual(len(self.history), 1)
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000343
344 def _test_require_reject_username(self, project, job):
345 "Test negative username's match"
346 # Should only trigger if Jenkins hasn't voted.
James E. Blairf84026c2015-12-08 16:11:46 -0800347 self.updateConfigLayout(
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000348 'tests/fixtures/layout-requirement-reject-username.yaml')
349 self.sched.reconfigure(self.config)
350 self.registerJobs()
351
352 # add in a change with no comments
353 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
354 self.waitUntilSettled()
355 self.assertEqual(len(self.history), 0)
356
357 # add in a comment that will trigger
358 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1,
359 username='reviewer'))
360 self.waitUntilSettled()
361 self.assertEqual(len(self.history), 1)
362 self.assertEqual(self.history[0].name, job)
363
364 # add in a comment from jenkins user which shouldn't trigger
365 self.fake_gerrit.addEvent(A.addApproval('VRFY', 1, username='jenkins'))
366 self.waitUntilSettled()
367 self.assertEqual(len(self.history), 1)
368
369 # Check future reviews also won't trigger as a 'jenkins' user has
370 # commented previously
371 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1,
372 username='reviewer'))
373 self.waitUntilSettled()
374 self.assertEqual(len(self.history), 1)
375
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100376 @skip("Disabled for early v3 development")
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000377 def test_pipeline_reject_username(self):
378 "Test negative pipeline requirement: no comment from jenkins"
379 return self._test_require_reject_username('org/project1',
380 'project1-pipeline')
381
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100382 @skip("Disabled for early v3 development")
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000383 def test_trigger_reject_username(self):
384 "Test negative trigger requirement: no comment from jenkins"
385 return self._test_require_reject_username('org/project2',
386 'project2-trigger')
387
388 def _test_require_reject(self, project, job):
389 "Test no approval matches a reject param"
James E. Blairf84026c2015-12-08 16:11:46 -0800390 self.updateConfigLayout(
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000391 'tests/fixtures/layout-requirement-reject.yaml')
392 self.sched.reconfigure(self.config)
393 self.registerJobs()
394
395 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
396 self.waitUntilSettled()
397 self.assertEqual(len(self.history), 0)
398
399 # First positive vote should not queue until jenkins has +1'd
400 comment = A.addApproval('VRFY', 1, username='reviewer_a')
401 self.fake_gerrit.addEvent(comment)
402 self.waitUntilSettled()
403 self.assertEqual(len(self.history), 0)
404
405 # Jenkins should put in a +1 which will also queue
406 comment = A.addApproval('VRFY', 1, username='jenkins')
407 self.fake_gerrit.addEvent(comment)
408 self.waitUntilSettled()
409 self.assertEqual(len(self.history), 1)
410 self.assertEqual(self.history[0].name, job)
411
412 # Negative vote should not queue
413 comment = A.addApproval('VRFY', -1, username='reviewer_b')
414 self.fake_gerrit.addEvent(comment)
415 self.waitUntilSettled()
416 self.assertEqual(len(self.history), 1)
417
418 # Future approvals should do nothing
419 comment = A.addApproval('VRFY', 1, username='reviewer_c')
420 self.fake_gerrit.addEvent(comment)
421 self.waitUntilSettled()
422 self.assertEqual(len(self.history), 1)
423
424 # Change/update negative vote should queue
425 comment = A.addApproval('VRFY', 1, username='reviewer_b')
426 self.fake_gerrit.addEvent(comment)
427 self.waitUntilSettled()
428 self.assertEqual(len(self.history), 2)
429 self.assertEqual(self.history[1].name, job)
430
431 # Future approvals should also queue
432 comment = A.addApproval('VRFY', 1, username='reviewer_d')
433 self.fake_gerrit.addEvent(comment)
434 self.waitUntilSettled()
435 self.assertEqual(len(self.history), 3)
436 self.assertEqual(self.history[2].name, job)
437
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100438 @skip("Disabled for early v3 development")
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000439 def test_pipeline_require_reject(self):
440 "Test pipeline requirement: rejections absent"
441 return self._test_require_reject('org/project1', 'project1-pipeline')
442
Jamie Lennoxff3e0b92016-11-23 10:38:25 +1100443 @skip("Disabled for early v3 development")
Joshua Hesketh66c8e522014-06-26 15:30:08 +1000444 def test_trigger_require_reject(self):
445 "Test trigger requirement: rejections absent"
446 return self._test_require_reject('org/project2', 'project2-trigger')