blob: 100e4ecce1c8da7b298601933cef34aaea90cc8a [file] [log] [blame]
Antoine Musso45dd2cb2014-01-29 17:17:43 +01001#!/usr/bin/env python
2
3# Copyright 2012 Hewlett-Packard Development Company, L.P.
4# Copyright 2014 Wikimedia Foundation Inc.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
18import logging
James E. Blair217b10d2015-01-08 16:25:28 -080019import time
Antoine Musso45dd2cb2014-01-29 17:17:43 +010020
James E. Blaird8af5422017-05-24 13:59:40 -070021from tests.base import ZuulTestCase, simple_layout
Antoine Musso45dd2cb2014-01-29 17:17:43 +010022
Antoine Musso45dd2cb2014-01-29 17:17:43 +010023
James E. Blairb3b5b382017-06-02 11:29:57 -070024class TestExecutorRepos(ZuulTestCase):
James E. Blaird8af5422017-05-24 13:59:40 -070025 tenant_config_file = 'config/single-tenant/main.yaml'
Antoine Musso45dd2cb2014-01-29 17:17:43 +010026
James E. Blairb3b5b382017-06-02 11:29:57 -070027 log = logging.getLogger("zuul.test.executor")
Antoine Musso45dd2cb2014-01-29 17:17:43 +010028
James E. Blairaf3d01e2017-05-26 14:30:18 -070029 def assertRepoState(self, repo, state, project, build, number):
James E. Blairbcaa2d42017-05-26 15:44:23 -070030 if 'branch' in state:
31 self.assertFalse(repo.head.is_detached,
32 'Project %s commit for build %s #%s should '
33 'not have a detached HEAD' % (
34 project, build, number))
35 self.assertEquals(repo.active_branch.name,
36 state['branch'],
37 'Project %s commit for build %s #%s should '
38 'be on the correct branch' % (
39 project, build, number))
40 if 'commit' in state:
41 self.assertEquals(state['commit'],
James E. Blairaf3d01e2017-05-26 14:30:18 -070042 str(repo.commit('HEAD')),
43 'Project %s commit for build %s #%s should '
44 'be correct' % (
45 project, build, number))
James E. Blairbcaa2d42017-05-26 15:44:23 -070046 ref = repo.commit('HEAD')
47 repo_messages = set(
48 [c.message.strip() for c in repo.iter_commits(ref)])
49 if 'present' in state:
50 for change in state['present']:
James E. Blairaf3d01e2017-05-26 14:30:18 -070051 msg = '%s-1' % change.subject
52 self.assertTrue(msg in repo_messages,
53 'Project %s for build %s #%s should '
54 'have change %s' % (
55 project, build, number, change.subject))
James E. Blairbcaa2d42017-05-26 15:44:23 -070056 if 'absent' in state:
57 for change in state['absent']:
James E. Blairaf3d01e2017-05-26 14:30:18 -070058 msg = '%s-1' % change.subject
59 self.assertTrue(msg not in repo_messages,
60 'Project %s for build %s #%s should '
61 'not have change %s' % (
62 project, build, number, change.subject))
63
James E. Blaird8af5422017-05-24 13:59:40 -070064 @simple_layout('layouts/repo-checkout-two-project.yaml')
James E. Blair97d902e2014-08-21 13:25:56 -070065 def test_one_branch(self):
James E. Blaird8af5422017-05-24 13:59:40 -070066 self.executor_server.hold_jobs_in_build = True
Antoine Musso45dd2cb2014-01-29 17:17:43 +010067
James E. Blaird8af5422017-05-24 13:59:40 -070068 p1 = 'review.example.com/org/project1'
69 p2 = 'review.example.com/org/project2'
70 projects = [p1, p2]
Antoine Musso45dd2cb2014-01-29 17:17:43 +010071 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
72 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
James E. Blaird8af5422017-05-24 13:59:40 -070073 A.addApproval('code-review', 2)
74 B.addApproval('code-review', 2)
75 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
76 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
Antoine Musso45dd2cb2014-01-29 17:17:43 +010077
78 self.waitUntilSettled()
79
80 self.assertEquals(2, len(self.builds), "Two builds are running")
81
James E. Blair97d902e2014-08-21 13:25:56 -070082 upstream = self.getUpstreamRepos(projects)
83 states = [
James E. Blairbcaa2d42017-05-26 15:44:23 -070084 {p1: dict(present=[A], absent=[B], branch='master'),
85 p2: dict(commit=str(upstream[p2].commit('master')),
86 branch='master'),
James E. Blair97d902e2014-08-21 13:25:56 -070087 },
James E. Blairbcaa2d42017-05-26 15:44:23 -070088 {p1: dict(present=[A], absent=[B], branch='master'),
89 p2: dict(present=[B], absent=[A], branch='master'),
James E. Blair97d902e2014-08-21 13:25:56 -070090 },
Joshua Hesketh29d99b72014-08-19 16:27:42 +100091 ]
James E. Blair97d902e2014-08-21 13:25:56 -070092
93 for number, build in enumerate(self.builds):
Antoine Musso45dd2cb2014-01-29 17:17:43 +010094 self.log.debug("Build parameters: %s", build.parameters)
James E. Blaird8af5422017-05-24 13:59:40 -070095 work = build.getWorkspaceRepos(projects)
James E. Blair97d902e2014-08-21 13:25:56 -070096 state = states[number]
97
98 for project in projects:
James E. Blairaf3d01e2017-05-26 14:30:18 -070099 self.assertRepoState(work[project], state[project],
100 project, build, number)
James E. Blair97d902e2014-08-21 13:25:56 -0700101
James E. Blaird8af5422017-05-24 13:59:40 -0700102 self.executor_server.hold_jobs_in_build = False
103 self.executor_server.release()
James E. Blair97d902e2014-08-21 13:25:56 -0700104 self.waitUntilSettled()
105
James E. Blairaf3d01e2017-05-26 14:30:18 -0700106 @simple_layout('layouts/repo-checkout-four-project.yaml')
James E. Blair97d902e2014-08-21 13:25:56 -0700107 def test_multi_branch(self):
James E. Blairaf3d01e2017-05-26 14:30:18 -0700108 self.executor_server.hold_jobs_in_build = True
109
110 p1 = 'review.example.com/org/project1'
111 p2 = 'review.example.com/org/project2'
112 p3 = 'review.example.com/org/project3'
113 p4 = 'review.example.com/org/project4'
114 projects = [p1, p2, p3, p4]
James E. Blair97d902e2014-08-21 13:25:56 -0700115
116 self.create_branch('org/project2', 'stable/havana')
117 self.create_branch('org/project4', 'stable/havana')
118 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
Joshua Hesketh29d99b72014-08-19 16:27:42 +1000119 B = self.fake_gerrit.addFakeChange('org/project2', 'stable/havana',
120 'B')
James E. Blair97d902e2014-08-21 13:25:56 -0700121 C = self.fake_gerrit.addFakeChange('org/project3', 'master', 'C')
James E. Blairaf3d01e2017-05-26 14:30:18 -0700122 A.addApproval('code-review', 2)
123 B.addApproval('code-review', 2)
124 C.addApproval('code-review', 2)
125 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
126 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
127 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair97d902e2014-08-21 13:25:56 -0700128
129 self.waitUntilSettled()
130
131 self.assertEquals(3, len(self.builds), "Three builds are running")
132
133 upstream = self.getUpstreamRepos(projects)
134 states = [
James E. Blairbcaa2d42017-05-26 15:44:23 -0700135 {p1: dict(present=[A], absent=[B, C], branch='master'),
136 p2: dict(commit=str(upstream[p2].commit('master')),
137 branch='master'),
138 p3: dict(commit=str(upstream[p3].commit('master')),
139 branch='master'),
140 p4: dict(commit=str(upstream[p4].commit('master')),
141 branch='master'),
James E. Blair97d902e2014-08-21 13:25:56 -0700142 },
James E. Blairbcaa2d42017-05-26 15:44:23 -0700143 {p1: dict(present=[A], absent=[B, C], branch='master'),
144 p2: dict(present=[B], absent=[A, C], branch='stable/havana'),
145 p3: dict(commit=str(upstream[p3].commit('master')),
146 branch='master'),
147 p4: dict(commit=str(upstream[p4].commit('stable/havana')),
148 branch='stable/havana'),
James E. Blair97d902e2014-08-21 13:25:56 -0700149 },
James E. Blairbcaa2d42017-05-26 15:44:23 -0700150 {p1: dict(present=[A], absent=[B, C], branch='master'),
151 p2: dict(commit=str(upstream[p2].commit('master')),
152 branch='master'),
153 p3: dict(present=[C], absent=[A, B], branch='master'),
154 p4: dict(commit=str(upstream[p4].commit('master')),
155 branch='master'),
James E. Blair97d902e2014-08-21 13:25:56 -0700156 },
Joshua Hesketh29d99b72014-08-19 16:27:42 +1000157 ]
James E. Blair97d902e2014-08-21 13:25:56 -0700158
159 for number, build in enumerate(self.builds):
160 self.log.debug("Build parameters: %s", build.parameters)
James E. Blairaf3d01e2017-05-26 14:30:18 -0700161 work = build.getWorkspaceRepos(projects)
James E. Blair97d902e2014-08-21 13:25:56 -0700162 state = states[number]
163
164 for project in projects:
James E. Blairaf3d01e2017-05-26 14:30:18 -0700165 self.assertRepoState(work[project], state[project],
166 project, build, number)
James E. Blair82318922014-08-21 11:05:32 -0700167
James E. Blairaf3d01e2017-05-26 14:30:18 -0700168 self.executor_server.hold_jobs_in_build = False
169 self.executor_server.release()
James E. Blair82318922014-08-21 11:05:32 -0700170 self.waitUntilSettled()
James E. Blairbce35e12014-08-21 14:31:17 -0700171
James E. Blair4de8d9e2017-06-01 15:41:40 -0700172 @simple_layout('layouts/repo-checkout-six-project.yaml')
James E. Blairf0420222014-08-21 16:02:17 -0700173 def test_project_override(self):
James E. Blair4de8d9e2017-06-01 15:41:40 -0700174 self.executor_server.hold_jobs_in_build = True
175
176 p1 = 'review.example.com/org/project1'
177 p2 = 'review.example.com/org/project2'
178 p3 = 'review.example.com/org/project3'
179 p4 = 'review.example.com/org/project4'
180 p5 = 'review.example.com/org/project5'
181 p6 = 'review.example.com/org/project6'
182 projects = [p1, p2, p3, p4, p5, p6]
James E. Blairf0420222014-08-21 16:02:17 -0700183
184 self.create_branch('org/project3', 'stable/havana')
185 self.create_branch('org/project4', 'stable/havana')
186 self.create_branch('org/project6', 'stable/havana')
187 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
188 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
189 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
Joshua Hesketh29d99b72014-08-19 16:27:42 +1000190 D = self.fake_gerrit.addFakeChange('org/project3', 'stable/havana',
191 'D')
James E. Blair4de8d9e2017-06-01 15:41:40 -0700192 A.addApproval('code-review', 2)
193 B.addApproval('code-review', 2)
194 C.addApproval('code-review', 2)
195 D.addApproval('code-review', 2)
196 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
197 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
198 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
199 self.fake_gerrit.addEvent(D.addApproval('approved', 1))
James E. Blairf0420222014-08-21 16:02:17 -0700200
201 self.waitUntilSettled()
202
203 self.assertEquals(4, len(self.builds), "Four builds are running")
204
205 upstream = self.getUpstreamRepos(projects)
206 states = [
James E. Blair4de8d9e2017-06-01 15:41:40 -0700207 {p1: dict(present=[A], absent=[B, C, D], branch='master'),
208 p2: dict(commit=str(upstream[p2].commit('master')),
209 branch='master'),
210 p3: dict(commit=str(upstream[p3].commit('master')),
211 branch='master'),
212 p4: dict(commit=str(upstream[p4].commit('master')),
213 branch='master'),
214 p5: dict(commit=str(upstream[p5].commit('master')),
215 branch='master'),
216 p6: dict(commit=str(upstream[p6].commit('master')),
217 branch='master'),
James E. Blairf0420222014-08-21 16:02:17 -0700218 },
James E. Blair4de8d9e2017-06-01 15:41:40 -0700219 {p1: dict(present=[A, B], absent=[C, D], branch='master'),
220 p2: dict(commit=str(upstream[p2].commit('master')),
221 branch='master'),
222 p3: dict(commit=str(upstream[p3].commit('master')),
223 branch='master'),
224 p4: dict(commit=str(upstream[p4].commit('master')),
225 branch='master'),
226 p5: dict(commit=str(upstream[p5].commit('master')),
227 branch='master'),
228 p6: dict(commit=str(upstream[p6].commit('master')),
229 branch='master'),
James E. Blairf0420222014-08-21 16:02:17 -0700230 },
James E. Blair4de8d9e2017-06-01 15:41:40 -0700231 {p1: dict(present=[A, B], absent=[C, D], branch='master'),
232 p2: dict(present=[C], absent=[A, B, D], branch='master'),
233 p3: dict(commit=str(upstream[p3].commit('master')),
234 branch='master'),
235 p4: dict(commit=str(upstream[p4].commit('master')),
236 branch='master'),
237 p5: dict(commit=str(upstream[p5].commit('master')),
238 branch='master'),
239 p6: dict(commit=str(upstream[p6].commit('master')),
240 branch='master'),
James E. Blairf0420222014-08-21 16:02:17 -0700241 },
James E. Blair4de8d9e2017-06-01 15:41:40 -0700242 {p1: dict(present=[A, B], absent=[C, D], branch='master'),
243 p2: dict(present=[C], absent=[A, B, D], branch='master'),
244 p3: dict(present=[D], absent=[A, B, C],
245 branch='stable/havana'),
246 p4: dict(commit=str(upstream[p4].commit('master')),
247 branch='master'),
248 p5: dict(commit=str(upstream[p5].commit('master')),
249 branch='master'),
250 p6: dict(commit=str(upstream[p6].commit('stable/havana')),
251 branch='stable/havana'),
James E. Blairf0420222014-08-21 16:02:17 -0700252 },
Joshua Hesketh29d99b72014-08-19 16:27:42 +1000253 ]
James E. Blairf0420222014-08-21 16:02:17 -0700254
255 for number, build in enumerate(self.builds):
256 self.log.debug("Build parameters: %s", build.parameters)
James E. Blair4de8d9e2017-06-01 15:41:40 -0700257 work = build.getWorkspaceRepos(projects)
James E. Blairf0420222014-08-21 16:02:17 -0700258 state = states[number]
259
260 for project in projects:
James E. Blair4de8d9e2017-06-01 15:41:40 -0700261 self.assertRepoState(work[project], state[project],
262 project, build, number)
James E. Blairf0420222014-08-21 16:02:17 -0700263
James E. Blair4de8d9e2017-06-01 15:41:40 -0700264 self.executor_server.hold_jobs_in_build = False
265 self.executor_server.release()
James E. Blairf0420222014-08-21 16:02:17 -0700266 self.waitUntilSettled()
James E. Blair217b10d2015-01-08 16:25:28 -0800267
268 def test_periodic(self):
James E. Blair95ae4fc2017-06-01 15:54:53 -0700269 # This test can not use simple_layout because it must start
270 # with a configuration which does not include a
271 # timer-triggered job so that we have an opportunity to set
272 # the hold flag before the first job.
273 self.executor_server.hold_jobs_in_build = True
274 # Start timer trigger - also org/project
275 self.commitConfigUpdate('common-config',
276 'layouts/repo-checkout-timer.yaml')
James E. Blair217b10d2015-01-08 16:25:28 -0800277 self.sched.reconfigure(self.config)
James E. Blair95ae4fc2017-06-01 15:54:53 -0700278
279 p1 = 'review.example.com/org/project1'
280 projects = [p1]
281 self.create_branch('org/project1', 'stable/havana')
James E. Blair217b10d2015-01-08 16:25:28 -0800282
283 # The pipeline triggers every second, so we should have seen
284 # several by now.
285 time.sleep(5)
286 self.waitUntilSettled()
287
James E. Blair217b10d2015-01-08 16:25:28 -0800288 # Stop queuing timer triggered jobs so that the assertions
289 # below don't race against more jobs being queued.
James E. Blair95ae4fc2017-06-01 15:54:53 -0700290 self.commitConfigUpdate('common-config',
291 'layouts/repo-checkout-no-timer.yaml')
James E. Blair217b10d2015-01-08 16:25:28 -0800292 self.sched.reconfigure(self.config)
James E. Blair217b10d2015-01-08 16:25:28 -0800293
James E. Blair95ae4fc2017-06-01 15:54:53 -0700294 self.assertEquals(1, len(self.builds), "One build is running")
James E. Blair217b10d2015-01-08 16:25:28 -0800295
296 upstream = self.getUpstreamRepos(projects)
297 states = [
James E. Blair95ae4fc2017-06-01 15:54:53 -0700298 {p1: dict(commit=str(upstream[p1].commit('stable/havana')),
299 branch='stable/havana'),
James E. Blair217b10d2015-01-08 16:25:28 -0800300 },
Joshua Hesketh29d99b72014-08-19 16:27:42 +1000301 ]
James E. Blair217b10d2015-01-08 16:25:28 -0800302
James E. Blair95ae4fc2017-06-01 15:54:53 -0700303 for number, build in enumerate(self.builds):
James E. Blair217b10d2015-01-08 16:25:28 -0800304 self.log.debug("Build parameters: %s", build.parameters)
James E. Blair95ae4fc2017-06-01 15:54:53 -0700305 work = build.getWorkspaceRepos(projects)
James E. Blair217b10d2015-01-08 16:25:28 -0800306 state = states[number]
307
308 for project in projects:
James E. Blair95ae4fc2017-06-01 15:54:53 -0700309 self.assertRepoState(work[project], state[project],
310 project, build, number)
James E. Blair217b10d2015-01-08 16:25:28 -0800311
James E. Blair95ae4fc2017-06-01 15:54:53 -0700312 self.executor_server.hold_jobs_in_build = False
313 self.executor_server.release()
James E. Blair217b10d2015-01-08 16:25:28 -0800314 self.waitUntilSettled()
Sachi King9f16d522016-03-16 12:20:45 +1100315
James E. Blairbbe811e2017-06-02 10:47:44 -0700316 @simple_layout('layouts/repo-checkout-post.yaml')
Sachi King9f16d522016-03-16 12:20:45 +1100317 def test_post_and_master_checkout(self):
James E. Blair1de2e492017-06-02 11:04:42 -0700318 self.executor_server.hold_jobs_in_build = True
319 p1 = "review.example.com/org/project1"
320 p2 = "review.example.com/org/project2"
321 projects = [p1, p2]
James E. Blair8cce42e2016-10-18 08:18:36 -0700322
James E. Blair1de2e492017-06-02 11:04:42 -0700323 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
James E. Blair8cce42e2016-10-18 08:18:36 -0700324 event = A.getRefUpdatedEvent()
325 A.setMerged()
326 self.fake_gerrit.addEvent(event)
327 self.waitUntilSettled()
328
James E. Blair8cce42e2016-10-18 08:18:36 -0700329 upstream = self.getUpstreamRepos(projects)
James E. Blair1de2e492017-06-02 11:04:42 -0700330 states = [
331 {p1: dict(commit=str(upstream[p1].commit('master')),
332 present=[A], branch='master'),
333 p2: dict(commit=str(upstream[p2].commit('master')),
334 absent=[A], branch='master'),
335 },
336 ]
James E. Blair8cce42e2016-10-18 08:18:36 -0700337
James E. Blair1de2e492017-06-02 11:04:42 -0700338 for number, build in enumerate(self.builds):
339 self.log.debug("Build parameters: %s", build.parameters)
340 work = build.getWorkspaceRepos(projects)
341 state = states[number]
342
343 for project in projects:
344 self.assertRepoState(work[project], state[project],
345 project, build, number)
346
347 self.executor_server.hold_jobs_in_build = False
348 self.executor_server.release()
James E. Blair8cce42e2016-10-18 08:18:36 -0700349 self.waitUntilSettled()