blob: ab2683d814fd16300a4e9d5b6dd4fdfda0d2ad85 [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
19import os
20import shutil
21
22import git
23
24import zuul.lib.cloner
25
26from tests.base import ZuulTestCase
27from tests.base import FIXTURE_DIR
28
29logging.basicConfig(level=logging.DEBUG,
30 format='%(asctime)s %(name)-32s '
31 '%(levelname)-8s %(message)s')
32
33
34class TestCloner(ZuulTestCase):
35
36 log = logging.getLogger("zuul.test.cloner")
37 workspace_root = None
38
39 def setUp(self):
40 super(TestCloner, self).setUp()
41 self.workspace_root = os.path.join(self.test_root, 'workspace')
42
43 self.config.set('zuul', 'layout_config',
James E. Blair97d902e2014-08-21 13:25:56 -070044 'tests/fixtures/layout-cloner.yaml')
Antoine Musso45dd2cb2014-01-29 17:17:43 +010045 self.sched.reconfigure(self.config)
46 self.registerJobs()
47
James E. Blair97d902e2014-08-21 13:25:56 -070048 def getWorkspaceRepos(self, projects):
49 repos = {}
50 for project in projects:
51 repos[project] = git.Repo(
52 os.path.join(self.workspace_root, project))
53 return repos
54
55 def getUpstreamRepos(self, projects):
56 repos = {}
57 for project in projects:
58 repos[project] = git.Repo(
59 os.path.join(self.upstream_root, project))
60 return repos
61
James E. Blair48ff4d52014-08-25 15:07:21 -070062 def test_cache_dir(self):
63 projects = ['org/project1', 'org/project2']
64 cache_root = os.path.join(self.test_root, "cache")
65 for project in projects:
66 upstream_repo_path = os.path.join(self.upstream_root, project)
67 cache_repo_path = os.path.join(cache_root, project)
68 git.Repo.clone_from(upstream_repo_path, cache_repo_path)
69
70 self.worker.hold_jobs_in_build = True
71 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
72 A.addApproval('CRVW', 2)
73 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
74
75 self.waitUntilSettled()
76
77 self.assertEquals(1, len(self.builds), "One build is running")
78
79 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
80 B.setMerged()
81
82 upstream = self.getUpstreamRepos(projects)
83 states = [
84 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
85 'org/project2': str(upstream['org/project2'].commit('master')),
86 },
87 ]
88
89 for number, build in enumerate(self.builds):
90 self.log.debug("Build parameters: %s", build.parameters)
91 cloner = zuul.lib.cloner.Cloner(
92 git_base_url=self.upstream_root,
93 projects=projects,
94 workspace=self.workspace_root,
95 zuul_branch=build.parameters['ZUUL_BRANCH'],
96 zuul_ref=build.parameters['ZUUL_REF'],
97 zuul_url=self.git_root,
98 cache_dir=cache_root,
99 )
100 cloner.execute()
101 work = self.getWorkspaceRepos(projects)
102 state = states[number]
103
104 for project in projects:
105 self.assertEquals(state[project],
106 str(work[project].commit('HEAD')),
107 'Project %s commit for build %s should '
108 'be correct' % (project, number))
109
110 work = self.getWorkspaceRepos(projects)
111 upstream_repo_path = os.path.join(self.upstream_root, 'org/project1')
112 self.assertEquals(work['org/project1'].remotes.origin.url,
113 upstream_repo_path,
114 'workspace repo origin should be upstream, not cache')
115
116 self.worker.hold_jobs_in_build = False
117 self.worker.release()
118 self.waitUntilSettled()
119
James E. Blair97d902e2014-08-21 13:25:56 -0700120 def test_one_branch(self):
Antoine Musso45dd2cb2014-01-29 17:17:43 +0100121 self.worker.hold_jobs_in_build = True
122
James E. Blair97d902e2014-08-21 13:25:56 -0700123 projects = ['org/project1', 'org/project2']
Antoine Musso45dd2cb2014-01-29 17:17:43 +0100124 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
125 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
Antoine Musso45dd2cb2014-01-29 17:17:43 +0100126 A.addApproval('CRVW', 2)
127 B.addApproval('CRVW', 2)
128 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
129 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
130
131 self.waitUntilSettled()
132
133 self.assertEquals(2, len(self.builds), "Two builds are running")
134
James E. Blair97d902e2014-08-21 13:25:56 -0700135 upstream = self.getUpstreamRepos(projects)
136 states = [
137 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
138 'org/project2': str(upstream['org/project2'].commit('master')),
139 },
140 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
141 'org/project2': self.builds[1].parameters['ZUUL_COMMIT'],
142 },
143 ]
144
145 for number, build in enumerate(self.builds):
Antoine Musso45dd2cb2014-01-29 17:17:43 +0100146 self.log.debug("Build parameters: %s", build.parameters)
Antoine Musso45dd2cb2014-01-29 17:17:43 +0100147 cloner = zuul.lib.cloner.Cloner(
148 git_base_url=self.upstream_root,
James E. Blair97d902e2014-08-21 13:25:56 -0700149 projects=projects,
Antoine Musso45dd2cb2014-01-29 17:17:43 +0100150 workspace=self.workspace_root,
James E. Blair97d902e2014-08-21 13:25:56 -0700151 zuul_branch=build.parameters['ZUUL_BRANCH'],
James E. Blair82318922014-08-21 11:05:32 -0700152 zuul_ref=build.parameters['ZUUL_REF'],
Antoine Musso45dd2cb2014-01-29 17:17:43 +0100153 zuul_url=self.git_root,
James E. Blair97d902e2014-08-21 13:25:56 -0700154 )
Antoine Musso45dd2cb2014-01-29 17:17:43 +0100155 cloner.execute()
James E. Blair97d902e2014-08-21 13:25:56 -0700156 work = self.getWorkspaceRepos(projects)
157 state = states[number]
158
159 for project in projects:
160 self.assertEquals(state[project],
161 str(work[project].commit('HEAD')),
162 'Project %s commit for build %s should '
163 'be correct' % (project, number))
164
165 shutil.rmtree(self.workspace_root)
166
167 self.worker.hold_jobs_in_build = False
168 self.worker.release()
169 self.waitUntilSettled()
170
171 def test_multi_branch(self):
172 self.worker.hold_jobs_in_build = True
173 projects = ['org/project1', 'org/project2',
174 'org/project3', 'org/project4']
175
176 self.create_branch('org/project2', 'stable/havana')
177 self.create_branch('org/project4', 'stable/havana')
178 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
179 B = self.fake_gerrit.addFakeChange('org/project2', 'stable/havana', 'B')
180 C = self.fake_gerrit.addFakeChange('org/project3', 'master', 'C')
181 A.addApproval('CRVW', 2)
182 B.addApproval('CRVW', 2)
183 C.addApproval('CRVW', 2)
184 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
185 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
186 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
187
188 self.waitUntilSettled()
189
190 self.assertEquals(3, len(self.builds), "Three builds are running")
191
192 upstream = self.getUpstreamRepos(projects)
193 states = [
194 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
195 'org/project2': str(upstream['org/project2'].commit('master')),
196 'org/project3': str(upstream['org/project3'].commit('master')),
197 'org/project4': str(upstream['org/project4'].
198 commit('master')),
199 },
200 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
201 'org/project2': self.builds[1].parameters['ZUUL_COMMIT'],
202 'org/project3': str(upstream['org/project3'].commit('master')),
203 'org/project4': str(upstream['org/project4'].
204 commit('stable/havana')),
205 },
206 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
207 'org/project2': str(upstream['org/project2'].commit('master')),
208 'org/project3': self.builds[2].parameters['ZUUL_COMMIT'],
209 'org/project4': str(upstream['org/project4'].
210 commit('master')),
211 },
212 ]
213
214 for number, build in enumerate(self.builds):
215 self.log.debug("Build parameters: %s", build.parameters)
216 cloner = zuul.lib.cloner.Cloner(
217 git_base_url=self.upstream_root,
218 projects=projects,
219 workspace=self.workspace_root,
220 zuul_branch=build.parameters['ZUUL_BRANCH'],
221 zuul_ref=build.parameters['ZUUL_REF'],
222 zuul_url=self.git_root,
223 )
224 cloner.execute()
225 work = self.getWorkspaceRepos(projects)
226 state = states[number]
227
228 for project in projects:
229 self.assertEquals(state[project],
230 str(work[project].commit('HEAD')),
231 'Project %s commit for build %s should '
232 'be correct' % (project, number))
Antoine Musso45dd2cb2014-01-29 17:17:43 +0100233 shutil.rmtree(self.workspace_root)
James E. Blair82318922014-08-21 11:05:32 -0700234
235 self.worker.hold_jobs_in_build = False
236 self.worker.release()
237 self.waitUntilSettled()
James E. Blairbce35e12014-08-21 14:31:17 -0700238
239 def test_upgrade(self):
240 # Simulates an upgrade test
241 self.worker.hold_jobs_in_build = True
242 projects = ['org/project1', 'org/project2', 'org/project3',
243 'org/project4', 'org/project5', 'org/project6']
244
245 self.create_branch('org/project2', 'stable/havana')
246 self.create_branch('org/project3', 'stable/havana')
247 self.create_branch('org/project4', 'stable/havana')
248 self.create_branch('org/project5', 'stable/havana')
249 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
250 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
251 C = self.fake_gerrit.addFakeChange('org/project3', 'stable/havana', 'C')
252 D = self.fake_gerrit.addFakeChange('org/project3', 'master', 'D')
253 E = self.fake_gerrit.addFakeChange('org/project4', 'stable/havana', 'E')
254 A.addApproval('CRVW', 2)
255 B.addApproval('CRVW', 2)
256 C.addApproval('CRVW', 2)
257 D.addApproval('CRVW', 2)
258 E.addApproval('CRVW', 2)
259 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
260 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
261 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
262 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
263 self.fake_gerrit.addEvent(E.addApproval('APRV', 1))
264
265 self.waitUntilSettled()
266
267 self.assertEquals(5, len(self.builds), "Five builds are running")
268
269 # Check the old side of the upgrade first
270 upstream = self.getUpstreamRepos(projects)
271 states = [
272 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
273 'org/project2': str(upstream['org/project2'].commit('stable/havana')),
274 'org/project3': str(upstream['org/project3'].commit('stable/havana')),
275 'org/project4': str(upstream['org/project4'].commit('stable/havana')),
276 'org/project5': str(upstream['org/project5'].commit('stable/havana')),
277 'org/project6': str(upstream['org/project6'].commit('master')),
278 },
279 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
280 'org/project2': str(upstream['org/project2'].commit('stable/havana')),
281 'org/project3': str(upstream['org/project3'].commit('stable/havana')),
282 'org/project4': str(upstream['org/project4'].commit('stable/havana')),
283 'org/project5': str(upstream['org/project5'].commit('stable/havana')),
284 'org/project6': str(upstream['org/project6'].commit('master')),
285 },
286 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
287 'org/project2': str(upstream['org/project2'].commit('stable/havana')),
288 'org/project3': self.builds[2].parameters['ZUUL_COMMIT'],
289 'org/project4': str(upstream['org/project4'].commit('stable/havana')),
290
291 'org/project5': str(upstream['org/project5'].commit('stable/havana')),
292 'org/project6': str(upstream['org/project6'].commit('master')),
293 },
294 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
295 'org/project2': str(upstream['org/project2'].commit('stable/havana')),
296 'org/project3': self.builds[2].parameters['ZUUL_COMMIT'],
297 'org/project4': str(upstream['org/project4'].commit('stable/havana')),
298 'org/project5': str(upstream['org/project5'].commit('stable/havana')),
299 'org/project6': str(upstream['org/project6'].commit('master')),
300 },
301 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
302 'org/project2': str(upstream['org/project2'].commit('stable/havana')),
303 'org/project3': self.builds[2].parameters['ZUUL_COMMIT'],
304 'org/project4': self.builds[4].parameters['ZUUL_COMMIT'],
305 'org/project5': str(upstream['org/project5'].commit('stable/havana')),
306 'org/project6': str(upstream['org/project6'].commit('master')),
307 },
308 ]
309
310 for number, build in enumerate(self.builds):
311 self.log.debug("Build parameters: %s", build.parameters)
312 change_number = int(build.parameters['ZUUL_CHANGE'])
313 cloner = zuul.lib.cloner.Cloner(
314 git_base_url=self.upstream_root,
315 projects=projects,
316 workspace=self.workspace_root,
317 zuul_branch=build.parameters['ZUUL_BRANCH'],
318 zuul_ref=build.parameters['ZUUL_REF'],
319 zuul_url=self.git_root,
320 branch='stable/havana', # Old branch for upgrade
321 )
322 cloner.execute()
323 work = self.getWorkspaceRepos(projects)
324 state = states[number]
325
326 for project in projects:
327 self.assertEquals(state[project],
328 str(work[project].commit('HEAD')),
329 'Project %s commit for build %s should '
330 'be correct on old side of upgrade' %
331 (project, number))
332 shutil.rmtree(self.workspace_root)
333
334 # Check the new side of the upgrade
335 states = [
336 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
337 'org/project2': str(upstream['org/project2'].commit('master')),
338 'org/project3': str(upstream['org/project3'].commit('master')),
339 'org/project4': str(upstream['org/project4'].commit('master')),
340 'org/project5': str(upstream['org/project5'].commit('master')),
341 'org/project6': str(upstream['org/project6'].commit('master')),
342 },
343 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
344 'org/project2': self.builds[1].parameters['ZUUL_COMMIT'],
345 'org/project3': str(upstream['org/project3'].commit('master')),
346 'org/project4': str(upstream['org/project4'].commit('master')),
347 'org/project5': str(upstream['org/project5'].commit('master')),
348 'org/project6': str(upstream['org/project6'].commit('master')),
349 },
350 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
351 'org/project2': self.builds[1].parameters['ZUUL_COMMIT'],
352 'org/project3': str(upstream['org/project3'].commit('master')),
353 'org/project4': str(upstream['org/project4'].commit('master')),
354 'org/project5': str(upstream['org/project5'].commit('master')),
355 'org/project6': str(upstream['org/project6'].commit('master')),
356 },
357 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
358 'org/project2': self.builds[1].parameters['ZUUL_COMMIT'],
359 'org/project3': self.builds[3].parameters['ZUUL_COMMIT'],
360 'org/project4': str(upstream['org/project4'].commit('master')),
361 'org/project5': str(upstream['org/project5'].commit('master')),
362 'org/project6': str(upstream['org/project6'].commit('master')),
363 },
364 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
365 'org/project2': self.builds[1].parameters['ZUUL_COMMIT'],
366 'org/project3': self.builds[3].parameters['ZUUL_COMMIT'],
367 'org/project4': str(upstream['org/project4'].commit('master')),
368 'org/project5': str(upstream['org/project5'].commit('master')),
369 'org/project6': str(upstream['org/project6'].commit('master')),
370 },
371 ]
372
373 for number, build in enumerate(self.builds):
374 self.log.debug("Build parameters: %s", build.parameters)
375 change_number = int(build.parameters['ZUUL_CHANGE'])
376 cloner = zuul.lib.cloner.Cloner(
377 git_base_url=self.upstream_root,
378 projects=projects,
379 workspace=self.workspace_root,
380 zuul_branch=build.parameters['ZUUL_BRANCH'],
381 zuul_ref=build.parameters['ZUUL_REF'],
382 zuul_url=self.git_root,
383 branch='master', # New branch for upgrade
384 )
385 cloner.execute()
386 work = self.getWorkspaceRepos(projects)
387 state = states[number]
388
389 for project in projects:
390 self.assertEquals(state[project],
391 str(work[project].commit('HEAD')),
392 'Project %s commit for build %s should '
393 'be correct on old side of upgrade' %
394 (project, number))
395 shutil.rmtree(self.workspace_root)
396
397 self.worker.hold_jobs_in_build = False
398 self.worker.release()
399 self.waitUntilSettled()
James E. Blairf0420222014-08-21 16:02:17 -0700400
401 def test_project_override(self):
402 self.worker.hold_jobs_in_build = True
403 projects = ['org/project1', 'org/project2', 'org/project3',
404 'org/project4', 'org/project5', 'org/project6']
405
406 self.create_branch('org/project3', 'stable/havana')
407 self.create_branch('org/project4', 'stable/havana')
408 self.create_branch('org/project6', 'stable/havana')
409 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
410 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
411 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
412 D = self.fake_gerrit.addFakeChange('org/project3', 'stable/havana', 'D')
413 A.addApproval('CRVW', 2)
414 B.addApproval('CRVW', 2)
415 C.addApproval('CRVW', 2)
416 D.addApproval('CRVW', 2)
417 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
418 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
419 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
420 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
421
422 self.waitUntilSettled()
423
424 self.assertEquals(4, len(self.builds), "Four builds are running")
425
426 upstream = self.getUpstreamRepos(projects)
427 states = [
428 {'org/project1': self.builds[0].parameters['ZUUL_COMMIT'],
429 'org/project2': str(upstream['org/project2'].commit('master')),
430 'org/project3': str(upstream['org/project3'].commit('master')),
431 'org/project4': str(upstream['org/project4'].commit('master')),
432 'org/project5': str(upstream['org/project5'].commit('master')),
433 'org/project6': str(upstream['org/project6'].commit('master')),
434 },
435 {'org/project1': self.builds[1].parameters['ZUUL_COMMIT'],
436 'org/project2': str(upstream['org/project2'].commit('master')),
437 'org/project3': str(upstream['org/project3'].commit('master')),
438 'org/project4': str(upstream['org/project4'].commit('master')),
439 'org/project5': str(upstream['org/project5'].commit('master')),
440 'org/project6': str(upstream['org/project6'].commit('master')),
441 },
442 {'org/project1': self.builds[1].parameters['ZUUL_COMMIT'],
443 'org/project2': self.builds[2].parameters['ZUUL_COMMIT'],
444 'org/project3': str(upstream['org/project3'].commit('master')),
445 'org/project4': str(upstream['org/project4'].commit('master')),
446 'org/project5': str(upstream['org/project5'].commit('master')),
447 'org/project6': str(upstream['org/project6'].commit('master')),
448 },
449 {'org/project1': self.builds[1].parameters['ZUUL_COMMIT'],
450 'org/project2': self.builds[2].parameters['ZUUL_COMMIT'],
451 'org/project3': self.builds[3].parameters['ZUUL_COMMIT'],
452 'org/project4': str(upstream['org/project4'].commit('master')),
453 'org/project5': str(upstream['org/project5'].commit('master')),
454 'org/project6': str(upstream['org/project6'].commit('stable/havana')),
455 },
456 ]
457
458 for number, build in enumerate(self.builds):
459 self.log.debug("Build parameters: %s", build.parameters)
460 change_number = int(build.parameters['ZUUL_CHANGE'])
461 cloner = zuul.lib.cloner.Cloner(
462 git_base_url=self.upstream_root,
463 projects=projects,
464 workspace=self.workspace_root,
465 zuul_branch=build.parameters['ZUUL_BRANCH'],
466 zuul_ref=build.parameters['ZUUL_REF'],
467 zuul_url=self.git_root,
468 project_branches={'org/project4': 'master'},
469 )
470 cloner.execute()
471 work = self.getWorkspaceRepos(projects)
472 state = states[number]
473
474 for project in projects:
475 self.assertEquals(state[project],
476 str(work[project].commit('HEAD')),
477 'Project %s commit for build %s should '
478 'be correct' % (project, number))
479 shutil.rmtree(self.workspace_root)
480
481 self.worker.hold_jobs_in_build = False
482 self.worker.release()
483 self.waitUntilSettled()