blob: 60bcf74ce24285c74fd7ae81af3480c5b734ded2 [file] [log] [blame]
Jesse Keatingd96e5882017-01-19 13:55:50 -08001#!/usr/bin/env python
2# Copyright (c) 2017 IBM Corp.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Adam Gandelmand81dd762017-02-09 15:15:49 -080016import time
17
Jesse Keatingd96e5882017-01-19 13:55:50 -080018from tests.base import ZuulTestCase, simple_layout
19
20
21class TestGithubRequirements(ZuulTestCase):
22 """Test pipeline and trigger requirements"""
23 config_file = 'zuul-github-driver.conf'
24
25 @simple_layout('layouts/requirements-github.yaml', driver='github')
26 def test_pipeline_require_status(self):
27 "Test pipeline requirement: status"
28 A = self.fake_github.openFakePullRequest('org/project1', 'master', 'A')
29 # A comment event that we will keep submitting to trigger
30 comment = A.getCommentAddedEvent('test me')
31 self.fake_github.emitEvent(comment)
32 self.waitUntilSettled()
33 # No status from zuul so should not be enqueued
34 self.assertEqual(len(self.history), 0)
35
36 # An error status should not cause it to be enqueued
37 A.setStatus(A.head_sha, 'error', 'null', 'null', 'check')
38 self.fake_github.emitEvent(comment)
39 self.waitUntilSettled()
40 self.assertEqual(len(self.history), 0)
41
42 # A success status goes in
43 A.setStatus(A.head_sha, 'success', 'null', 'null', 'check')
44 self.fake_github.emitEvent(comment)
45 self.waitUntilSettled()
46 self.assertEqual(len(self.history), 1)
47 self.assertEqual(self.history[0].name, 'project1-pipeline')
Adam Gandelman8c6eeb52017-01-23 16:31:06 -080048
49 @simple_layout('layouts/requirements-github.yaml', driver='github')
50 def test_trigger_require_status(self):
51 "Test trigger requirement: status"
52 A = self.fake_github.openFakePullRequest('org/project2', 'master', 'A')
53
54 # An error status should not cause it to be enqueued
55 A.setStatus(A.head_sha, 'error', 'null', 'null', 'check')
56 self.fake_github.emitEvent(A.getCommitStatusEvent('check',
57 state='error'))
58 self.waitUntilSettled()
59 self.assertEqual(len(self.history), 0)
60
Jesse Keatingae4cd272017-01-30 17:10:44 -080061 # A success status from unknown user should not cause it to be
Adam Gandelman8c6eeb52017-01-23 16:31:06 -080062 # enqueued
63 A.setStatus(A.head_sha, 'success', 'null', 'null', 'check', user='foo')
64 self.fake_github.emitEvent(A.getCommitStatusEvent('check',
65 state='success',
66 user='foo'))
67 self.waitUntilSettled()
68 self.assertEqual(len(self.history), 0)
69
Jesse Keatingae4cd272017-01-30 17:10:44 -080070 # A success status from zuul goes in
Adam Gandelman8c6eeb52017-01-23 16:31:06 -080071 A.setStatus(A.head_sha, 'success', 'null', 'null', 'check')
72 self.fake_github.emitEvent(A.getCommitStatusEvent('check'))
73 self.waitUntilSettled()
74 self.assertEqual(len(self.history), 1)
75 self.assertEqual(self.history[0].name, 'project2-trigger')
76
77 # An error status for a different context should not cause it to be
78 # enqueued
79 A.setStatus(A.head_sha, 'error', 'null', 'null', 'gate')
80 self.fake_github.emitEvent(A.getCommitStatusEvent('gate',
81 state='error'))
82 self.waitUntilSettled()
83 self.assertEqual(len(self.history), 1)
Jesse Keatingae4cd272017-01-30 17:10:44 -080084
85 @simple_layout('layouts/requirements-github.yaml', driver='github')
86 def test_pipeline_require_review_username(self):
87 "Test pipeline requirement: review username"
88
89 A = self.fake_github.openFakePullRequest('org/project3', 'master', 'A')
90 # A comment event that we will keep submitting to trigger
91 comment = A.getCommentAddedEvent('test me')
92 self.fake_github.emitEvent(comment)
93 self.waitUntilSettled()
94 # No approval from derp so should not be enqueued
95 self.assertEqual(len(self.history), 0)
96
97 # Add an approved review from derp
98 A.addReview('derp', 'APPROVED')
99 self.fake_github.emitEvent(comment)
100 self.waitUntilSettled()
101 self.assertEqual(len(self.history), 1)
102 self.assertEqual(self.history[0].name, 'project3-reviewusername')
103
104 @simple_layout('layouts/requirements-github.yaml', driver='github')
105 def test_pipeline_require_review_state(self):
106 "Test pipeline requirement: review state"
107
108 A = self.fake_github.openFakePullRequest('org/project4', 'master', 'A')
109 # Add derp to writers
110 A.writers.append('derp')
111 # A comment event that we will keep submitting to trigger
112 comment = A.getCommentAddedEvent('test me')
113 self.fake_github.emitEvent(comment)
114 self.waitUntilSettled()
115 # No positive review from derp so should not be enqueued
116 self.assertEqual(len(self.history), 0)
117
118 # A negative review from derp should not cause it to be enqueued
119 A.addReview('derp', 'CHANGES_REQUESTED')
120 self.fake_github.emitEvent(comment)
121 self.waitUntilSettled()
122 self.assertEqual(len(self.history), 0)
123
124 # A positive from nobody should not cause it to be enqueued
125 A.addReview('nobody', 'APPROVED')
126 self.fake_github.emitEvent(comment)
127 self.waitUntilSettled()
128 self.assertEqual(len(self.history), 0)
129
130 # A positive review from derp should cause it to be enqueued
131 A.addReview('derp', 'APPROVED')
132 self.fake_github.emitEvent(comment)
133 self.waitUntilSettled()
134 self.assertEqual(len(self.history), 1)
135 self.assertEqual(self.history[0].name, 'project4-reviewreq')
136
137 @simple_layout('layouts/requirements-github.yaml', driver='github')
138 def test_pipeline_require_review_user_state(self):
139 "Test pipeline requirement: review state from user"
140
141 A = self.fake_github.openFakePullRequest('org/project5', 'master', 'A')
142 # Add derp and herp to writers
143 A.writers.extend(('derp', 'herp'))
144 # A comment event that we will keep submitting to trigger
145 comment = A.getCommentAddedEvent('test me')
146 self.fake_github.emitEvent(comment)
147 self.waitUntilSettled()
148 # No positive review from derp so should not be enqueued
149 self.assertEqual(len(self.history), 0)
150
151 # A negative review from derp should not cause it to be enqueued
152 A.addReview('derp', 'CHANGES_REQUESTED')
153 self.fake_github.emitEvent(comment)
154 self.waitUntilSettled()
155 self.assertEqual(len(self.history), 0)
156
157 # A positive from nobody should not cause it to be enqueued
158 A.addReview('nobody', 'APPROVED')
159 self.fake_github.emitEvent(comment)
160 self.waitUntilSettled()
161 self.assertEqual(len(self.history), 0)
162
163 # A positive review from herp (a writer) should not cause it to be
164 # enqueued
165 A.addReview('herp', 'APPROVED')
166 self.fake_github.emitEvent(comment)
167 self.waitUntilSettled()
168 self.assertEqual(len(self.history), 0)
169
170 # A positive review from derp should cause it to be enqueued
171 A.addReview('derp', 'APPROVED')
172 self.fake_github.emitEvent(comment)
173 self.waitUntilSettled()
174 self.assertEqual(len(self.history), 1)
175 self.assertEqual(self.history[0].name, 'project5-reviewuserstate')
Adam Gandelmand81dd762017-02-09 15:15:49 -0800176
177# TODO: Implement reject on approval username/state
178
179 @simple_layout('layouts/requirements-github.yaml', driver='github')
180 def test_pipeline_require_review_latest_user_state(self):
181 "Test pipeline requirement: review state from user"
182
183 A = self.fake_github.openFakePullRequest('org/project5', 'master', 'A')
184 # Add derp and herp to writers
185 A.writers.extend(('derp', 'herp'))
186 # A comment event that we will keep submitting to trigger
187 comment = A.getCommentAddedEvent('test me')
188 self.fake_github.emitEvent(comment)
189 self.waitUntilSettled()
190 # No positive review from derp so should not be enqueued
191 self.assertEqual(len(self.history), 0)
192
193 # The first negative review from derp should not cause it to be
194 # enqueued
195 for i in range(1, 4):
196 submitted_at = time.time() - 72 * 60 * 60
197 A.addReview('derp', 'CHANGES_REQUESTED',
198 submitted_at)
199 self.fake_github.emitEvent(comment)
200 self.waitUntilSettled()
201 self.assertEqual(len(self.history), 0)
202
203 # A positive review from derp should cause it to be enqueued
204 A.addReview('derp', 'APPROVED')
205 self.fake_github.emitEvent(comment)
206 self.waitUntilSettled()
207 self.assertEqual(len(self.history), 1)
208 self.assertEqual(self.history[0].name, 'project5-reviewuserstate')
209
210 @simple_layout('layouts/requirements-github.yaml', driver='github')
211 def test_require_review_newer_than(self):
212
213 A = self.fake_github.openFakePullRequest('org/project6', 'master', 'A')
214 # Add derp and herp to writers
215 A.writers.extend(('derp', 'herp'))
216 # A comment event that we will keep submitting to trigger
217 comment = A.getCommentAddedEvent('test me')
218 self.fake_github.emitEvent(comment)
219 self.waitUntilSettled()
220 # No positive review from derp so should not be enqueued
221 self.assertEqual(len(self.history), 0)
222
223 # Add a too-old positive review, should not be enqueued
224 submitted_at = time.time() - 72 * 60 * 60
225 A.addReview('derp', 'APPROVED',
226 submitted_at)
227 self.fake_github.emitEvent(comment)
228 self.waitUntilSettled()
229 self.assertEqual(len(self.history), 0)
230
231 # Add a recent positive review
232 submitted_at = time.time() - 12 * 60 * 60
233 A.addReview('derp', 'APPROVED', submitted_at)
234 self.fake_github.emitEvent(comment)
235 self.waitUntilSettled()
236 self.assertEqual(len(self.history), 1)
237 self.assertEqual(self.history[0].name, 'project6-newerthan')
238
239 @simple_layout('layouts/requirements-github.yaml', driver='github')
240 def test_require_review_older_than(self):
241
242 A = self.fake_github.openFakePullRequest('org/project7', 'master', 'A')
243 # Add derp and herp to writers
244 A.writers.extend(('derp', 'herp'))
245 # A comment event that we will keep submitting to trigger
246 comment = A.getCommentAddedEvent('test me')
247 self.fake_github.emitEvent(comment)
248 self.waitUntilSettled()
249 # No positive review from derp so should not be enqueued
250 self.assertEqual(len(self.history), 0)
251
252 # Add a too-new positive, should not be enqueued
253 submitted_at = time.time() - 12 * 60 * 60
254 A.addReview('derp', 'APPROVED',
255 submitted_at)
256 self.fake_github.emitEvent(comment)
257 self.waitUntilSettled()
258 self.assertEqual(len(self.history), 0)
259
260 # Add an old enough positive, should enqueue
261 submitted_at = time.time() - 72 * 60 * 60
262 A.addReview('herp', 'APPROVED', submitted_at)
263 self.fake_github.emitEvent(comment)
264 self.waitUntilSettled()
265 self.assertEqual(len(self.history), 1)
266 self.assertEqual(self.history[0].name, 'project7-olderthan')