blob: b7cf912191e3a47fb29693bd9a6d1a62b39eedcd [file] [log] [blame]
James E. Blairb0fcae42012-07-17 11:12:10 -07001#!/usr/bin/env python
2
3# Copyright 2012 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
James E. Blairb0fcae42012-07-17 11:12:10 -070017import json
Monty Taylorbc758832013-06-17 17:22:42 -040018import logging
19import os
James E. Blairb0fcae42012-07-17 11:12:10 -070020import re
James E. Blair4886cc12012-07-18 15:39:41 -070021import shutil
Monty Taylorbc758832013-06-17 17:22:42 -040022import time
James E. Blairec056492016-07-22 09:45:56 -070023from unittest import skip
Monty Taylorbc758832013-06-17 17:22:42 -040024
James E. Blair4886cc12012-07-18 15:39:41 -070025import git
Morgan Fainberg293f7f82016-05-30 14:01:22 -070026from six.moves import urllib
Monty Taylorbc758832013-06-17 17:22:42 -040027import testtools
James E. Blairb0fcae42012-07-17 11:12:10 -070028
Maru Newby3fe5f852015-01-13 04:22:14 +000029import zuul.change_matcher
James E. Blairb0fcae42012-07-17 11:12:10 -070030import zuul.scheduler
James E. Blairad28e912013-11-27 10:43:22 -080031import zuul.rpcclient
Joshua Hesketh1879cf72013-08-19 14:13:15 +100032import zuul.reporter.gerrit
Joshua Hesketh5fea8672013-08-19 17:32:01 +100033import zuul.reporter.smtp
Paul Belanger9bba4902016-11-02 16:07:33 -040034import zuul.model
James E. Blairb0fcae42012-07-17 11:12:10 -070035
Maru Newby3fe5f852015-01-13 04:22:14 +000036from tests.base import (
Maru Newby3fe5f852015-01-13 04:22:14 +000037 ZuulTestCase,
38 repack_repo,
39)
James E. Blairb0fcae42012-07-17 11:12:10 -070040
James E. Blair1f4c2bb2013-04-26 08:40:46 -070041logging.basicConfig(level=logging.DEBUG,
42 format='%(asctime)s %(name)-32s '
43 '%(levelname)-8s %(message)s')
James E. Blairb0fcae42012-07-17 11:12:10 -070044
45
Clark Boylanb640e052014-04-03 16:41:46 -070046class TestScheduler(ZuulTestCase):
James E. Blair552b54f2016-07-22 13:55:32 -070047 tenant_config_file = 'config/single-tenant/main.yaml'
Antoine Mussobd86a312014-01-08 14:51:33 +010048
James E. Blairb0fcae42012-07-17 11:12:10 -070049 def test_jobs_launched(self):
50 "Test that jobs are launched and a change is merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -070051
James E. Blairb0fcae42012-07-17 11:12:10 -070052 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -070053 A.addApproval('code-review', 2)
54 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blairb0fcae42012-07-17 11:12:10 -070055 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -040056 self.assertEqual(self.getJobFromHistory('project-merge').result,
57 'SUCCESS')
58 self.assertEqual(self.getJobFromHistory('project-test1').result,
59 'SUCCESS')
60 self.assertEqual(self.getJobFromHistory('project-test2').result,
61 'SUCCESS')
62 self.assertEqual(A.data['status'], 'MERGED')
63 self.assertEqual(A.reported, 2)
James E. Blair34776ee2016-08-25 13:53:54 -070064 self.assertEqual(self.getJobFromHistory('project-test1').node,
65 'image1')
James E. Blairb0fcae42012-07-17 11:12:10 -070066
James E. Blair552b54f2016-07-22 13:55:32 -070067 # TODOv3(jeblair): we may want to report stats by tenant (also?).
James E. Blair66eeebf2013-07-27 17:44:32 -070068 self.assertReportedStat('gerrit.event.comment-added', value='1|c')
69 self.assertReportedStat('zuul.pipeline.gate.current_changes',
70 value='1|g')
71 self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
72 kind='ms')
73 self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
74 value='1|c')
75 self.assertReportedStat('zuul.pipeline.gate.resident_time', kind='ms')
76 self.assertReportedStat('zuul.pipeline.gate.total_changes',
77 value='1|c')
James E. Blair412e5582013-04-22 15:50:12 -070078 self.assertReportedStat(
James E. Blair66eeebf2013-07-27 17:44:32 -070079 'zuul.pipeline.gate.org.project.resident_time', kind='ms')
James E. Blair412e5582013-04-22 15:50:12 -070080 self.assertReportedStat(
James E. Blair66eeebf2013-07-27 17:44:32 -070081 'zuul.pipeline.gate.org.project.total_changes', value='1|c')
James E. Blair412e5582013-04-22 15:50:12 -070082
James E. Blair5821bd92015-09-16 08:48:15 -070083 for build in self.builds:
84 self.assertEqual(build.parameters['ZUUL_VOTING'], '1')
85
James E. Blair3cb10702013-08-24 08:56:03 -070086 def test_initial_pipeline_gauges(self):
87 "Test that each pipeline reported its length on start"
James E. Blair7da51b72016-07-25 15:29:43 -070088 self.assertReportedStat('zuul.pipeline.gate.current_changes',
89 value='0|g')
90 self.assertReportedStat('zuul.pipeline.check.current_changes',
91 value='0|g')
James E. Blair3cb10702013-08-24 08:56:03 -070092
James E. Blair34776ee2016-08-25 13:53:54 -070093 def test_job_branch(self):
94 "Test the correct variant of a job runs on a branch"
95 self.create_branch('org/project', 'stable')
96 A = self.fake_gerrit.addFakeChange('org/project', 'stable', 'A')
97 A.addApproval('code-review', 2)
98 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
99 self.waitUntilSettled()
100 self.assertEqual(self.getJobFromHistory('project-test1').result,
101 'SUCCESS')
102 self.assertEqual(self.getJobFromHistory('project-test2').result,
103 'SUCCESS')
104 self.assertEqual(A.data['status'], 'MERGED')
105 self.assertEqual(A.reported, 2,
106 "A should report start and success")
107 self.assertIn('gate', A.messages[1],
108 "A should transit gate")
109 self.assertEqual(self.getJobFromHistory('project-test1').node,
110 'image2')
111
James E. Blairb0fcae42012-07-17 11:12:10 -0700112 def test_parallel_changes(self):
113 "Test that changes are tested in parallel and merged in series"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700114
James E. Blair791b5392016-08-03 11:25:56 -0700115 self.launch_server.hold_jobs_in_build = True
James E. Blairb0fcae42012-07-17 11:12:10 -0700116 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
117 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
118 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700119 A.addApproval('code-review', 2)
120 B.addApproval('code-review', 2)
121 C.addApproval('code-review', 2)
James E. Blairb0fcae42012-07-17 11:12:10 -0700122
James E. Blair8b5408c2016-08-08 15:37:46 -0700123 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
124 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
125 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blairb0fcae42012-07-17 11:12:10 -0700126
127 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400128 self.assertEqual(len(self.builds), 1)
129 self.assertEqual(self.builds[0].name, 'project-merge')
James E. Blair791b5392016-08-03 11:25:56 -0700130 self.assertTrue(self.builds[0].hasChanges(A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700131
James E. Blair791b5392016-08-03 11:25:56 -0700132 self.launch_server.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700133 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400134 self.assertEqual(len(self.builds), 3)
135 self.assertEqual(self.builds[0].name, 'project-test1')
James E. Blair791b5392016-08-03 11:25:56 -0700136 self.assertTrue(self.builds[0].hasChanges(A))
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400137 self.assertEqual(self.builds[1].name, 'project-test2')
James E. Blair791b5392016-08-03 11:25:56 -0700138 self.assertTrue(self.builds[1].hasChanges(A))
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400139 self.assertEqual(self.builds[2].name, 'project-merge')
James E. Blair791b5392016-08-03 11:25:56 -0700140 self.assertTrue(self.builds[2].hasChanges(A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700141
James E. Blair791b5392016-08-03 11:25:56 -0700142 self.launch_server.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700143 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400144 self.assertEqual(len(self.builds), 5)
145 self.assertEqual(self.builds[0].name, 'project-test1')
James E. Blair791b5392016-08-03 11:25:56 -0700146 self.assertTrue(self.builds[0].hasChanges(A))
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400147 self.assertEqual(self.builds[1].name, 'project-test2')
James E. Blair791b5392016-08-03 11:25:56 -0700148 self.assertTrue(self.builds[1].hasChanges(A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700149
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400150 self.assertEqual(self.builds[2].name, 'project-test1')
James E. Blair791b5392016-08-03 11:25:56 -0700151 self.assertTrue(self.builds[2].hasChanges(A, B))
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400152 self.assertEqual(self.builds[3].name, 'project-test2')
James E. Blair791b5392016-08-03 11:25:56 -0700153 self.assertTrue(self.builds[3].hasChanges(A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700154
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400155 self.assertEqual(self.builds[4].name, 'project-merge')
James E. Blair791b5392016-08-03 11:25:56 -0700156 self.assertTrue(self.builds[4].hasChanges(A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700157
James E. Blair791b5392016-08-03 11:25:56 -0700158 self.launch_server.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700159 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400160 self.assertEqual(len(self.builds), 6)
161 self.assertEqual(self.builds[0].name, 'project-test1')
James E. Blair791b5392016-08-03 11:25:56 -0700162 self.assertTrue(self.builds[0].hasChanges(A))
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400163 self.assertEqual(self.builds[1].name, 'project-test2')
James E. Blair791b5392016-08-03 11:25:56 -0700164 self.assertTrue(self.builds[1].hasChanges(A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700165
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400166 self.assertEqual(self.builds[2].name, 'project-test1')
James E. Blair791b5392016-08-03 11:25:56 -0700167 self.assertTrue(self.builds[2].hasChanges(A, B))
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400168 self.assertEqual(self.builds[3].name, 'project-test2')
James E. Blair791b5392016-08-03 11:25:56 -0700169 self.assertTrue(self.builds[3].hasChanges(A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700170
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400171 self.assertEqual(self.builds[4].name, 'project-test1')
James E. Blair791b5392016-08-03 11:25:56 -0700172 self.assertTrue(self.builds[4].hasChanges(A, B, C))
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400173 self.assertEqual(self.builds[5].name, 'project-test2')
James E. Blair791b5392016-08-03 11:25:56 -0700174 self.assertTrue(self.builds[5].hasChanges(A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700175
James E. Blair791b5392016-08-03 11:25:56 -0700176 self.launch_server.hold_jobs_in_build = False
177 self.launch_server.release()
James E. Blairb0fcae42012-07-17 11:12:10 -0700178 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400179 self.assertEqual(len(self.builds), 0)
James E. Blairb0fcae42012-07-17 11:12:10 -0700180
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400181 self.assertEqual(len(self.history), 9)
182 self.assertEqual(A.data['status'], 'MERGED')
183 self.assertEqual(B.data['status'], 'MERGED')
184 self.assertEqual(C.data['status'], 'MERGED')
185 self.assertEqual(A.reported, 2)
186 self.assertEqual(B.reported, 2)
187 self.assertEqual(C.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700188
189 def test_failed_changes(self):
190 "Test that a change behind a failed change is retested"
James E. Blair08d19992016-08-10 15:25:31 -0700191 self.launch_server.hold_jobs_in_build = True
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700192
James E. Blairb02a3bb2012-07-30 17:49:55 -0700193 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
194 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -0700195 A.addApproval('code-review', 2)
196 B.addApproval('code-review', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700197
James E. Blair08d19992016-08-10 15:25:31 -0700198 self.launch_server.failJob('project-test1', A)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700199
James E. Blair8b5408c2016-08-08 15:37:46 -0700200 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
201 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700202 self.waitUntilSettled()
James E. Blair2b2a8ab2016-08-11 14:39:11 -0700203 self.assertBuilds([dict(name='project-merge', changes='1,1')])
James E. Blaire2819012013-06-28 17:17:26 -0400204
James E. Blair08d19992016-08-10 15:25:31 -0700205 self.launch_server.release('.*-merge')
James E. Blaire2819012013-06-28 17:17:26 -0400206 self.waitUntilSettled()
James E. Blair2b2a8ab2016-08-11 14:39:11 -0700207 # A/project-merge is complete
208 self.assertBuilds([
209 dict(name='project-test1', changes='1,1'),
210 dict(name='project-test2', changes='1,1'),
211 dict(name='project-merge', changes='1,1 2,1'),
212 ])
James E. Blaire2819012013-06-28 17:17:26 -0400213
James E. Blair2b2a8ab2016-08-11 14:39:11 -0700214 self.launch_server.release('.*-merge')
James E. Blaire2819012013-06-28 17:17:26 -0400215 self.waitUntilSettled()
James E. Blair2b2a8ab2016-08-11 14:39:11 -0700216 # A/project-merge is complete
217 # B/project-merge is complete
218 self.assertBuilds([
219 dict(name='project-test1', changes='1,1'),
220 dict(name='project-test2', changes='1,1'),
221 dict(name='project-test1', changes='1,1 2,1'),
222 dict(name='project-test2', changes='1,1 2,1'),
223 ])
224
225 # Release project-test1 for A which will fail. This will
226 # abort both running B jobs and relaunch project-merge for B.
227 self.builds[0].release()
228 self.waitUntilSettled()
229
230 self.orderedRelease()
231 self.assertHistory([
232 dict(name='project-merge', result='SUCCESS', changes='1,1'),
233 dict(name='project-merge', result='SUCCESS', changes='1,1 2,1'),
234 dict(name='project-test1', result='FAILURE', changes='1,1'),
235 dict(name='project-test1', result='ABORTED', changes='1,1 2,1'),
236 dict(name='project-test2', result='ABORTED', changes='1,1 2,1'),
237 dict(name='project-test2', result='SUCCESS', changes='1,1'),
238 dict(name='project-merge', result='SUCCESS', changes='2,1'),
239 dict(name='project-test1', result='SUCCESS', changes='2,1'),
240 dict(name='project-test2', result='SUCCESS', changes='2,1'),
James E. Blairb536ecc2016-08-31 10:11:42 -0700241 ], ordered=False)
James E. Blair2b2a8ab2016-08-11 14:39:11 -0700242
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400243 self.assertEqual(A.data['status'], 'NEW')
244 self.assertEqual(B.data['status'], 'MERGED')
245 self.assertEqual(A.reported, 2)
246 self.assertEqual(B.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700247
248 def test_independent_queues(self):
249 "Test that changes end up in the right queues"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700250
James E. Blair08d19992016-08-10 15:25:31 -0700251 self.launch_server.hold_jobs_in_build = True
Zhongyue Luo5d556072012-09-21 02:00:47 +0900252 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700253 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
254 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700255 A.addApproval('code-review', 2)
256 B.addApproval('code-review', 2)
257 C.addApproval('code-review', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700258
James E. Blair8b5408c2016-08-08 15:37:46 -0700259 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
260 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
261 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700262
James E. Blairb02a3bb2012-07-30 17:49:55 -0700263 self.waitUntilSettled()
264
265 # There should be one merge job at the head of each queue running
James E. Blair5f0d49e2016-08-19 09:36:50 -0700266 self.assertBuilds([
267 dict(name='project-merge', changes='1,1'),
268 dict(name='project-merge', changes='2,1'),
269 ])
James E. Blairb02a3bb2012-07-30 17:49:55 -0700270
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700271 # Release the current merge builds
James E. Blair5f0d49e2016-08-19 09:36:50 -0700272 self.builds[0].release()
273 self.waitUntilSettled()
274 self.builds[0].release()
James E. Blairb02a3bb2012-07-30 17:49:55 -0700275 self.waitUntilSettled()
276 # Release the merge job for project2 which is behind project1
James E. Blair08d19992016-08-10 15:25:31 -0700277 self.launch_server.release('.*-merge')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700278 self.waitUntilSettled()
279
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700280 # All the test builds should be running:
James E. Blair5f0d49e2016-08-19 09:36:50 -0700281 self.assertBuilds([
282 dict(name='project-test1', changes='1,1'),
283 dict(name='project-test2', changes='1,1'),
284 dict(name='project-test1', changes='2,1'),
285 dict(name='project-test2', changes='2,1'),
Paul Belanger58bf6912016-11-11 19:36:01 -0500286 dict(name='project1-project2-integration', changes='2,1'),
James E. Blair5f0d49e2016-08-19 09:36:50 -0700287 dict(name='project-test1', changes='2,1 3,1'),
288 dict(name='project-test2', changes='2,1 3,1'),
289 ])
James E. Blairb02a3bb2012-07-30 17:49:55 -0700290
James E. Blair5f0d49e2016-08-19 09:36:50 -0700291 self.orderedRelease()
292 self.assertHistory([
293 dict(name='project-merge', result='SUCCESS', changes='1,1'),
294 dict(name='project-merge', result='SUCCESS', changes='2,1'),
295 dict(name='project-merge', result='SUCCESS', changes='2,1 3,1'),
296 dict(name='project-test1', result='SUCCESS', changes='1,1'),
297 dict(name='project-test2', result='SUCCESS', changes='1,1'),
298 dict(name='project-test1', result='SUCCESS', changes='2,1'),
299 dict(name='project-test2', result='SUCCESS', changes='2,1'),
Paul Belanger58bf6912016-11-11 19:36:01 -0500300 dict(
301 name='project1-project2-integration',
302 result='SUCCESS',
303 changes='2,1'),
James E. Blair5f0d49e2016-08-19 09:36:50 -0700304 dict(name='project-test1', result='SUCCESS', changes='2,1 3,1'),
305 dict(name='project-test2', result='SUCCESS', changes='2,1 3,1'),
306 ])
James E. Blairb02a3bb2012-07-30 17:49:55 -0700307
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400308 self.assertEqual(A.data['status'], 'MERGED')
309 self.assertEqual(B.data['status'], 'MERGED')
310 self.assertEqual(C.data['status'], 'MERGED')
311 self.assertEqual(A.reported, 2)
312 self.assertEqual(B.reported, 2)
313 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700314
315 def test_failed_change_at_head(self):
316 "Test that if a change at the head fails, jobs behind it are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700317
James E. Blair08d19992016-08-10 15:25:31 -0700318 self.launch_server.hold_jobs_in_build = True
James E. Blaird466dc42012-07-31 10:42:56 -0700319 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
320 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
321 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700322 A.addApproval('code-review', 2)
323 B.addApproval('code-review', 2)
324 C.addApproval('code-review', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700325
James E. Blair08d19992016-08-10 15:25:31 -0700326 self.launch_server.failJob('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700327
James E. Blair8b5408c2016-08-08 15:37:46 -0700328 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
329 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
330 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blaird466dc42012-07-31 10:42:56 -0700331
332 self.waitUntilSettled()
James E. Blaird466dc42012-07-31 10:42:56 -0700333
James E. Blairb536ecc2016-08-31 10:11:42 -0700334 self.assertBuilds([
335 dict(name='project-merge', changes='1,1'),
336 ])
James E. Blaird466dc42012-07-31 10:42:56 -0700337
James E. Blair08d19992016-08-10 15:25:31 -0700338 self.launch_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700339 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700340 self.launch_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700341 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700342 self.launch_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700343 self.waitUntilSettled()
344
James E. Blairb536ecc2016-08-31 10:11:42 -0700345 self.assertBuilds([
346 dict(name='project-test1', changes='1,1'),
347 dict(name='project-test2', changes='1,1'),
348 dict(name='project-test1', changes='1,1 2,1'),
349 dict(name='project-test2', changes='1,1 2,1'),
350 dict(name='project-test1', changes='1,1 2,1 3,1'),
351 dict(name='project-test2', changes='1,1 2,1 3,1'),
352 ])
James E. Blaird466dc42012-07-31 10:42:56 -0700353
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400354 self.release(self.builds[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700355 self.waitUntilSettled()
356
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400357 # project-test2, project-merge for B
James E. Blairb536ecc2016-08-31 10:11:42 -0700358 self.assertBuilds([
359 dict(name='project-test2', changes='1,1'),
360 dict(name='project-merge', changes='2,1'),
361 ])
362 # Unordered history comparison because the aborts can finish
363 # in any order.
364 self.assertHistory([
365 dict(name='project-merge', result='SUCCESS',
366 changes='1,1'),
367 dict(name='project-merge', result='SUCCESS',
368 changes='1,1 2,1'),
369 dict(name='project-merge', result='SUCCESS',
370 changes='1,1 2,1 3,1'),
371 dict(name='project-test1', result='FAILURE',
372 changes='1,1'),
373 dict(name='project-test1', result='ABORTED',
374 changes='1,1 2,1'),
375 dict(name='project-test2', result='ABORTED',
376 changes='1,1 2,1'),
377 dict(name='project-test1', result='ABORTED',
378 changes='1,1 2,1 3,1'),
379 dict(name='project-test2', result='ABORTED',
380 changes='1,1 2,1 3,1'),
381 ], ordered=False)
James E. Blaird466dc42012-07-31 10:42:56 -0700382
James E. Blairb536ecc2016-08-31 10:11:42 -0700383 self.launch_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700384 self.waitUntilSettled()
James E. Blairb536ecc2016-08-31 10:11:42 -0700385 self.launch_server.release('.*-merge')
386 self.waitUntilSettled()
387 self.orderedRelease()
James E. Blaird466dc42012-07-31 10:42:56 -0700388
James E. Blairb536ecc2016-08-31 10:11:42 -0700389 self.assertBuilds([])
390 self.assertHistory([
391 dict(name='project-merge', result='SUCCESS',
392 changes='1,1'),
393 dict(name='project-merge', result='SUCCESS',
394 changes='1,1 2,1'),
395 dict(name='project-merge', result='SUCCESS',
396 changes='1,1 2,1 3,1'),
397 dict(name='project-test1', result='FAILURE',
398 changes='1,1'),
399 dict(name='project-test1', result='ABORTED',
400 changes='1,1 2,1'),
401 dict(name='project-test2', result='ABORTED',
402 changes='1,1 2,1'),
403 dict(name='project-test1', result='ABORTED',
404 changes='1,1 2,1 3,1'),
405 dict(name='project-test2', result='ABORTED',
406 changes='1,1 2,1 3,1'),
407 dict(name='project-merge', result='SUCCESS',
408 changes='2,1'),
409 dict(name='project-merge', result='SUCCESS',
410 changes='2,1 3,1'),
411 dict(name='project-test2', result='SUCCESS',
412 changes='1,1'),
413 dict(name='project-test1', result='SUCCESS',
414 changes='2,1'),
415 dict(name='project-test2', result='SUCCESS',
416 changes='2,1'),
417 dict(name='project-test1', result='SUCCESS',
418 changes='2,1 3,1'),
419 dict(name='project-test2', result='SUCCESS',
420 changes='2,1 3,1'),
421 ], ordered=False)
422
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400423 self.assertEqual(A.data['status'], 'NEW')
424 self.assertEqual(B.data['status'], 'MERGED')
425 self.assertEqual(C.data['status'], 'MERGED')
426 self.assertEqual(A.reported, 2)
427 self.assertEqual(B.reported, 2)
428 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700429
James E. Blair0aac4872013-08-23 14:02:38 -0700430 def test_failed_change_in_middle(self):
431 "Test a failed change in the middle of the queue"
432
James E. Blair08d19992016-08-10 15:25:31 -0700433 self.launch_server.hold_jobs_in_build = True
James E. Blair0aac4872013-08-23 14:02:38 -0700434 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
435 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
436 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700437 A.addApproval('code-review', 2)
438 B.addApproval('code-review', 2)
439 C.addApproval('code-review', 2)
James E. Blair0aac4872013-08-23 14:02:38 -0700440
James E. Blair08d19992016-08-10 15:25:31 -0700441 self.launch_server.failJob('project-test1', B)
James E. Blair0aac4872013-08-23 14:02:38 -0700442
James E. Blair8b5408c2016-08-08 15:37:46 -0700443 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
444 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
445 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair0aac4872013-08-23 14:02:38 -0700446
447 self.waitUntilSettled()
448
James E. Blair08d19992016-08-10 15:25:31 -0700449 self.launch_server.release('.*-merge')
James E. Blair0aac4872013-08-23 14:02:38 -0700450 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700451 self.launch_server.release('.*-merge')
James E. Blair0aac4872013-08-23 14:02:38 -0700452 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700453 self.launch_server.release('.*-merge')
James E. Blair0aac4872013-08-23 14:02:38 -0700454 self.waitUntilSettled()
455
456 self.assertEqual(len(self.builds), 6)
457 self.assertEqual(self.builds[0].name, 'project-test1')
458 self.assertEqual(self.builds[1].name, 'project-test2')
459 self.assertEqual(self.builds[2].name, 'project-test1')
460 self.assertEqual(self.builds[3].name, 'project-test2')
461 self.assertEqual(self.builds[4].name, 'project-test1')
462 self.assertEqual(self.builds[5].name, 'project-test2')
463
464 self.release(self.builds[2])
465 self.waitUntilSettled()
466
James E. Blair972e3c72013-08-29 12:04:55 -0700467 # project-test1 and project-test2 for A
468 # project-test2 for B
469 # project-merge for C (without B)
470 self.assertEqual(len(self.builds), 4)
James E. Blair0aac4872013-08-23 14:02:38 -0700471 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 2)
472
James E. Blair08d19992016-08-10 15:25:31 -0700473 self.launch_server.release('.*-merge')
James E. Blair972e3c72013-08-29 12:04:55 -0700474 self.waitUntilSettled()
475
476 # project-test1 and project-test2 for A
477 # project-test2 for B
478 # project-test1 and project-test2 for C
479 self.assertEqual(len(self.builds), 5)
480
Paul Belanger2e2a0492016-10-30 18:33:37 -0400481 tenant = self.sched.abide.tenants.get('tenant-one')
482 items = tenant.layout.pipelines['gate'].getAllItems()
James E. Blair0aac4872013-08-23 14:02:38 -0700483 builds = items[0].current_build_set.getBuilds()
484 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
485 self.assertEqual(self.countJobResults(builds, None), 2)
486 builds = items[1].current_build_set.getBuilds()
487 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
488 self.assertEqual(self.countJobResults(builds, 'FAILURE'), 1)
489 self.assertEqual(self.countJobResults(builds, None), 1)
490 builds = items[2].current_build_set.getBuilds()
491 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
James E. Blair972e3c72013-08-29 12:04:55 -0700492 self.assertEqual(self.countJobResults(builds, None), 2)
James E. Blair0aac4872013-08-23 14:02:38 -0700493
James E. Blair08d19992016-08-10 15:25:31 -0700494 self.launch_server.hold_jobs_in_build = False
495 self.launch_server.release()
James E. Blair0aac4872013-08-23 14:02:38 -0700496 self.waitUntilSettled()
497
498 self.assertEqual(len(self.builds), 0)
499 self.assertEqual(len(self.history), 12)
500 self.assertEqual(A.data['status'], 'MERGED')
501 self.assertEqual(B.data['status'], 'NEW')
502 self.assertEqual(C.data['status'], 'MERGED')
503 self.assertEqual(A.reported, 2)
504 self.assertEqual(B.reported, 2)
505 self.assertEqual(C.reported, 2)
506
James E. Blaird466dc42012-07-31 10:42:56 -0700507 def test_failed_change_at_head_with_queue(self):
508 "Test that if a change at the head fails, queued jobs are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700509
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700510 self.gearman_server.hold_jobs_in_queue = True
James E. Blaird466dc42012-07-31 10:42:56 -0700511 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
512 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
513 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700514 A.addApproval('code-review', 2)
515 B.addApproval('code-review', 2)
516 C.addApproval('code-review', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700517
James E. Blair08d19992016-08-10 15:25:31 -0700518 self.launch_server.failJob('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700519
James E. Blair8b5408c2016-08-08 15:37:46 -0700520 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
521 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
522 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blaird466dc42012-07-31 10:42:56 -0700523
524 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700525 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400526 self.assertEqual(len(self.builds), 0)
527 self.assertEqual(len(queue), 1)
Clint Byrum8b2bc0c2016-11-16 16:28:50 -0800528 self.assertEqual(queue[0].name, 'launcher:launch')
529 job_args = json.loads(queue[0].arguments)
530 self.assertEqual(job_args['job'], 'project-merge')
531 self.assertEqual(job_args['items'][0]['number'], '%d' % A.number)
James E. Blaird466dc42012-07-31 10:42:56 -0700532
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700533 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700534 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700535 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700536 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700537 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700538 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700539 queue = self.gearman_server.getQueue()
James E. Blaird466dc42012-07-31 10:42:56 -0700540
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400541 self.assertEqual(len(self.builds), 0)
542 self.assertEqual(len(queue), 6)
Clint Byrum8b2bc0c2016-11-16 16:28:50 -0800543
544 self.assertEqual(
545 json.loads(queue[0].arguments)['job'], 'project-test1')
546 self.assertEqual(
547 json.loads(queue[1].arguments)['job'], 'project-test2')
548 self.assertEqual(
549 json.loads(queue[2].arguments)['job'], 'project-test1')
550 self.assertEqual(
551 json.loads(queue[3].arguments)['job'], 'project-test2')
552 self.assertEqual(
553 json.loads(queue[4].arguments)['job'], 'project-test1')
554 self.assertEqual(
555 json.loads(queue[5].arguments)['job'], 'project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700556
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700557 self.release(queue[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700558 self.waitUntilSettled()
559
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400560 self.assertEqual(len(self.builds), 0)
James E. Blair701c5b42013-06-06 09:34:59 -0700561 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400562 self.assertEqual(len(queue), 2) # project-test2, project-merge for B
563 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 0)
James E. Blaird466dc42012-07-31 10:42:56 -0700564
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700565 self.gearman_server.hold_jobs_in_queue = False
566 self.gearman_server.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700567 self.waitUntilSettled()
568
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400569 self.assertEqual(len(self.builds), 0)
570 self.assertEqual(len(self.history), 11)
571 self.assertEqual(A.data['status'], 'NEW')
572 self.assertEqual(B.data['status'], 'MERGED')
573 self.assertEqual(C.data['status'], 'MERGED')
574 self.assertEqual(A.reported, 2)
575 self.assertEqual(B.reported, 2)
576 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700577
James E. Blairec056492016-07-22 09:45:56 -0700578 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700579 def _test_time_database(self, iteration):
James E. Blair08d19992016-08-10 15:25:31 -0700580 self.launch_server.hold_jobs_in_build = True
James E. Blairce8a2132016-05-19 15:21:52 -0700581 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -0700582 A.addApproval('code-review', 2)
583 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blairce8a2132016-05-19 15:21:52 -0700584 self.waitUntilSettled()
585 time.sleep(2)
586
587 data = json.loads(self.sched.formatStatusJSON())
588 found_job = None
589 for pipeline in data['pipelines']:
590 if pipeline['name'] != 'gate':
591 continue
592 for queue in pipeline['change_queues']:
593 for head in queue['heads']:
594 for item in head:
595 for job in item['jobs']:
596 if job['name'] == 'project-merge':
597 found_job = job
598 break
599
600 self.assertIsNotNone(found_job)
601 if iteration == 1:
602 self.assertIsNotNone(found_job['estimated_time'])
603 self.assertIsNone(found_job['remaining_time'])
604 else:
605 self.assertIsNotNone(found_job['estimated_time'])
606 self.assertTrue(found_job['estimated_time'] >= 2)
607 self.assertIsNotNone(found_job['remaining_time'])
608
James E. Blair08d19992016-08-10 15:25:31 -0700609 self.launch_server.hold_jobs_in_build = False
610 self.launch_server.release()
James E. Blairce8a2132016-05-19 15:21:52 -0700611 self.waitUntilSettled()
612
James E. Blairec056492016-07-22 09:45:56 -0700613 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700614 def test_time_database(self):
615 "Test the time database"
616
617 self._test_time_database(1)
618 self._test_time_database(2)
619
James E. Blairfef71632013-09-23 11:15:47 -0700620 def test_two_failed_changes_at_head(self):
621 "Test that changes are reparented correctly if 2 fail at head"
622
James E. Blair08d19992016-08-10 15:25:31 -0700623 self.launch_server.hold_jobs_in_build = True
James E. Blairfef71632013-09-23 11:15:47 -0700624 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
625 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
626 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700627 A.addApproval('code-review', 2)
628 B.addApproval('code-review', 2)
629 C.addApproval('code-review', 2)
James E. Blairfef71632013-09-23 11:15:47 -0700630
James E. Blair08d19992016-08-10 15:25:31 -0700631 self.launch_server.failJob('project-test1', A)
632 self.launch_server.failJob('project-test1', B)
James E. Blairfef71632013-09-23 11:15:47 -0700633
James E. Blair8b5408c2016-08-08 15:37:46 -0700634 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
635 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
636 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blairfef71632013-09-23 11:15:47 -0700637 self.waitUntilSettled()
638
James E. Blair08d19992016-08-10 15:25:31 -0700639 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700640 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700641 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700642 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700643 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700644 self.waitUntilSettled()
645
646 self.assertEqual(len(self.builds), 6)
647 self.assertEqual(self.builds[0].name, 'project-test1')
648 self.assertEqual(self.builds[1].name, 'project-test2')
649 self.assertEqual(self.builds[2].name, 'project-test1')
650 self.assertEqual(self.builds[3].name, 'project-test2')
651 self.assertEqual(self.builds[4].name, 'project-test1')
652 self.assertEqual(self.builds[5].name, 'project-test2')
653
Paul Belanger71dd2fc2016-11-04 19:05:55 -0400654 self.assertTrue(self.builds[0].hasChanges(A))
655 self.assertTrue(self.builds[2].hasChanges(A))
656 self.assertTrue(self.builds[2].hasChanges(B))
657 self.assertTrue(self.builds[4].hasChanges(A))
658 self.assertTrue(self.builds[4].hasChanges(B))
659 self.assertTrue(self.builds[4].hasChanges(C))
James E. Blairfef71632013-09-23 11:15:47 -0700660
661 # Fail change B first
662 self.release(self.builds[2])
663 self.waitUntilSettled()
664
665 # restart of C after B failure
James E. Blair08d19992016-08-10 15:25:31 -0700666 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700667 self.waitUntilSettled()
668
669 self.assertEqual(len(self.builds), 5)
670 self.assertEqual(self.builds[0].name, 'project-test1')
671 self.assertEqual(self.builds[1].name, 'project-test2')
672 self.assertEqual(self.builds[2].name, 'project-test2')
673 self.assertEqual(self.builds[3].name, 'project-test1')
674 self.assertEqual(self.builds[4].name, 'project-test2')
675
Paul Belanger71dd2fc2016-11-04 19:05:55 -0400676 self.assertTrue(self.builds[1].hasChanges(A))
677 self.assertTrue(self.builds[2].hasChanges(A))
678 self.assertTrue(self.builds[2].hasChanges(B))
679 self.assertTrue(self.builds[4].hasChanges(A))
680 self.assertFalse(self.builds[4].hasChanges(B))
681 self.assertTrue(self.builds[4].hasChanges(C))
James E. Blairfef71632013-09-23 11:15:47 -0700682
683 # Finish running all passing jobs for change A
684 self.release(self.builds[1])
685 self.waitUntilSettled()
686 # Fail and report change A
687 self.release(self.builds[0])
688 self.waitUntilSettled()
689
690 # restart of B,C after A failure
James E. Blair08d19992016-08-10 15:25:31 -0700691 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700692 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700693 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700694 self.waitUntilSettled()
695
696 self.assertEqual(len(self.builds), 4)
697 self.assertEqual(self.builds[0].name, 'project-test1') # B
698 self.assertEqual(self.builds[1].name, 'project-test2') # B
699 self.assertEqual(self.builds[2].name, 'project-test1') # C
700 self.assertEqual(self.builds[3].name, 'project-test2') # C
701
Paul Belanger71dd2fc2016-11-04 19:05:55 -0400702 self.assertFalse(self.builds[1].hasChanges(A))
703 self.assertTrue(self.builds[1].hasChanges(B))
704 self.assertFalse(self.builds[1].hasChanges(C))
James E. Blairfef71632013-09-23 11:15:47 -0700705
Paul Belanger71dd2fc2016-11-04 19:05:55 -0400706 self.assertFalse(self.builds[2].hasChanges(A))
James E. Blairfef71632013-09-23 11:15:47 -0700707 # After A failed and B and C restarted, B should be back in
708 # C's tests because it has not failed yet.
Paul Belanger71dd2fc2016-11-04 19:05:55 -0400709 self.assertTrue(self.builds[2].hasChanges(B))
710 self.assertTrue(self.builds[2].hasChanges(C))
James E. Blairfef71632013-09-23 11:15:47 -0700711
James E. Blair08d19992016-08-10 15:25:31 -0700712 self.launch_server.hold_jobs_in_build = False
713 self.launch_server.release()
James E. Blairfef71632013-09-23 11:15:47 -0700714 self.waitUntilSettled()
715
716 self.assertEqual(len(self.builds), 0)
717 self.assertEqual(len(self.history), 21)
718 self.assertEqual(A.data['status'], 'NEW')
719 self.assertEqual(B.data['status'], 'NEW')
720 self.assertEqual(C.data['status'], 'MERGED')
721 self.assertEqual(A.reported, 2)
722 self.assertEqual(B.reported, 2)
723 self.assertEqual(C.reported, 2)
724
James E. Blair8c803f82012-07-31 16:25:42 -0700725 def test_patch_order(self):
726 "Test that dependent patches are tested in the right order"
727 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
728 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
729 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700730 A.addApproval('code-review', 2)
731 B.addApproval('code-review', 2)
732 C.addApproval('code-review', 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700733
734 M2 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M2')
735 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
736 M2.setMerged()
737 M1.setMerged()
738
739 # C -> B -> A -> M1 -> M2
740 # M2 is here to make sure it is never queried. If it is, it
741 # means zuul is walking down the entire history of merged
742 # changes.
743
744 C.setDependsOn(B, 1)
745 B.setDependsOn(A, 1)
746 A.setDependsOn(M1, 1)
747 M1.setDependsOn(M2, 1)
748
James E. Blair8b5408c2016-08-08 15:37:46 -0700749 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair8c803f82012-07-31 16:25:42 -0700750
751 self.waitUntilSettled()
752
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400753 self.assertEqual(A.data['status'], 'NEW')
754 self.assertEqual(B.data['status'], 'NEW')
755 self.assertEqual(C.data['status'], 'NEW')
James E. Blair8c803f82012-07-31 16:25:42 -0700756
James E. Blair8b5408c2016-08-08 15:37:46 -0700757 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
758 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair8c803f82012-07-31 16:25:42 -0700759
760 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400761 self.assertEqual(M2.queried, 0)
762 self.assertEqual(A.data['status'], 'MERGED')
763 self.assertEqual(B.data['status'], 'MERGED')
764 self.assertEqual(C.data['status'], 'MERGED')
765 self.assertEqual(A.reported, 2)
766 self.assertEqual(B.reported, 2)
767 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700768
James E. Blair063672f2015-01-29 13:09:12 -0800769 def test_needed_changes_enqueue(self):
770 "Test that a needed change is enqueued ahead"
771 # A Given a git tree like this, if we enqueue
772 # / \ change C, we should walk up and down the tree
773 # B G and enqueue changes in the order ABCDEFG.
774 # /|\ This is also the order that you would get if
775 # *C E F you enqueued changes in the order ABCDEFG, so
776 # / the ordering is stable across re-enqueue events.
777 # D
778
779 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
780 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
781 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
782 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
783 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
784 F = self.fake_gerrit.addFakeChange('org/project', 'master', 'F')
785 G = self.fake_gerrit.addFakeChange('org/project', 'master', 'G')
786 B.setDependsOn(A, 1)
787 C.setDependsOn(B, 1)
788 D.setDependsOn(C, 1)
789 E.setDependsOn(B, 1)
790 F.setDependsOn(B, 1)
791 G.setDependsOn(A, 1)
792
James E. Blair8b5408c2016-08-08 15:37:46 -0700793 A.addApproval('code-review', 2)
794 B.addApproval('code-review', 2)
795 C.addApproval('code-review', 2)
796 D.addApproval('code-review', 2)
797 E.addApproval('code-review', 2)
798 F.addApproval('code-review', 2)
799 G.addApproval('code-review', 2)
800 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair063672f2015-01-29 13:09:12 -0800801
802 self.waitUntilSettled()
803
804 self.assertEqual(A.data['status'], 'NEW')
805 self.assertEqual(B.data['status'], 'NEW')
806 self.assertEqual(C.data['status'], 'NEW')
807 self.assertEqual(D.data['status'], 'NEW')
808 self.assertEqual(E.data['status'], 'NEW')
809 self.assertEqual(F.data['status'], 'NEW')
810 self.assertEqual(G.data['status'], 'NEW')
811
812 # We're about to add approvals to changes without adding the
813 # triggering events to Zuul, so that we can be sure that it is
814 # enqueing the changes based on dependencies, not because of
815 # triggering events. Since it will have the changes cached
816 # already (without approvals), we need to clear the cache
817 # first.
Paul Belanger593480a2016-11-02 19:06:28 -0400818 for connection in self.connections.connections.values():
Joshua Hesketh4bd7da32016-02-17 20:58:47 +1100819 connection.maintainCache([])
James E. Blair063672f2015-01-29 13:09:12 -0800820
James E. Blair08d19992016-08-10 15:25:31 -0700821 self.launch_server.hold_jobs_in_build = True
James E. Blair8b5408c2016-08-08 15:37:46 -0700822 A.addApproval('approved', 1)
823 B.addApproval('approved', 1)
824 D.addApproval('approved', 1)
825 E.addApproval('approved', 1)
826 F.addApproval('approved', 1)
827 G.addApproval('approved', 1)
828 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair063672f2015-01-29 13:09:12 -0800829
830 for x in range(8):
James E. Blair08d19992016-08-10 15:25:31 -0700831 self.launch_server.release('.*-merge')
James E. Blair063672f2015-01-29 13:09:12 -0800832 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700833 self.launch_server.hold_jobs_in_build = False
834 self.launch_server.release()
James E. Blair063672f2015-01-29 13:09:12 -0800835 self.waitUntilSettled()
836
837 self.assertEqual(A.data['status'], 'MERGED')
838 self.assertEqual(B.data['status'], 'MERGED')
839 self.assertEqual(C.data['status'], 'MERGED')
840 self.assertEqual(D.data['status'], 'MERGED')
841 self.assertEqual(E.data['status'], 'MERGED')
842 self.assertEqual(F.data['status'], 'MERGED')
843 self.assertEqual(G.data['status'], 'MERGED')
844 self.assertEqual(A.reported, 2)
845 self.assertEqual(B.reported, 2)
846 self.assertEqual(C.reported, 2)
847 self.assertEqual(D.reported, 2)
848 self.assertEqual(E.reported, 2)
849 self.assertEqual(F.reported, 2)
850 self.assertEqual(G.reported, 2)
851 self.assertEqual(self.history[6].changes,
852 '1,1 2,1 3,1 4,1 5,1 6,1 7,1')
853
Joshua Hesketh850ccb62014-11-27 11:31:02 +1100854 def test_source_cache(self):
855 "Test that the source cache operates correctly"
James E. Blair08d19992016-08-10 15:25:31 -0700856 self.launch_server.hold_jobs_in_build = True
James E. Blair0e933c52013-07-11 10:18:52 -0700857
858 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
859 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
860 X = self.fake_gerrit.addFakeChange('org/project', 'master', 'X')
James E. Blair8b5408c2016-08-08 15:37:46 -0700861 A.addApproval('code-review', 2)
862 B.addApproval('code-review', 2)
James E. Blair0e933c52013-07-11 10:18:52 -0700863
864 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
865 M1.setMerged()
866
867 B.setDependsOn(A, 1)
868 A.setDependsOn(M1, 1)
869
James E. Blair8b5408c2016-08-08 15:37:46 -0700870 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair0e933c52013-07-11 10:18:52 -0700871 self.fake_gerrit.addEvent(X.getPatchsetCreatedEvent(1))
872
873 self.waitUntilSettled()
874
875 for build in self.builds:
876 if build.parameters['ZUUL_PIPELINE'] == 'check':
877 build.release()
878 self.waitUntilSettled()
879 for build in self.builds:
880 if build.parameters['ZUUL_PIPELINE'] == 'check':
881 build.release()
882 self.waitUntilSettled()
883
James E. Blair8b5408c2016-08-08 15:37:46 -0700884 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair0e933c52013-07-11 10:18:52 -0700885 self.waitUntilSettled()
886
Joshua Hesketh352264b2015-08-11 23:42:08 +1000887 self.log.debug("len %s" % self.fake_gerrit._change_cache.keys())
James E. Blair0e933c52013-07-11 10:18:52 -0700888 # there should still be changes in the cache
Joshua Hesketh352264b2015-08-11 23:42:08 +1000889 self.assertNotEqual(len(self.fake_gerrit._change_cache.keys()), 0)
James E. Blair0e933c52013-07-11 10:18:52 -0700890
James E. Blair08d19992016-08-10 15:25:31 -0700891 self.launch_server.hold_jobs_in_build = False
892 self.launch_server.release()
James E. Blair0e933c52013-07-11 10:18:52 -0700893 self.waitUntilSettled()
894
895 self.assertEqual(A.data['status'], 'MERGED')
896 self.assertEqual(B.data['status'], 'MERGED')
897 self.assertEqual(A.queried, 2) # Initial and isMerged
898 self.assertEqual(B.queried, 3) # Initial A, refresh from B, isMerged
899
James E. Blair8c803f82012-07-31 16:25:42 -0700900 def test_can_merge(self):
James E. Blair4886cc12012-07-18 15:39:41 -0700901 "Test whether a change is ready to merge"
James E. Blair8c803f82012-07-31 16:25:42 -0700902 # TODO: move to test_gerrit (this is a unit test!)
903 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
Paul Belanger9bba4902016-11-02 16:07:33 -0400904 tenant = self.sched.abide.tenants.get('tenant-one')
905 source = tenant.layout.pipelines['gate'].source
906
907 # TODO(pabelanger): As we add more source / trigger APIs we should make
908 # it easier for users to create events for testing.
909 event = zuul.model.TriggerEvent()
910 event.trigger_name = 'gerrit'
911 event.change_number = '1'
912 event.patch_number = '2'
913
914 a = source.getChange(event)
915 mgr = tenant.layout.pipelines['gate'].manager
James E. Blairc0dedf82014-08-06 09:37:52 -0700916 self.assertFalse(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700917
James E. Blair8b5408c2016-08-08 15:37:46 -0700918 A.addApproval('code-review', 2)
Paul Belanger9bba4902016-11-02 16:07:33 -0400919 a = source.getChange(event, refresh=True)
James E. Blairc0dedf82014-08-06 09:37:52 -0700920 self.assertFalse(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700921
James E. Blair8b5408c2016-08-08 15:37:46 -0700922 A.addApproval('approved', 1)
Paul Belanger9bba4902016-11-02 16:07:33 -0400923 a = source.getChange(event, refresh=True)
James E. Blairc0dedf82014-08-06 09:37:52 -0700924 self.assertTrue(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair4886cc12012-07-18 15:39:41 -0700925
James E. Blairec056492016-07-22 09:45:56 -0700926 @skip("Disabled for early v3 development")
James E. Blair973721f2012-08-15 10:19:43 -0700927 def test_build_configuration_conflict(self):
928 "Test that merge conflicts are handled"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700929
930 self.gearman_server.hold_jobs_in_queue = True
James E. Blair6736beb2013-07-11 15:18:15 -0700931 A = self.fake_gerrit.addFakeChange('org/conflict-project',
932 'master', 'A')
James E. Blair973721f2012-08-15 10:19:43 -0700933 A.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700934 B = self.fake_gerrit.addFakeChange('org/conflict-project',
935 'master', 'B')
James E. Blair973721f2012-08-15 10:19:43 -0700936 B.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700937 C = self.fake_gerrit.addFakeChange('org/conflict-project',
938 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700939 A.addApproval('code-review', 2)
940 B.addApproval('code-review', 2)
941 C.addApproval('code-review', 2)
942 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
943 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
944 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair973721f2012-08-15 10:19:43 -0700945 self.waitUntilSettled()
946
James E. Blair6736beb2013-07-11 15:18:15 -0700947 self.assertEqual(A.reported, 1)
948 self.assertEqual(B.reported, 1)
949 self.assertEqual(C.reported, 1)
950
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700951 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700952 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700953 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700954 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700955 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700956 self.waitUntilSettled()
James E. Blair972e3c72013-08-29 12:04:55 -0700957
958 self.assertEqual(len(self.history), 2) # A and C merge jobs
959
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700960 self.gearman_server.hold_jobs_in_queue = False
961 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700962 self.waitUntilSettled()
963
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400964 self.assertEqual(A.data['status'], 'MERGED')
965 self.assertEqual(B.data['status'], 'NEW')
966 self.assertEqual(C.data['status'], 'MERGED')
967 self.assertEqual(A.reported, 2)
968 self.assertEqual(B.reported, 2)
969 self.assertEqual(C.reported, 2)
James E. Blair972e3c72013-08-29 12:04:55 -0700970 self.assertEqual(len(self.history), 6)
James E. Blair6736beb2013-07-11 15:18:15 -0700971
James E. Blairdaabed22012-08-15 15:38:57 -0700972 def test_post(self):
973 "Test that post jobs run"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700974
Zhongyue Luo5d556072012-09-21 02:00:47 +0900975 e = {
976 "type": "ref-updated",
977 "submitter": {
978 "name": "User Name",
979 },
980 "refUpdate": {
981 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
982 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
983 "refName": "master",
984 "project": "org/project",
985 }
986 }
James E. Blairdaabed22012-08-15 15:38:57 -0700987 self.fake_gerrit.addEvent(e)
988 self.waitUntilSettled()
989
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400990 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400991 self.assertEqual(len(self.history), 1)
992 self.assertIn('project-post', job_names)
James E. Blairc6294a52012-08-17 10:19:48 -0700993
K Jonathan Harkerf95e7232015-04-29 13:33:16 -0700994 def test_post_ignore_deletes(self):
995 "Test that deleting refs does not trigger post jobs"
996
997 e = {
998 "type": "ref-updated",
999 "submitter": {
1000 "name": "User Name",
1001 },
1002 "refUpdate": {
1003 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
1004 "newRev": "0000000000000000000000000000000000000000",
1005 "refName": "master",
1006 "project": "org/project",
1007 }
1008 }
1009 self.fake_gerrit.addEvent(e)
1010 self.waitUntilSettled()
1011
1012 job_names = [x.name for x in self.history]
1013 self.assertEqual(len(self.history), 0)
1014 self.assertNotIn('project-post', job_names)
1015
1016 def test_post_ignore_deletes_negative(self):
1017 "Test that deleting refs does trigger post jobs"
1018
Adam Gandelmanc5e4f1d2016-11-29 14:27:17 -08001019 self.updateConfigLayout('layout-dont-ignore-ref-deletes')
K Jonathan Harkerf95e7232015-04-29 13:33:16 -07001020 self.sched.reconfigure(self.config)
1021
1022 e = {
1023 "type": "ref-updated",
1024 "submitter": {
1025 "name": "User Name",
1026 },
1027 "refUpdate": {
1028 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
1029 "newRev": "0000000000000000000000000000000000000000",
1030 "refName": "master",
1031 "project": "org/project",
1032 }
1033 }
1034 self.fake_gerrit.addEvent(e)
1035 self.waitUntilSettled()
1036
1037 job_names = [x.name for x in self.history]
1038 self.assertEqual(len(self.history), 1)
1039 self.assertIn('project-post', job_names)
1040
James E. Blairec056492016-07-22 09:45:56 -07001041 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001042 def test_build_configuration_branch(self):
1043 "Test that the right commits are on alternate branches"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001044
1045 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -07001046 A = self.fake_gerrit.addFakeChange('org/project', 'mp', 'A')
1047 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
1048 C = self.fake_gerrit.addFakeChange('org/project', 'mp', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07001049 A.addApproval('code-review', 2)
1050 B.addApproval('code-review', 2)
1051 C.addApproval('code-review', 2)
1052 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1053 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1054 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blairc6294a52012-08-17 10:19:48 -07001055 self.waitUntilSettled()
1056
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001057 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001058 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001059 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001060 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001061 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001062 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001063 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001064 ref = self.getParameter(queue[-1], 'ZUUL_REF')
1065 self.gearman_server.hold_jobs_in_queue = False
1066 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -07001067 self.waitUntilSettled()
1068
Monty Taylorbc758832013-06-17 17:22:42 -04001069 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001070 repo = git.Repo(path)
1071 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
1072 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001073 correct_messages = ['initial commit', 'mp commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001074 self.assertEqual(repo_messages, correct_messages)
James E. Blairc6294a52012-08-17 10:19:48 -07001075
James E. Blairec056492016-07-22 09:45:56 -07001076 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001077 def test_build_configuration_branch_interaction(self):
1078 "Test that switching between branches works"
1079 self.test_build_configuration()
1080 self.test_build_configuration_branch()
1081 # C has been merged, undo that
Monty Taylorbc758832013-06-17 17:22:42 -04001082 path = os.path.join(self.upstream_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001083 repo = git.Repo(path)
1084 repo.heads.master.commit = repo.commit('init')
1085 self.test_build_configuration()
1086
James E. Blairec056492016-07-22 09:45:56 -07001087 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001088 def test_build_configuration_multi_branch(self):
1089 "Test that dependent changes on multiple branches are merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001090
1091 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -07001092 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1093 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
1094 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07001095 A.addApproval('code-review', 2)
1096 B.addApproval('code-review', 2)
1097 C.addApproval('code-review', 2)
1098 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1099 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1100 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blairc6294a52012-08-17 10:19:48 -07001101 self.waitUntilSettled()
James E. Blairbb1fe502014-03-04 10:15:06 -08001102 queue = self.gearman_server.getQueue()
1103 job_A = None
1104 for job in queue:
1105 if 'project-merge' in job.name:
1106 job_A = job
1107 ref_A = self.getParameter(job_A, 'ZUUL_REF')
1108 commit_A = self.getParameter(job_A, 'ZUUL_COMMIT')
1109 self.log.debug("Got Zuul ref for change A: %s" % ref_A)
1110 self.log.debug("Got Zuul commit for change A: %s" % commit_A)
James E. Blairc6294a52012-08-17 10:19:48 -07001111
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001112 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001113 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001114 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -07001115 job_B = None
1116 for job in queue:
1117 if 'project-merge' in job.name:
1118 job_B = job
1119 ref_B = self.getParameter(job_B, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -08001120 commit_B = self.getParameter(job_B, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -07001121 self.log.debug("Got Zuul ref for change B: %s" % ref_B)
James E. Blairbb1fe502014-03-04 10:15:06 -08001122 self.log.debug("Got Zuul commit for change B: %s" % commit_B)
1123
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001124 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001125 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001126 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -07001127 for job in queue:
1128 if 'project-merge' in job.name:
1129 job_C = job
1130 ref_C = self.getParameter(job_C, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -08001131 commit_C = self.getParameter(job_C, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -07001132 self.log.debug("Got Zuul ref for change C: %s" % ref_C)
James E. Blairbb1fe502014-03-04 10:15:06 -08001133 self.log.debug("Got Zuul commit for change C: %s" % commit_C)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001134 self.gearman_server.hold_jobs_in_queue = False
1135 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -07001136 self.waitUntilSettled()
1137
Monty Taylorbc758832013-06-17 17:22:42 -04001138 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001139 repo = git.Repo(path)
1140
1141 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -07001142 for c in repo.iter_commits(ref_C)]
James E. Blairbb1fe502014-03-04 10:15:06 -08001143 repo_shas = [c.hexsha for c in repo.iter_commits(ref_C)]
James E. Blairc6294a52012-08-17 10:19:48 -07001144 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001145 correct_messages = ['initial commit', 'A-1', 'C-1']
James E. Blairbb1fe502014-03-04 10:15:06 -08001146 # Ensure the right commits are in the history for this ref
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001147 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -08001148 # Ensure ZUUL_REF -> ZUUL_COMMIT
1149 self.assertEqual(repo_shas[0], commit_C)
James E. Blairc6294a52012-08-17 10:19:48 -07001150
1151 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -07001152 for c in repo.iter_commits(ref_B)]
James E. Blairbb1fe502014-03-04 10:15:06 -08001153 repo_shas = [c.hexsha for c in repo.iter_commits(ref_B)]
James E. Blairc6294a52012-08-17 10:19:48 -07001154 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001155 correct_messages = ['initial commit', 'mp commit', 'B-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001156 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -08001157 self.assertEqual(repo_shas[0], commit_B)
1158
1159 repo_messages = [c.message.strip()
1160 for c in repo.iter_commits(ref_A)]
1161 repo_shas = [c.hexsha for c in repo.iter_commits(ref_A)]
1162 repo_messages.reverse()
1163 correct_messages = ['initial commit', 'A-1']
1164 self.assertEqual(repo_messages, correct_messages)
1165 self.assertEqual(repo_shas[0], commit_A)
1166
1167 self.assertNotEqual(ref_A, ref_B, ref_C)
1168 self.assertNotEqual(commit_A, commit_B, commit_C)
James E. Blair7f71c802012-08-22 13:04:32 -07001169
James E. Blaircaec0c52012-08-22 14:52:22 -07001170 def test_dependent_changes_dequeue(self):
1171 "Test that dependent patches are not needlessly tested"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001172
James E. Blaircaec0c52012-08-22 14:52:22 -07001173 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1174 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1175 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07001176 A.addApproval('code-review', 2)
1177 B.addApproval('code-review', 2)
1178 C.addApproval('code-review', 2)
James E. Blaircaec0c52012-08-22 14:52:22 -07001179
1180 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
1181 M1.setMerged()
1182
1183 # C -> B -> A -> M1
1184
1185 C.setDependsOn(B, 1)
1186 B.setDependsOn(A, 1)
1187 A.setDependsOn(M1, 1)
1188
James E. Blair08d19992016-08-10 15:25:31 -07001189 self.launch_server.failJob('project-merge', A)
James E. Blaircaec0c52012-08-22 14:52:22 -07001190
James E. Blair8b5408c2016-08-08 15:37:46 -07001191 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
1192 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1193 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blaircaec0c52012-08-22 14:52:22 -07001194
1195 self.waitUntilSettled()
1196
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001197 self.assertEqual(A.data['status'], 'NEW')
1198 self.assertEqual(A.reported, 2)
1199 self.assertEqual(B.data['status'], 'NEW')
1200 self.assertEqual(B.reported, 2)
1201 self.assertEqual(C.data['status'], 'NEW')
1202 self.assertEqual(C.reported, 2)
1203 self.assertEqual(len(self.history), 1)
James E. Blairec590122012-08-22 15:19:31 -07001204
James E. Blair972e3c72013-08-29 12:04:55 -07001205 def test_failing_dependent_changes(self):
1206 "Test that failing dependent patches are taken out of stream"
James E. Blair08d19992016-08-10 15:25:31 -07001207 self.launch_server.hold_jobs_in_build = True
James E. Blair972e3c72013-08-29 12:04:55 -07001208 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1209 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1210 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1211 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1212 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
James E. Blair8b5408c2016-08-08 15:37:46 -07001213 A.addApproval('code-review', 2)
1214 B.addApproval('code-review', 2)
1215 C.addApproval('code-review', 2)
1216 D.addApproval('code-review', 2)
1217 E.addApproval('code-review', 2)
James E. Blair972e3c72013-08-29 12:04:55 -07001218
1219 # E, D -> C -> B, A
1220
1221 D.setDependsOn(C, 1)
1222 C.setDependsOn(B, 1)
1223
James E. Blair08d19992016-08-10 15:25:31 -07001224 self.launch_server.failJob('project-test1', B)
James E. Blair972e3c72013-08-29 12:04:55 -07001225
James E. Blair8b5408c2016-08-08 15:37:46 -07001226 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1227 self.fake_gerrit.addEvent(D.addApproval('approved', 1))
1228 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
1229 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1230 self.fake_gerrit.addEvent(E.addApproval('approved', 1))
James E. Blair972e3c72013-08-29 12:04:55 -07001231
1232 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001233 self.launch_server.release('.*-merge')
James E. Blair972e3c72013-08-29 12:04:55 -07001234 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001235 self.launch_server.release('.*-merge')
James E. Blair972e3c72013-08-29 12:04:55 -07001236 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001237 self.launch_server.release('.*-merge')
James E. Blair972e3c72013-08-29 12:04:55 -07001238 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001239 self.launch_server.release('.*-merge')
James E. Blair972e3c72013-08-29 12:04:55 -07001240 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001241 self.launch_server.release('.*-merge')
James E. Blair972e3c72013-08-29 12:04:55 -07001242 self.waitUntilSettled()
1243
James E. Blair08d19992016-08-10 15:25:31 -07001244 self.launch_server.hold_jobs_in_build = False
James E. Blair972e3c72013-08-29 12:04:55 -07001245 for build in self.builds:
1246 if build.parameters['ZUUL_CHANGE'] != '1':
1247 build.release()
1248 self.waitUntilSettled()
1249
James E. Blair08d19992016-08-10 15:25:31 -07001250 self.launch_server.release()
James E. Blair972e3c72013-08-29 12:04:55 -07001251 self.waitUntilSettled()
1252
1253 self.assertEqual(A.data['status'], 'MERGED')
1254 self.assertEqual(A.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001255 self.assertIn('Build succeeded', A.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001256 self.assertEqual(B.data['status'], 'NEW')
1257 self.assertEqual(B.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001258 self.assertIn('Build failed', B.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001259 self.assertEqual(C.data['status'], 'NEW')
1260 self.assertEqual(C.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001261 self.assertIn('depends on a change', C.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001262 self.assertEqual(D.data['status'], 'NEW')
1263 self.assertEqual(D.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001264 self.assertIn('depends on a change', D.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001265 self.assertEqual(E.data['status'], 'MERGED')
1266 self.assertEqual(E.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001267 self.assertIn('Build succeeded', E.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001268 self.assertEqual(len(self.history), 18)
1269
James E. Blairec590122012-08-22 15:19:31 -07001270 def test_head_is_dequeued_once(self):
James E. Blair2fa50962013-01-30 21:50:41 -08001271 "Test that if a change at the head fails it is dequeued only once"
James E. Blairec590122012-08-22 15:19:31 -07001272 # If it's dequeued more than once, we should see extra
1273 # aborted jobs.
James E. Blairec590122012-08-22 15:19:31 -07001274
James E. Blair08d19992016-08-10 15:25:31 -07001275 self.launch_server.hold_jobs_in_build = True
James E. Blairec590122012-08-22 15:19:31 -07001276 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1277 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1278 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07001279 A.addApproval('code-review', 2)
1280 B.addApproval('code-review', 2)
1281 C.addApproval('code-review', 2)
James E. Blairec590122012-08-22 15:19:31 -07001282
Paul Belanger58bf6912016-11-11 19:36:01 -05001283 self.launch_server.failJob('project-test1', A)
1284 self.launch_server.failJob('project-test2', A)
James E. Blair08d19992016-08-10 15:25:31 -07001285 self.launch_server.failJob('project1-project2-integration', A)
James E. Blairec590122012-08-22 15:19:31 -07001286
James E. Blair8b5408c2016-08-08 15:37:46 -07001287 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1288 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1289 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blairec590122012-08-22 15:19:31 -07001290
1291 self.waitUntilSettled()
James E. Blairec590122012-08-22 15:19:31 -07001292
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001293 self.assertEqual(len(self.builds), 1)
Paul Belanger58bf6912016-11-11 19:36:01 -05001294 self.assertEqual(self.builds[0].name, 'project-merge')
1295 self.assertTrue(self.builds[0].hasChanges(A))
James E. Blairec590122012-08-22 15:19:31 -07001296
James E. Blair08d19992016-08-10 15:25:31 -07001297 self.launch_server.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001298 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001299 self.launch_server.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001300 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001301 self.launch_server.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001302 self.waitUntilSettled()
1303
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001304 self.assertEqual(len(self.builds), 9)
Paul Belanger58bf6912016-11-11 19:36:01 -05001305 self.assertEqual(self.builds[0].name, 'project-test1')
1306 self.assertEqual(self.builds[1].name, 'project-test2')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001307 self.assertEqual(self.builds[2].name, 'project1-project2-integration')
Paul Belanger58bf6912016-11-11 19:36:01 -05001308 self.assertEqual(self.builds[3].name, 'project-test1')
1309 self.assertEqual(self.builds[4].name, 'project-test2')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001310 self.assertEqual(self.builds[5].name, 'project1-project2-integration')
Paul Belanger58bf6912016-11-11 19:36:01 -05001311 self.assertEqual(self.builds[6].name, 'project-test1')
1312 self.assertEqual(self.builds[7].name, 'project-test2')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001313 self.assertEqual(self.builds[8].name, 'project1-project2-integration')
James E. Blairec590122012-08-22 15:19:31 -07001314
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001315 self.release(self.builds[0])
James E. Blairec590122012-08-22 15:19:31 -07001316 self.waitUntilSettled()
1317
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001318 self.assertEqual(len(self.builds), 3) # test2,integration, merge for B
1319 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 6)
James E. Blairec590122012-08-22 15:19:31 -07001320
James E. Blair08d19992016-08-10 15:25:31 -07001321 self.launch_server.hold_jobs_in_build = False
1322 self.launch_server.release()
James E. Blairec590122012-08-22 15:19:31 -07001323 self.waitUntilSettled()
1324
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001325 self.assertEqual(len(self.builds), 0)
1326 self.assertEqual(len(self.history), 20)
James E. Blaircaec0c52012-08-22 14:52:22 -07001327
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001328 self.assertEqual(A.data['status'], 'NEW')
1329 self.assertEqual(B.data['status'], 'MERGED')
1330 self.assertEqual(C.data['status'], 'MERGED')
1331 self.assertEqual(A.reported, 2)
1332 self.assertEqual(B.reported, 2)
1333 self.assertEqual(C.reported, 2)
James E. Blair4ec821f2012-08-23 15:28:28 -07001334
James E. Blairec056492016-07-22 09:45:56 -07001335 @skip("Disabled for early v3 development")
James E. Blair4ec821f2012-08-23 15:28:28 -07001336 def test_nonvoting_job(self):
1337 "Test that non-voting jobs don't vote."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001338
James E. Blair4ec821f2012-08-23 15:28:28 -07001339 A = self.fake_gerrit.addFakeChange('org/nonvoting-project',
1340 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001341 A.addApproval('code-review', 2)
James E. Blair08d19992016-08-10 15:25:31 -07001342 self.launch_server.failJob('nonvoting-project-test2', A)
James E. Blair8b5408c2016-08-08 15:37:46 -07001343 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair4ec821f2012-08-23 15:28:28 -07001344
1345 self.waitUntilSettled()
James E. Blair4ec821f2012-08-23 15:28:28 -07001346
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001347 self.assertEqual(A.data['status'], 'MERGED')
1348 self.assertEqual(A.reported, 2)
1349 self.assertEqual(
1350 self.getJobFromHistory('nonvoting-project-merge').result,
1351 'SUCCESS')
1352 self.assertEqual(
1353 self.getJobFromHistory('nonvoting-project-test1').result,
1354 'SUCCESS')
1355 self.assertEqual(
1356 self.getJobFromHistory('nonvoting-project-test2').result,
1357 'FAILURE')
James E. Blaire0487072012-08-29 17:38:31 -07001358
James E. Blair5821bd92015-09-16 08:48:15 -07001359 for build in self.builds:
1360 self.assertEqual(build.parameters['ZUUL_VOTING'], '0')
1361
James E. Blaire0487072012-08-29 17:38:31 -07001362 def test_check_queue_success(self):
1363 "Test successful check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001364
James E. Blaire0487072012-08-29 17:38:31 -07001365 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1366 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1367
1368 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001369
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001370 self.assertEqual(A.data['status'], 'NEW')
1371 self.assertEqual(A.reported, 1)
1372 self.assertEqual(self.getJobFromHistory('project-merge').result,
1373 'SUCCESS')
1374 self.assertEqual(self.getJobFromHistory('project-test1').result,
1375 'SUCCESS')
1376 self.assertEqual(self.getJobFromHistory('project-test2').result,
1377 'SUCCESS')
James E. Blaire0487072012-08-29 17:38:31 -07001378
1379 def test_check_queue_failure(self):
1380 "Test failed check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001381
James E. Blaire0487072012-08-29 17:38:31 -07001382 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair08d19992016-08-10 15:25:31 -07001383 self.launch_server.failJob('project-test2', A)
James E. Blaire0487072012-08-29 17:38:31 -07001384 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1385
1386 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001387
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001388 self.assertEqual(A.data['status'], 'NEW')
1389 self.assertEqual(A.reported, 1)
1390 self.assertEqual(self.getJobFromHistory('project-merge').result,
James E. Blair78e31b32013-07-09 09:11:34 -07001391 'SUCCESS')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001392 self.assertEqual(self.getJobFromHistory('project-test1').result,
1393 'SUCCESS')
1394 self.assertEqual(self.getJobFromHistory('project-test2').result,
1395 'FAILURE')
James E. Blair127bc182012-08-28 15:55:15 -07001396
James E. Blairec056492016-07-22 09:45:56 -07001397 @skip("Disabled for early v3 development")
James E. Blair127bc182012-08-28 15:55:15 -07001398 def test_dependent_behind_dequeue(self):
1399 "test that dependent changes behind dequeued changes work"
1400 # This complicated test is a reproduction of a real life bug
1401 self.sched.reconfigure(self.config)
James E. Blair127bc182012-08-28 15:55:15 -07001402
James E. Blair08d19992016-08-10 15:25:31 -07001403 self.launch_server.hold_jobs_in_build = True
James E. Blair127bc182012-08-28 15:55:15 -07001404 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1405 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1406 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
1407 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
1408 E = self.fake_gerrit.addFakeChange('org/project2', 'master', 'E')
1409 F = self.fake_gerrit.addFakeChange('org/project3', 'master', 'F')
1410 D.setDependsOn(C, 1)
1411 E.setDependsOn(D, 1)
James E. Blair8b5408c2016-08-08 15:37:46 -07001412 A.addApproval('code-review', 2)
1413 B.addApproval('code-review', 2)
1414 C.addApproval('code-review', 2)
1415 D.addApproval('code-review', 2)
1416 E.addApproval('code-review', 2)
1417 F.addApproval('code-review', 2)
James E. Blair127bc182012-08-28 15:55:15 -07001418
1419 A.fail_merge = True
James E. Blair127bc182012-08-28 15:55:15 -07001420
1421 # Change object re-use in the gerrit trigger is hidden if
1422 # changes are added in quick succession; waiting makes it more
1423 # like real life.
James E. Blair8b5408c2016-08-08 15:37:46 -07001424 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001425 self.waitUntilSettled()
James E. Blair8b5408c2016-08-08 15:37:46 -07001426 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001427 self.waitUntilSettled()
1428
James E. Blair08d19992016-08-10 15:25:31 -07001429 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001430 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001431 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001432 self.waitUntilSettled()
1433
James E. Blair8b5408c2016-08-08 15:37:46 -07001434 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001435 self.waitUntilSettled()
James E. Blair8b5408c2016-08-08 15:37:46 -07001436 self.fake_gerrit.addEvent(D.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001437 self.waitUntilSettled()
James E. Blair8b5408c2016-08-08 15:37:46 -07001438 self.fake_gerrit.addEvent(E.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001439 self.waitUntilSettled()
James E. Blair8b5408c2016-08-08 15:37:46 -07001440 self.fake_gerrit.addEvent(F.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001441 self.waitUntilSettled()
1442
James E. Blair08d19992016-08-10 15:25:31 -07001443 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001444 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001445 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001446 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001447 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001448 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001449 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001450 self.waitUntilSettled()
1451
1452 # all jobs running
James E. Blaire955e062012-10-08 09:49:03 -07001453
1454 # Grab pointers to the jobs we want to release before
1455 # releasing any, because list indexes may change as
1456 # the jobs complete.
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001457 a, b, c = self.builds[:3]
James E. Blaire955e062012-10-08 09:49:03 -07001458 a.release()
1459 b.release()
1460 c.release()
James E. Blair127bc182012-08-28 15:55:15 -07001461 self.waitUntilSettled()
1462
James E. Blair08d19992016-08-10 15:25:31 -07001463 self.launch_server.hold_jobs_in_build = False
1464 self.launch_server.release()
James E. Blair127bc182012-08-28 15:55:15 -07001465 self.waitUntilSettled()
1466
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001467 self.assertEqual(A.data['status'], 'NEW')
1468 self.assertEqual(B.data['status'], 'MERGED')
1469 self.assertEqual(C.data['status'], 'MERGED')
1470 self.assertEqual(D.data['status'], 'MERGED')
1471 self.assertEqual(E.data['status'], 'MERGED')
1472 self.assertEqual(F.data['status'], 'MERGED')
James E. Blair127bc182012-08-28 15:55:15 -07001473
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001474 self.assertEqual(A.reported, 2)
1475 self.assertEqual(B.reported, 2)
1476 self.assertEqual(C.reported, 2)
1477 self.assertEqual(D.reported, 2)
1478 self.assertEqual(E.reported, 2)
1479 self.assertEqual(F.reported, 2)
James E. Blair127bc182012-08-28 15:55:15 -07001480
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001481 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 15)
1482 self.assertEqual(len(self.history), 44)
James E. Blair05fed602012-09-07 12:45:24 -07001483
1484 def test_merger_repack(self):
1485 "Test that the merger works after a repack"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001486
James E. Blair05fed602012-09-07 12:45:24 -07001487 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001488 A.addApproval('code-review', 2)
1489 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair05fed602012-09-07 12:45:24 -07001490 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001491 self.assertEqual(self.getJobFromHistory('project-merge').result,
1492 'SUCCESS')
1493 self.assertEqual(self.getJobFromHistory('project-test1').result,
1494 'SUCCESS')
1495 self.assertEqual(self.getJobFromHistory('project-test2').result,
1496 'SUCCESS')
1497 self.assertEqual(A.data['status'], 'MERGED')
1498 self.assertEqual(A.reported, 2)
James E. Blair05fed602012-09-07 12:45:24 -07001499 self.assertEmptyQueues()
Paul Belanger5bfe9e72016-11-04 19:20:04 -04001500 self.build_history = []
James E. Blair05fed602012-09-07 12:45:24 -07001501
Monty Taylorbc758832013-06-17 17:22:42 -04001502 path = os.path.join(self.git_root, "org/project")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001503 print(repack_repo(path))
James E. Blair05fed602012-09-07 12:45:24 -07001504
1505 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001506 A.addApproval('code-review', 2)
1507 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair05fed602012-09-07 12:45:24 -07001508 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001509 self.assertEqual(self.getJobFromHistory('project-merge').result,
1510 'SUCCESS')
1511 self.assertEqual(self.getJobFromHistory('project-test1').result,
1512 'SUCCESS')
1513 self.assertEqual(self.getJobFromHistory('project-test2').result,
1514 'SUCCESS')
1515 self.assertEqual(A.data['status'], 'MERGED')
1516 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001517
James E. Blair4886f282012-11-15 09:27:33 -08001518 def test_merger_repack_large_change(self):
1519 "Test that the merger works with large changes after a repack"
1520 # https://bugs.launchpad.net/zuul/+bug/1078946
James E. Blairac2c3242014-01-24 13:38:51 -08001521 # This test assumes the repo is already cloned; make sure it is
Paul Belanger503bded2016-11-11 19:43:38 -05001522 tenant = self.sched.abide.tenants.get('tenant-one')
Joshua Hesketh352264b2015-08-11 23:42:08 +10001523 url = self.fake_gerrit.getGitUrl(
Paul Belanger503bded2016-11-11 19:43:38 -05001524 tenant.layout.project_configs.get('org/project1'))
James E. Blair4076e2b2014-01-28 12:42:20 -08001525 self.merge_server.merger.addProject('org/project1', url)
James E. Blair4886f282012-11-15 09:27:33 -08001526 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1527 A.addPatchset(large=True)
Monty Taylorbc758832013-06-17 17:22:42 -04001528 path = os.path.join(self.upstream_root, "org/project1")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001529 print(repack_repo(path))
Monty Taylorbc758832013-06-17 17:22:42 -04001530 path = os.path.join(self.git_root, "org/project1")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001531 print(repack_repo(path))
James E. Blair4886f282012-11-15 09:27:33 -08001532
James E. Blair8b5408c2016-08-08 15:37:46 -07001533 A.addApproval('code-review', 2)
1534 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair4886f282012-11-15 09:27:33 -08001535 self.waitUntilSettled()
Paul Belanger503bded2016-11-11 19:43:38 -05001536 self.assertEqual(self.getJobFromHistory('project-merge').result,
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001537 'SUCCESS')
Paul Belanger503bded2016-11-11 19:43:38 -05001538 self.assertEqual(self.getJobFromHistory('project-test1').result,
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001539 'SUCCESS')
Paul Belanger503bded2016-11-11 19:43:38 -05001540 self.assertEqual(self.getJobFromHistory('project-test2').result,
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001541 'SUCCESS')
1542 self.assertEqual(A.data['status'], 'MERGED')
1543 self.assertEqual(A.reported, 2)
James E. Blair4886f282012-11-15 09:27:33 -08001544
James E. Blairec056492016-07-22 09:45:56 -07001545 @skip("Disabled for early v3 development")
James E. Blair7ee88a22012-09-12 18:59:31 +02001546 def test_nonexistent_job(self):
1547 "Test launching a job that doesn't exist"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001548 # Set to the state immediately after a restart
1549 self.resetGearmanServer()
1550 self.launcher.negative_function_cache_ttl = 0
James E. Blair7ee88a22012-09-12 18:59:31 +02001551
1552 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001553 A.addApproval('code-review', 2)
1554 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair7ee88a22012-09-12 18:59:31 +02001555 # There may be a thread about to report a lost change
1556 while A.reported < 2:
1557 self.waitUntilSettled()
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001558 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001559 self.assertFalse(job_names)
1560 self.assertEqual(A.data['status'], 'NEW')
1561 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001562 self.assertEmptyQueues()
1563
1564 # Make sure things still work:
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001565 self.registerJobs()
James E. Blair7ee88a22012-09-12 18:59:31 +02001566 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001567 A.addApproval('code-review', 2)
1568 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair7ee88a22012-09-12 18:59:31 +02001569 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001570 self.assertEqual(self.getJobFromHistory('project-merge').result,
1571 'SUCCESS')
1572 self.assertEqual(self.getJobFromHistory('project-test1').result,
1573 'SUCCESS')
1574 self.assertEqual(self.getJobFromHistory('project-test2').result,
1575 'SUCCESS')
1576 self.assertEqual(A.data['status'], 'MERGED')
1577 self.assertEqual(A.reported, 2)
James E. Blairf62d4282012-12-31 17:01:50 -08001578
James E. Blair2fa50962013-01-30 21:50:41 -08001579 def test_new_patchset_dequeues_old(self):
1580 "Test that a new patchset causes the old to be dequeued"
1581 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair08d19992016-08-10 15:25:31 -07001582 self.launch_server.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001583 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1584 M.setMerged()
1585
1586 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1587 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1588 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1589 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
James E. Blair8b5408c2016-08-08 15:37:46 -07001590 A.addApproval('code-review', 2)
1591 B.addApproval('code-review', 2)
1592 C.addApproval('code-review', 2)
1593 D.addApproval('code-review', 2)
James E. Blair2fa50962013-01-30 21:50:41 -08001594
1595 C.setDependsOn(B, 1)
1596 B.setDependsOn(A, 1)
1597 A.setDependsOn(M, 1)
1598
James E. Blair8b5408c2016-08-08 15:37:46 -07001599 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1600 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1601 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
1602 self.fake_gerrit.addEvent(D.addApproval('approved', 1))
James E. Blair2fa50962013-01-30 21:50:41 -08001603 self.waitUntilSettled()
1604
1605 B.addPatchset()
1606 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1607 self.waitUntilSettled()
1608
James E. Blair08d19992016-08-10 15:25:31 -07001609 self.launch_server.hold_jobs_in_build = False
1610 self.launch_server.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001611 self.waitUntilSettled()
1612
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001613 self.assertEqual(A.data['status'], 'MERGED')
1614 self.assertEqual(A.reported, 2)
1615 self.assertEqual(B.data['status'], 'NEW')
1616 self.assertEqual(B.reported, 2)
1617 self.assertEqual(C.data['status'], 'NEW')
1618 self.assertEqual(C.reported, 2)
1619 self.assertEqual(D.data['status'], 'MERGED')
1620 self.assertEqual(D.reported, 2)
1621 self.assertEqual(len(self.history), 9) # 3 each for A, B, D.
James E. Blair2fa50962013-01-30 21:50:41 -08001622
James E. Blairba437362015-02-07 11:41:52 -08001623 def test_new_patchset_check(self):
1624 "Test a new patchset in check"
Antoine Mussobd86a312014-01-08 14:51:33 +01001625
James E. Blair08d19992016-08-10 15:25:31 -07001626 self.launch_server.hold_jobs_in_build = True
Antoine Mussobd86a312014-01-08 14:51:33 +01001627
1628 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairba437362015-02-07 11:41:52 -08001629 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
Paul Belanger18e5f632016-11-03 15:24:16 -04001630 tenant = self.sched.abide.tenants.get('tenant-one')
1631 check_pipeline = tenant.layout.pipelines['check']
James E. Blairba437362015-02-07 11:41:52 -08001632
1633 # Add two git-dependent changes
1634 B.setDependsOn(A, 1)
1635 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1636 self.waitUntilSettled()
Antoine Mussobd86a312014-01-08 14:51:33 +01001637 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1638 self.waitUntilSettled()
James E. Blairba437362015-02-07 11:41:52 -08001639
1640 # A live item, and a non-live/live pair
1641 items = check_pipeline.getAllItems()
1642 self.assertEqual(len(items), 3)
1643
1644 self.assertEqual(items[0].change.number, '1')
1645 self.assertEqual(items[0].change.patchset, '1')
1646 self.assertFalse(items[0].live)
1647
1648 self.assertEqual(items[1].change.number, '2')
1649 self.assertEqual(items[1].change.patchset, '1')
1650 self.assertTrue(items[1].live)
1651
1652 self.assertEqual(items[2].change.number, '1')
1653 self.assertEqual(items[2].change.patchset, '1')
1654 self.assertTrue(items[2].live)
1655
1656 # Add a new patchset to A
1657 A.addPatchset()
1658 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1659 self.waitUntilSettled()
1660
1661 # The live copy of A,1 should be gone, but the non-live and B
1662 # should continue, and we should have a new A,2
1663 items = check_pipeline.getAllItems()
1664 self.assertEqual(len(items), 3)
1665
1666 self.assertEqual(items[0].change.number, '1')
1667 self.assertEqual(items[0].change.patchset, '1')
1668 self.assertFalse(items[0].live)
1669
1670 self.assertEqual(items[1].change.number, '2')
1671 self.assertEqual(items[1].change.patchset, '1')
1672 self.assertTrue(items[1].live)
1673
1674 self.assertEqual(items[2].change.number, '1')
1675 self.assertEqual(items[2].change.patchset, '2')
1676 self.assertTrue(items[2].live)
1677
1678 # Add a new patchset to B
1679 B.addPatchset()
1680 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1681 self.waitUntilSettled()
1682
1683 # The live copy of B,1 should be gone, and it's non-live copy of A,1
1684 # but we should have a new B,2 (still based on A,1)
1685 items = check_pipeline.getAllItems()
1686 self.assertEqual(len(items), 3)
1687
1688 self.assertEqual(items[0].change.number, '1')
1689 self.assertEqual(items[0].change.patchset, '2')
1690 self.assertTrue(items[0].live)
1691
1692 self.assertEqual(items[1].change.number, '1')
1693 self.assertEqual(items[1].change.patchset, '1')
1694 self.assertFalse(items[1].live)
1695
1696 self.assertEqual(items[2].change.number, '2')
1697 self.assertEqual(items[2].change.patchset, '2')
1698 self.assertTrue(items[2].live)
1699
1700 self.builds[0].release()
1701 self.waitUntilSettled()
1702 self.builds[0].release()
1703 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001704 self.launch_server.hold_jobs_in_build = False
1705 self.launch_server.release()
James E. Blairba437362015-02-07 11:41:52 -08001706 self.waitUntilSettled()
1707
1708 self.assertEqual(A.reported, 1)
1709 self.assertEqual(B.reported, 1)
1710 self.assertEqual(self.history[0].result, 'ABORTED')
1711 self.assertEqual(self.history[0].changes, '1,1')
1712 self.assertEqual(self.history[1].result, 'ABORTED')
1713 self.assertEqual(self.history[1].changes, '1,1 2,1')
1714 self.assertEqual(self.history[2].result, 'SUCCESS')
1715 self.assertEqual(self.history[2].changes, '1,2')
1716 self.assertEqual(self.history[3].result, 'SUCCESS')
1717 self.assertEqual(self.history[3].changes, '1,1 2,2')
1718
1719 def test_abandoned_gate(self):
1720 "Test that an abandoned change is dequeued from gate"
1721
James E. Blair08d19992016-08-10 15:25:31 -07001722 self.launch_server.hold_jobs_in_build = True
James E. Blairba437362015-02-07 11:41:52 -08001723
1724 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001725 A.addApproval('code-review', 2)
1726 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blairba437362015-02-07 11:41:52 -08001727 self.waitUntilSettled()
Antoine Mussobd86a312014-01-08 14:51:33 +01001728 self.assertEqual(len(self.builds), 1, "One job being built (on hold)")
1729 self.assertEqual(self.builds[0].name, 'project-merge')
1730
1731 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1732 self.waitUntilSettled()
1733
James E. Blair08d19992016-08-10 15:25:31 -07001734 self.launch_server.release('.*-merge')
Antoine Mussobd86a312014-01-08 14:51:33 +01001735 self.waitUntilSettled()
1736
Arie5b4048c2016-10-05 16:12:06 +03001737 self.assertBuilds([])
1738 self.assertHistory([
1739 dict(name='project-merge', result='ABORTED', changes='1,1')],
1740 ordered=False)
James E. Blairba437362015-02-07 11:41:52 -08001741 self.assertEqual(A.reported, 1,
1742 "Abandoned gate change should report only start")
1743
1744 def test_abandoned_check(self):
1745 "Test that an abandoned change is dequeued from check"
1746
James E. Blair08d19992016-08-10 15:25:31 -07001747 self.launch_server.hold_jobs_in_build = True
James E. Blairba437362015-02-07 11:41:52 -08001748
1749 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1750 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
Paul Belanger18e5f632016-11-03 15:24:16 -04001751 tenant = self.sched.abide.tenants.get('tenant-one')
1752 check_pipeline = tenant.layout.pipelines['check']
James E. Blairba437362015-02-07 11:41:52 -08001753
1754 # Add two git-dependent changes
1755 B.setDependsOn(A, 1)
1756 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1757 self.waitUntilSettled()
1758 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1759 self.waitUntilSettled()
1760 # A live item, and a non-live/live pair
1761 items = check_pipeline.getAllItems()
1762 self.assertEqual(len(items), 3)
1763
1764 self.assertEqual(items[0].change.number, '1')
1765 self.assertFalse(items[0].live)
1766
1767 self.assertEqual(items[1].change.number, '2')
1768 self.assertTrue(items[1].live)
1769
1770 self.assertEqual(items[2].change.number, '1')
1771 self.assertTrue(items[2].live)
1772
1773 # Abandon A
1774 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1775 self.waitUntilSettled()
1776
1777 # The live copy of A should be gone, but the non-live and B
1778 # should continue
1779 items = check_pipeline.getAllItems()
1780 self.assertEqual(len(items), 2)
1781
1782 self.assertEqual(items[0].change.number, '1')
1783 self.assertFalse(items[0].live)
1784
1785 self.assertEqual(items[1].change.number, '2')
1786 self.assertTrue(items[1].live)
1787
James E. Blair08d19992016-08-10 15:25:31 -07001788 self.launch_server.hold_jobs_in_build = False
1789 self.launch_server.release()
James E. Blairba437362015-02-07 11:41:52 -08001790 self.waitUntilSettled()
1791
1792 self.assertEqual(len(self.history), 4)
1793 self.assertEqual(self.history[0].result, 'ABORTED',
Antoine Mussobd86a312014-01-08 14:51:33 +01001794 'Build should have been aborted')
1795 self.assertEqual(A.reported, 0, "Abandoned change should not report")
James E. Blairba437362015-02-07 11:41:52 -08001796 self.assertEqual(B.reported, 1, "Change should report")
Antoine Mussobd86a312014-01-08 14:51:33 +01001797
James E. Blairec056492016-07-22 09:45:56 -07001798 @skip("Disabled for early v3 development")
Steve Varnau7b78b312015-04-03 14:49:46 -07001799 def test_abandoned_not_timer(self):
1800 "Test that an abandoned change does not cancel timer jobs"
1801
James E. Blair08d19992016-08-10 15:25:31 -07001802 self.launch_server.hold_jobs_in_build = True
Steve Varnau7b78b312015-04-03 14:49:46 -07001803
1804 # Start timer trigger - also org/project
James E. Blairf84026c2015-12-08 16:11:46 -08001805 self.updateConfigLayout(
1806 'tests/fixtures/layout-idle.yaml')
Steve Varnau7b78b312015-04-03 14:49:46 -07001807 self.sched.reconfigure(self.config)
1808 self.registerJobs()
1809 # The pipeline triggers every second, so we should have seen
1810 # several by now.
1811 time.sleep(5)
1812 self.waitUntilSettled()
1813 # Stop queuing timer triggered jobs so that the assertions
1814 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08001815 self.updateConfigLayout(
1816 'tests/fixtures/layout-no-timer.yaml')
Steve Varnau7b78b312015-04-03 14:49:46 -07001817 self.sched.reconfigure(self.config)
1818 self.registerJobs()
1819 self.assertEqual(len(self.builds), 2, "Two timer jobs")
1820
1821 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1822 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1823 self.waitUntilSettled()
1824 self.assertEqual(len(self.builds), 3, "One change plus two timer jobs")
1825
1826 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1827 self.waitUntilSettled()
1828
1829 self.assertEqual(len(self.builds), 2, "Two timer jobs remain")
1830
James E. Blair08d19992016-08-10 15:25:31 -07001831 self.launch_server.release()
Steve Varnau7b78b312015-04-03 14:49:46 -07001832 self.waitUntilSettled()
1833
Arx Cruzb1b010d2013-10-28 19:49:59 -02001834 def test_zuul_url_return(self):
1835 "Test if ZUUL_URL is returning when zuul_url is set in zuul.conf"
James E. Blair4076e2b2014-01-28 12:42:20 -08001836 self.assertTrue(self.sched.config.has_option('merger', 'zuul_url'))
James E. Blair08d19992016-08-10 15:25:31 -07001837 self.launch_server.hold_jobs_in_build = True
Arx Cruzb1b010d2013-10-28 19:49:59 -02001838
1839 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001840 A.addApproval('code-review', 2)
1841 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Arx Cruzb1b010d2013-10-28 19:49:59 -02001842 self.waitUntilSettled()
1843
1844 self.assertEqual(len(self.builds), 1)
1845 for build in self.builds:
1846 self.assertTrue('ZUUL_URL' in build.parameters)
1847
James E. Blair08d19992016-08-10 15:25:31 -07001848 self.launch_server.hold_jobs_in_build = False
1849 self.launch_server.release()
Arx Cruzb1b010d2013-10-28 19:49:59 -02001850 self.waitUntilSettled()
1851
James E. Blair2fa50962013-01-30 21:50:41 -08001852 def test_new_patchset_dequeues_old_on_head(self):
1853 "Test that a new patchset causes the old to be dequeued (at head)"
1854 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair08d19992016-08-10 15:25:31 -07001855 self.launch_server.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001856 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1857 M.setMerged()
1858 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1859 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1860 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1861 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
James E. Blair8b5408c2016-08-08 15:37:46 -07001862 A.addApproval('code-review', 2)
1863 B.addApproval('code-review', 2)
1864 C.addApproval('code-review', 2)
1865 D.addApproval('code-review', 2)
James E. Blair2fa50962013-01-30 21:50:41 -08001866
1867 C.setDependsOn(B, 1)
1868 B.setDependsOn(A, 1)
1869 A.setDependsOn(M, 1)
1870
James E. Blair8b5408c2016-08-08 15:37:46 -07001871 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1872 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1873 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
1874 self.fake_gerrit.addEvent(D.addApproval('approved', 1))
James E. Blair2fa50962013-01-30 21:50:41 -08001875 self.waitUntilSettled()
1876
1877 A.addPatchset()
1878 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1879 self.waitUntilSettled()
1880
James E. Blair08d19992016-08-10 15:25:31 -07001881 self.launch_server.hold_jobs_in_build = False
1882 self.launch_server.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001883 self.waitUntilSettled()
1884
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001885 self.assertEqual(A.data['status'], 'NEW')
1886 self.assertEqual(A.reported, 2)
1887 self.assertEqual(B.data['status'], 'NEW')
1888 self.assertEqual(B.reported, 2)
1889 self.assertEqual(C.data['status'], 'NEW')
1890 self.assertEqual(C.reported, 2)
1891 self.assertEqual(D.data['status'], 'MERGED')
1892 self.assertEqual(D.reported, 2)
1893 self.assertEqual(len(self.history), 7)
James E. Blair2fa50962013-01-30 21:50:41 -08001894
1895 def test_new_patchset_dequeues_old_without_dependents(self):
1896 "Test that a new patchset causes only the old to be dequeued"
James E. Blair08d19992016-08-10 15:25:31 -07001897 self.launch_server.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001898 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1899 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1900 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07001901 A.addApproval('code-review', 2)
1902 B.addApproval('code-review', 2)
1903 C.addApproval('code-review', 2)
James E. Blair2fa50962013-01-30 21:50:41 -08001904
James E. Blair8b5408c2016-08-08 15:37:46 -07001905 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
1906 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1907 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair2fa50962013-01-30 21:50:41 -08001908 self.waitUntilSettled()
1909
1910 B.addPatchset()
1911 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1912 self.waitUntilSettled()
1913
James E. Blair08d19992016-08-10 15:25:31 -07001914 self.launch_server.hold_jobs_in_build = False
1915 self.launch_server.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001916 self.waitUntilSettled()
1917
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001918 self.assertEqual(A.data['status'], 'MERGED')
1919 self.assertEqual(A.reported, 2)
1920 self.assertEqual(B.data['status'], 'NEW')
1921 self.assertEqual(B.reported, 2)
1922 self.assertEqual(C.data['status'], 'MERGED')
1923 self.assertEqual(C.reported, 2)
1924 self.assertEqual(len(self.history), 9)
James E. Blair2fa50962013-01-30 21:50:41 -08001925
1926 def test_new_patchset_dequeues_old_independent_queue(self):
1927 "Test that a new patchset causes the old to be dequeued (independent)"
James E. Blair08d19992016-08-10 15:25:31 -07001928 self.launch_server.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001929 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1930 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1931 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1932 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1933 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1934 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
1935 self.waitUntilSettled()
1936
1937 B.addPatchset()
1938 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1939 self.waitUntilSettled()
1940
James E. Blair08d19992016-08-10 15:25:31 -07001941 self.launch_server.hold_jobs_in_build = False
1942 self.launch_server.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001943 self.waitUntilSettled()
1944
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001945 self.assertEqual(A.data['status'], 'NEW')
1946 self.assertEqual(A.reported, 1)
1947 self.assertEqual(B.data['status'], 'NEW')
1948 self.assertEqual(B.reported, 1)
1949 self.assertEqual(C.data['status'], 'NEW')
1950 self.assertEqual(C.reported, 1)
1951 self.assertEqual(len(self.history), 10)
1952 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 1)
James E. Blair7d0dedc2013-02-21 17:26:09 -08001953
James E. Blair18c64442014-03-18 10:14:45 -07001954 def test_noop_job(self):
1955 "Test that the internal noop job works"
1956 A = self.fake_gerrit.addFakeChange('org/noop-project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001957 A.addApproval('code-review', 2)
1958 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair18c64442014-03-18 10:14:45 -07001959 self.waitUntilSettled()
1960
1961 self.assertEqual(len(self.gearman_server.getQueue()), 0)
1962 self.assertTrue(self.sched._areAllBuildsComplete())
1963 self.assertEqual(len(self.history), 0)
1964 self.assertEqual(A.data['status'], 'MERGED')
1965 self.assertEqual(A.reported, 2)
1966
James E. Blairec056492016-07-22 09:45:56 -07001967 @skip("Disabled for early v3 development")
Evgeny Antyshevd6e546c2015-06-11 15:13:57 +00001968 def test_no_job_project(self):
1969 "Test that reports with no jobs don't get sent"
1970 A = self.fake_gerrit.addFakeChange('org/no-jobs-project',
1971 'master', 'A')
1972 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1973 self.waitUntilSettled()
1974
1975 # Change wasn't reported to
1976 self.assertEqual(A.reported, False)
1977
1978 # Check queue is empty afterwards
1979 check_pipeline = self.sched.layout.pipelines['check']
1980 items = check_pipeline.getAllItems()
1981 self.assertEqual(len(items), 0)
1982
1983 self.assertEqual(len(self.history), 0)
1984
James E. Blair7d0dedc2013-02-21 17:26:09 -08001985 def test_zuul_refs(self):
1986 "Test that zuul refs exist and have the right changes"
James E. Blair08d19992016-08-10 15:25:31 -07001987 self.launch_server.hold_jobs_in_build = True
James E. Blair7d0dedc2013-02-21 17:26:09 -08001988 M1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'M1')
1989 M1.setMerged()
1990 M2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'M2')
1991 M2.setMerged()
1992
1993 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1994 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1995 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
1996 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
James E. Blair8b5408c2016-08-08 15:37:46 -07001997 A.addApproval('code-review', 2)
1998 B.addApproval('code-review', 2)
1999 C.addApproval('code-review', 2)
2000 D.addApproval('code-review', 2)
2001 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
2002 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
2003 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
2004 self.fake_gerrit.addEvent(D.addApproval('approved', 1))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002005
2006 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002007 self.launch_server.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002008 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002009 self.launch_server.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002010 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002011 self.launch_server.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002012 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002013 self.launch_server.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002014 self.waitUntilSettled()
2015
James E. Blair7d0dedc2013-02-21 17:26:09 -08002016 a_zref = b_zref = c_zref = d_zref = None
Clint Byrum3343e3e2016-11-15 16:05:03 -08002017 a_build = b_build = c_build = d_build = None
Monty Taylor6bef8ef2013-06-02 08:17:12 -04002018 for x in self.builds:
James E. Blair7d0dedc2013-02-21 17:26:09 -08002019 if x.parameters['ZUUL_CHANGE'] == '3':
2020 a_zref = x.parameters['ZUUL_REF']
Clint Byrum3343e3e2016-11-15 16:05:03 -08002021 a_build = x
2022 elif x.parameters['ZUUL_CHANGE'] == '4':
James E. Blair7d0dedc2013-02-21 17:26:09 -08002023 b_zref = x.parameters['ZUUL_REF']
Clint Byrum3343e3e2016-11-15 16:05:03 -08002024 b_build = x
2025 elif x.parameters['ZUUL_CHANGE'] == '5':
James E. Blair7d0dedc2013-02-21 17:26:09 -08002026 c_zref = x.parameters['ZUUL_REF']
Clint Byrum3343e3e2016-11-15 16:05:03 -08002027 c_build = x
2028 elif x.parameters['ZUUL_CHANGE'] == '6':
James E. Blair7d0dedc2013-02-21 17:26:09 -08002029 d_zref = x.parameters['ZUUL_REF']
Clint Byrum3343e3e2016-11-15 16:05:03 -08002030 d_build = x
2031 if a_build and b_build and c_build and d_build:
2032 break
James E. Blair7d0dedc2013-02-21 17:26:09 -08002033
2034 # There are... four... refs.
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002035 self.assertIsNotNone(a_zref)
2036 self.assertIsNotNone(b_zref)
2037 self.assertIsNotNone(c_zref)
2038 self.assertIsNotNone(d_zref)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002039
2040 # And they should all be different
2041 refs = set([a_zref, b_zref, c_zref, d_zref])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002042 self.assertEqual(len(refs), 4)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002043
Clint Byrum3343e3e2016-11-15 16:05:03 -08002044 # should have a, not b, and should not be in project2
2045 self.assertTrue(a_build.hasChanges(A))
2046 self.assertFalse(a_build.hasChanges(B, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002047
Clint Byrum3343e3e2016-11-15 16:05:03 -08002048 # should have a and b, and should not be in project2
2049 self.assertTrue(b_build.hasChanges(A, B))
2050 self.assertFalse(b_build.hasChanges(M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002051
Clint Byrum3343e3e2016-11-15 16:05:03 -08002052 # should have a and b in 1, c in 2
2053 self.assertTrue(c_build.hasChanges(A, B, C))
2054 self.assertFalse(c_build.hasChanges(D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002055
Clint Byrum3343e3e2016-11-15 16:05:03 -08002056 # should have a and b in 1, c and d in 2
2057 self.assertTrue(d_build.hasChanges(A, B, C, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002058
James E. Blair08d19992016-08-10 15:25:31 -07002059 self.launch_server.hold_jobs_in_build = False
2060 self.launch_server.release()
James E. Blair7d0dedc2013-02-21 17:26:09 -08002061 self.waitUntilSettled()
2062
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002063 self.assertEqual(A.data['status'], 'MERGED')
2064 self.assertEqual(A.reported, 2)
2065 self.assertEqual(B.data['status'], 'MERGED')
2066 self.assertEqual(B.reported, 2)
2067 self.assertEqual(C.data['status'], 'MERGED')
2068 self.assertEqual(C.reported, 2)
2069 self.assertEqual(D.data['status'], 'MERGED')
2070 self.assertEqual(D.reported, 2)
James E. Blair70c71582013-03-06 08:50:50 -08002071
James E. Blair4a28a882013-08-23 15:17:33 -07002072 def test_rerun_on_error(self):
2073 "Test that if a worker fails to run a job, it is run again"
James E. Blair08d19992016-08-10 15:25:31 -07002074 self.launch_server.hold_jobs_in_build = True
James E. Blair4a28a882013-08-23 15:17:33 -07002075 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07002076 A.addApproval('code-review', 2)
2077 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair4a28a882013-08-23 15:17:33 -07002078 self.waitUntilSettled()
2079
2080 self.builds[0].run_error = True
James E. Blair08d19992016-08-10 15:25:31 -07002081 self.launch_server.hold_jobs_in_build = False
2082 self.launch_server.release()
James E. Blair4a28a882013-08-23 15:17:33 -07002083 self.waitUntilSettled()
2084 self.assertEqual(self.countJobResults(self.history, 'RUN_ERROR'), 1)
2085 self.assertEqual(self.countJobResults(self.history, 'SUCCESS'), 3)
2086
James E. Blair412e5582013-04-22 15:50:12 -07002087 def test_statsd(self):
2088 "Test each of the statsd methods used in the scheduler"
2089 import extras
2090 statsd = extras.try_import('statsd.statsd')
2091 statsd.incr('test-incr')
2092 statsd.timing('test-timing', 3)
Alex Gaynor813d39b2014-05-17 16:17:16 -07002093 statsd.gauge('test-gauge', 12)
James E. Blair412e5582013-04-22 15:50:12 -07002094 self.assertReportedStat('test-incr', '1|c')
2095 self.assertReportedStat('test-timing', '3|ms')
Alex Gaynor813d39b2014-05-17 16:17:16 -07002096 self.assertReportedStat('test-gauge', '12|g')
James E. Blair412e5582013-04-22 15:50:12 -07002097
James E. Blairec056492016-07-22 09:45:56 -07002098 @skip("Disabled for early v3 development")
James E. Blairdad52252014-02-07 16:59:17 -08002099 def test_stuck_job_cleanup(self):
2100 "Test that pending jobs are cleaned up if removed from layout"
James E. Blair18c64442014-03-18 10:14:45 -07002101 # This job won't be registered at startup because it is not in
2102 # the standard layout, but we need it to already be registerd
2103 # for when we reconfigure, as that is when Zuul will attempt
2104 # to run the new job.
2105 self.worker.registerFunction('build:gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002106 self.gearman_server.hold_jobs_in_queue = True
2107 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07002108 A.addApproval('code-review', 2)
2109 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blairdad52252014-02-07 16:59:17 -08002110 self.waitUntilSettled()
2111 self.assertEqual(len(self.gearman_server.getQueue()), 1)
2112
James E. Blairf84026c2015-12-08 16:11:46 -08002113 self.updateConfigLayout(
2114 'tests/fixtures/layout-no-jobs.yaml')
James E. Blairdad52252014-02-07 16:59:17 -08002115 self.sched.reconfigure(self.config)
2116 self.waitUntilSettled()
2117
James E. Blair18c64442014-03-18 10:14:45 -07002118 self.gearman_server.release('gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002119 self.waitUntilSettled()
2120 self.assertEqual(len(self.gearman_server.getQueue()), 0)
2121 self.assertTrue(self.sched._areAllBuildsComplete())
2122
2123 self.assertEqual(len(self.history), 1)
James E. Blair18c64442014-03-18 10:14:45 -07002124 self.assertEqual(self.history[0].name, 'gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002125 self.assertEqual(self.history[0].result, 'SUCCESS')
2126
James E. Blair879dafb2015-07-17 14:04:49 -07002127 def test_file_head(self):
2128 # This is a regression test for an observed bug. A change
2129 # with a file named "HEAD" in the root directory of the repo
2130 # was processed by a merger. It then was unable to reset the
2131 # repo because of:
2132 # GitCommandError: 'git reset --hard HEAD' returned
2133 # with exit code 128
2134 # stderr: 'fatal: ambiguous argument 'HEAD': both revision
2135 # and filename
2136 # Use '--' to separate filenames from revisions'
2137
2138 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
Paul Belangera91095f2016-11-04 19:28:48 -04002139 A.addPatchset({'HEAD': ''})
James E. Blair879dafb2015-07-17 14:04:49 -07002140 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2141
2142 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
2143 self.waitUntilSettled()
2144
2145 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2146 self.waitUntilSettled()
2147
2148 self.assertIn('Build succeeded', A.messages[0])
2149 self.assertIn('Build succeeded', B.messages[0])
2150
James E. Blairec056492016-07-22 09:45:56 -07002151 @skip("Disabled for early v3 development")
James E. Blair70c71582013-03-06 08:50:50 -08002152 def test_file_jobs(self):
2153 "Test that file jobs run only when appropriate"
2154 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2155 A.addPatchset(['pip-requires'])
2156 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07002157 A.addApproval('code-review', 2)
2158 B.addApproval('code-review', 2)
2159 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
2160 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair70c71582013-03-06 08:50:50 -08002161 self.waitUntilSettled()
2162
Monty Taylor6bef8ef2013-06-02 08:17:12 -04002163 testfile_jobs = [x for x in self.history
James E. Blair70c71582013-03-06 08:50:50 -08002164 if x.name == 'project-testfile']
2165
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002166 self.assertEqual(len(testfile_jobs), 1)
2167 self.assertEqual(testfile_jobs[0].changes, '1,2')
2168 self.assertEqual(A.data['status'], 'MERGED')
2169 self.assertEqual(A.reported, 2)
2170 self.assertEqual(B.data['status'], 'MERGED')
2171 self.assertEqual(B.reported, 2)
James E. Blair3c5e5b52013-04-26 11:17:03 -07002172
Clint Byrum3ee39f32016-11-17 23:45:07 -08002173 def _test_irrelevant_files_jobs(self, should_skip):
2174 "Test that jobs with irrelevant-files filter run only when appropriate"
2175 self.updateConfigLayout('layout-irrelevant-files')
Maru Newby3fe5f852015-01-13 04:22:14 +00002176 self.sched.reconfigure(self.config)
Clint Byrum3ee39f32016-11-17 23:45:07 -08002177
2178 if should_skip:
2179 files = {'ignoreme': 'ignored\n'}
2180 else:
2181 files = {'respectme': 'please!\n'}
Maru Newby3fe5f852015-01-13 04:22:14 +00002182
2183 change = self.fake_gerrit.addFakeChange('org/project',
Clint Byrum3ee39f32016-11-17 23:45:07 -08002184 'master',
2185 'test irrelevant-files',
2186 files=files)
Maru Newby3fe5f852015-01-13 04:22:14 +00002187 self.fake_gerrit.addEvent(change.getPatchsetCreatedEvent(1))
2188 self.waitUntilSettled()
2189
2190 tested_change_ids = [x.changes[0] for x in self.history
Clint Byrum3ee39f32016-11-17 23:45:07 -08002191 if x.name == 'project-test-irrelevant-files']
Maru Newby3fe5f852015-01-13 04:22:14 +00002192
2193 if should_skip:
2194 self.assertEqual([], tested_change_ids)
2195 else:
2196 self.assertIn(change.data['number'], tested_change_ids)
2197
Clint Byrum3ee39f32016-11-17 23:45:07 -08002198 def test_irrelevant_files_match_skips_job(self):
2199 self._test_irrelevant_files_jobs(should_skip=True)
Maru Newby3fe5f852015-01-13 04:22:14 +00002200
Clint Byrum3ee39f32016-11-17 23:45:07 -08002201 def test_irrelevant_files_no_match_runs_job(self):
2202 self._test_irrelevant_files_jobs(should_skip=False)
Maru Newby3fe5f852015-01-13 04:22:14 +00002203
Clint Byrum85493602016-11-18 11:59:47 -08002204 def test_inherited_jobs_keep_matchers(self):
2205 self.updateConfigLayout('layout-inheritance')
2206 self.sched.reconfigure(self.config)
2207
2208 files = {'ignoreme': 'ignored\n'}
2209
2210 change = self.fake_gerrit.addFakeChange('org/project',
2211 'master',
2212 'test irrelevant-files',
2213 files=files)
2214 self.fake_gerrit.addEvent(change.getPatchsetCreatedEvent(1))
2215 self.waitUntilSettled()
2216
2217 run_jobs = set([build.name for build in self.history])
2218
2219 self.assertEqual(set(['project-test-nomatch-starts-empty',
2220 'project-test-nomatch-starts-full']), run_jobs)
2221
James E. Blairec056492016-07-22 09:45:56 -07002222 @skip("Disabled for early v3 development")
James E. Blair3c5e5b52013-04-26 11:17:03 -07002223 def test_test_config(self):
2224 "Test that we can test the config"
James E. Blairf84026c2015-12-08 16:11:46 -08002225 self.sched.testConfig(self.config.get('zuul', 'tenant_config'),
Joshua Hesketh352264b2015-08-11 23:42:08 +10002226 self.connections)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002227
James E. Blairec056492016-07-22 09:45:56 -07002228 @skip("Disabled for early v3 development")
James E. Blairc8a1e052014-02-25 09:29:26 -08002229 def test_queue_names(self):
2230 "Test shared change queue names"
2231 project1 = self.sched.layout.projects['org/project1']
2232 project2 = self.sched.layout.projects['org/project2']
2233 q1 = self.sched.layout.pipelines['gate'].getQueue(project1)
2234 q2 = self.sched.layout.pipelines['gate'].getQueue(project2)
2235 self.assertEqual(q1.name, 'integration')
2236 self.assertEqual(q2.name, 'integration')
2237
James E. Blairf84026c2015-12-08 16:11:46 -08002238 self.updateConfigLayout(
2239 'tests/fixtures/layout-bad-queue.yaml')
James E. Blairc8a1e052014-02-25 09:29:26 -08002240 with testtools.ExpectedException(
2241 Exception, "More than one name assigned to change queue"):
2242 self.sched.reconfigure(self.config)
2243
James E. Blair64ed6f22013-07-10 14:07:23 -07002244 def test_queue_precedence(self):
2245 "Test that queue precedence works"
2246
2247 self.gearman_server.hold_jobs_in_queue = True
James E. Blair08d19992016-08-10 15:25:31 -07002248 self.launch_server.hold_jobs_in_build = True
James E. Blair64ed6f22013-07-10 14:07:23 -07002249 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2250 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
James E. Blair8b5408c2016-08-08 15:37:46 -07002251 A.addApproval('code-review', 2)
2252 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair64ed6f22013-07-10 14:07:23 -07002253
2254 self.waitUntilSettled()
2255 self.gearman_server.hold_jobs_in_queue = False
2256 self.gearman_server.release()
2257 self.waitUntilSettled()
2258
James E. Blair8de58bd2013-07-18 16:23:33 -07002259 # Run one build at a time to ensure non-race order:
James E. Blairb8c16472015-05-05 14:55:26 -07002260 self.orderedRelease()
James E. Blair08d19992016-08-10 15:25:31 -07002261 self.launch_server.hold_jobs_in_build = False
James E. Blair8de58bd2013-07-18 16:23:33 -07002262 self.waitUntilSettled()
2263
James E. Blair64ed6f22013-07-10 14:07:23 -07002264 self.log.debug(self.history)
2265 self.assertEqual(self.history[0].pipeline, 'gate')
2266 self.assertEqual(self.history[1].pipeline, 'check')
2267 self.assertEqual(self.history[2].pipeline, 'gate')
2268 self.assertEqual(self.history[3].pipeline, 'gate')
2269 self.assertEqual(self.history[4].pipeline, 'check')
2270 self.assertEqual(self.history[5].pipeline, 'check')
2271
James E. Blairec056492016-07-22 09:45:56 -07002272 @skip("Disabled for early v3 development")
Clark Boylana5edbe42014-06-03 16:39:10 -07002273 def test_json_status(self):
James E. Blair1843a552013-07-03 14:19:52 -07002274 "Test that we can retrieve JSON status info"
James E. Blair08d19992016-08-10 15:25:31 -07002275 self.launch_server.hold_jobs_in_build = True
James E. Blair1843a552013-07-03 14:19:52 -07002276 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07002277 A.addApproval('code-review', 2)
2278 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair1843a552013-07-03 14:19:52 -07002279 self.waitUntilSettled()
2280
James E. Blair08d19992016-08-10 15:25:31 -07002281 self.launch_server.release('project-merge')
James E. Blairb7273ef2016-04-19 08:58:51 -07002282 self.waitUntilSettled()
2283
James E. Blair1843a552013-07-03 14:19:52 -07002284 port = self.webapp.server.socket.getsockname()[1]
2285
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002286 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2287 f = urllib.request.urlopen(req)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002288 headers = f.info()
2289 self.assertIn('Content-Length', headers)
2290 self.assertIn('Content-Type', headers)
Sachi Kingdc963fc2016-03-23 16:00:33 +11002291 self.assertIsNotNone(re.match('^application/json(; charset=UTF-8)?$',
2292 headers['Content-Type']))
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002293 self.assertIn('Access-Control-Allow-Origin', headers)
2294 self.assertIn('Cache-Control', headers)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002295 self.assertIn('Last-Modified', headers)
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002296 self.assertIn('Expires', headers)
James E. Blair1843a552013-07-03 14:19:52 -07002297 data = f.read()
2298
James E. Blair08d19992016-08-10 15:25:31 -07002299 self.launch_server.hold_jobs_in_build = False
2300 self.launch_server.release()
James E. Blair1843a552013-07-03 14:19:52 -07002301 self.waitUntilSettled()
2302
2303 data = json.loads(data)
James E. Blairb7273ef2016-04-19 08:58:51 -07002304 status_jobs = []
James E. Blair1843a552013-07-03 14:19:52 -07002305 for p in data['pipelines']:
2306 for q in p['change_queues']:
James E. Blairbfb8e042014-12-30 17:01:44 -08002307 if p['name'] in ['gate', 'conflict']:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002308 self.assertEqual(q['window'], 20)
2309 else:
2310 self.assertEqual(q['window'], 0)
James E. Blair1843a552013-07-03 14:19:52 -07002311 for head in q['heads']:
2312 for change in head:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002313 self.assertTrue(change['active'])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002314 self.assertEqual(change['id'], '1,1')
James E. Blair1843a552013-07-03 14:19:52 -07002315 for job in change['jobs']:
James E. Blairb7273ef2016-04-19 08:58:51 -07002316 status_jobs.append(job)
2317 self.assertEqual('project-merge', status_jobs[0]['name'])
2318 self.assertEqual('https://server/job/project-merge/0/',
2319 status_jobs[0]['url'])
2320 self.assertEqual('http://logs.example.com/1/1/gate/project-merge/0',
2321 status_jobs[0]['report_url'])
2322
2323 self.assertEqual('project-test1', status_jobs[1]['name'])
2324 self.assertEqual('https://server/job/project-test1/1/',
2325 status_jobs[1]['url'])
2326 self.assertEqual('http://logs.example.com/1/1/gate/project-test1/1',
2327 status_jobs[1]['report_url'])
2328
2329 self.assertEqual('project-test2', status_jobs[2]['name'])
2330 self.assertEqual('https://server/job/project-test2/2/',
2331 status_jobs[2]['url'])
2332 self.assertEqual('http://logs.example.com/1/1/gate/project-test2/2',
2333 status_jobs[2]['report_url'])
James E. Blair1843a552013-07-03 14:19:52 -07002334
James E. Blairec056492016-07-22 09:45:56 -07002335 @skip("Disabled for early v3 development")
James E. Blairc3d428e2013-12-03 15:06:48 -08002336 def test_merging_queues(self):
2337 "Test that transitively-connected change queues are merged"
James E. Blairf84026c2015-12-08 16:11:46 -08002338 self.updateConfigLayout(
2339 'tests/fixtures/layout-merge-queues.yaml')
James E. Blairc3d428e2013-12-03 15:06:48 -08002340 self.sched.reconfigure(self.config)
2341 self.assertEqual(len(self.sched.layout.pipelines['gate'].queues), 1)
2342
James E. Blairec056492016-07-22 09:45:56 -07002343 @skip("Disabled for early v3 development")
James E. Blairaf17a972016-02-03 15:07:18 -08002344 def test_mutex(self):
2345 "Test job mutexes"
2346 self.config.set('zuul', 'layout_config',
2347 'tests/fixtures/layout-mutex.yaml')
2348 self.sched.reconfigure(self.config)
2349
James E. Blair08d19992016-08-10 15:25:31 -07002350 self.launch_server.hold_jobs_in_build = True
James E. Blairaf17a972016-02-03 15:07:18 -08002351 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2352 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2353 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2354
2355 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2356 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2357 self.waitUntilSettled()
2358 self.assertEqual(len(self.builds), 3)
2359 self.assertEqual(self.builds[0].name, 'project-test1')
2360 self.assertEqual(self.builds[1].name, 'mutex-one')
2361 self.assertEqual(self.builds[2].name, 'project-test1')
2362
James E. Blair08d19992016-08-10 15:25:31 -07002363 self.launch_server.release('mutex-one')
James E. Blairaf17a972016-02-03 15:07:18 -08002364 self.waitUntilSettled()
2365
2366 self.assertEqual(len(self.builds), 3)
2367 self.assertEqual(self.builds[0].name, 'project-test1')
2368 self.assertEqual(self.builds[1].name, 'project-test1')
2369 self.assertEqual(self.builds[2].name, 'mutex-two')
2370 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2371
James E. Blair08d19992016-08-10 15:25:31 -07002372 self.launch_server.release('mutex-two')
James E. Blairaf17a972016-02-03 15:07:18 -08002373 self.waitUntilSettled()
2374
2375 self.assertEqual(len(self.builds), 3)
2376 self.assertEqual(self.builds[0].name, 'project-test1')
2377 self.assertEqual(self.builds[1].name, 'project-test1')
2378 self.assertEqual(self.builds[2].name, 'mutex-one')
2379 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2380
James E. Blair08d19992016-08-10 15:25:31 -07002381 self.launch_server.release('mutex-one')
James E. Blairaf17a972016-02-03 15:07:18 -08002382 self.waitUntilSettled()
2383
2384 self.assertEqual(len(self.builds), 3)
2385 self.assertEqual(self.builds[0].name, 'project-test1')
2386 self.assertEqual(self.builds[1].name, 'project-test1')
2387 self.assertEqual(self.builds[2].name, 'mutex-two')
2388 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2389
James E. Blair08d19992016-08-10 15:25:31 -07002390 self.launch_server.release('mutex-two')
James E. Blairaf17a972016-02-03 15:07:18 -08002391 self.waitUntilSettled()
2392
2393 self.assertEqual(len(self.builds), 2)
2394 self.assertEqual(self.builds[0].name, 'project-test1')
2395 self.assertEqual(self.builds[1].name, 'project-test1')
2396 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2397
James E. Blair08d19992016-08-10 15:25:31 -07002398 self.launch_server.hold_jobs_in_build = False
2399 self.launch_server.release()
James E. Blairaf17a972016-02-03 15:07:18 -08002400
2401 self.waitUntilSettled()
2402 self.assertEqual(len(self.builds), 0)
2403
2404 self.assertEqual(A.reported, 1)
2405 self.assertEqual(B.reported, 1)
2406 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2407
James E. Blairec056492016-07-22 09:45:56 -07002408 @skip("Disabled for early v3 development")
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002409 def test_node_label(self):
2410 "Test that a job runs on a specific node label"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002411 self.worker.registerFunction('build:node-project-test1:debian')
2412
2413 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07002414 A.addApproval('code-review', 2)
2415 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002416 self.waitUntilSettled()
James E. Blair4ca985f2013-05-30 12:27:43 -07002417
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002418 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2419 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2420 'debian')
2421 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
James E. Blaircdccd972013-07-01 12:10:22 -07002422
2423 def test_live_reconfiguration(self):
2424 "Test that live reconfiguration works"
James E. Blair08d19992016-08-10 15:25:31 -07002425 self.launch_server.hold_jobs_in_build = True
James E. Blaircdccd972013-07-01 12:10:22 -07002426 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07002427 A.addApproval('code-review', 2)
2428 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blaircdccd972013-07-01 12:10:22 -07002429 self.waitUntilSettled()
2430
2431 self.sched.reconfigure(self.config)
2432
James E. Blair08d19992016-08-10 15:25:31 -07002433 self.launch_server.hold_jobs_in_build = False
2434 self.launch_server.release()
James E. Blaircdccd972013-07-01 12:10:22 -07002435 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002436 self.assertEqual(self.getJobFromHistory('project-merge').result,
2437 'SUCCESS')
2438 self.assertEqual(self.getJobFromHistory('project-test1').result,
2439 'SUCCESS')
2440 self.assertEqual(self.getJobFromHistory('project-test2').result,
2441 'SUCCESS')
2442 self.assertEqual(A.data['status'], 'MERGED')
2443 self.assertEqual(A.reported, 2)
James E. Blair287c06d2013-07-24 10:39:30 -07002444
James E. Blairec056492016-07-22 09:45:56 -07002445 @skip("Disabled for early v3 development")
James E. Blair6bc782d2015-07-17 16:20:21 -07002446 def test_live_reconfiguration_merge_conflict(self):
2447 # A real-world bug: a change in a gate queue has a merge
2448 # conflict and a job is added to its project while it's
2449 # sitting in the queue. The job gets added to the change and
2450 # enqueued and the change gets stuck.
2451 self.worker.registerFunction('build:project-test3')
James E. Blair08d19992016-08-10 15:25:31 -07002452 self.launch_server.hold_jobs_in_build = True
James E. Blair6bc782d2015-07-17 16:20:21 -07002453
2454 # This change is fine. It's here to stop the queue long
2455 # enough for the next change to be subject to the
2456 # reconfiguration, as well as to provide a conflict for the
2457 # next change. This change will succeed and merge.
2458 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2459 A.addPatchset(['conflict'])
James E. Blair8b5408c2016-08-08 15:37:46 -07002460 A.addApproval('code-review', 2)
James E. Blair6bc782d2015-07-17 16:20:21 -07002461
2462 # This change will be in merge conflict. During the
2463 # reconfiguration, we will add a job. We want to make sure
2464 # that doesn't cause it to get stuck.
2465 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2466 B.addPatchset(['conflict'])
James E. Blair8b5408c2016-08-08 15:37:46 -07002467 B.addApproval('code-review', 2)
James E. Blair4eb21fa2015-07-27 14:56:47 -07002468
James E. Blair8b5408c2016-08-08 15:37:46 -07002469 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
2470 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair6bc782d2015-07-17 16:20:21 -07002471
2472 self.waitUntilSettled()
2473
2474 # No jobs have run yet
2475 self.assertEqual(A.data['status'], 'NEW')
2476 self.assertEqual(A.reported, 1)
2477 self.assertEqual(B.data['status'], 'NEW')
2478 self.assertEqual(B.reported, 1)
2479 self.assertEqual(len(self.history), 0)
2480
2481 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002482 self.updateConfigLayout(
2483 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002484 self.sched.reconfigure(self.config)
2485 self.waitUntilSettled()
2486
James E. Blair08d19992016-08-10 15:25:31 -07002487 self.launch_server.hold_jobs_in_build = False
2488 self.launch_server.release()
James E. Blair6bc782d2015-07-17 16:20:21 -07002489 self.waitUntilSettled()
2490
2491 self.assertEqual(A.data['status'], 'MERGED')
2492 self.assertEqual(A.reported, 2)
2493 self.assertEqual(B.data['status'], 'NEW')
2494 self.assertEqual(B.reported, 2)
2495 self.assertEqual(self.getJobFromHistory('project-merge').result,
2496 'SUCCESS')
2497 self.assertEqual(self.getJobFromHistory('project-test1').result,
2498 'SUCCESS')
2499 self.assertEqual(self.getJobFromHistory('project-test2').result,
2500 'SUCCESS')
2501 self.assertEqual(self.getJobFromHistory('project-test3').result,
2502 'SUCCESS')
2503 self.assertEqual(len(self.history), 4)
2504
James E. Blairec056492016-07-22 09:45:56 -07002505 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002506 def test_live_reconfiguration_failed_root(self):
James E. Blair6bc782d2015-07-17 16:20:21 -07002507 # An extrapolation of test_live_reconfiguration_merge_conflict
2508 # that tests a job added to a job tree with a failed root does
2509 # not run.
2510 self.worker.registerFunction('build:project-test3')
James E. Blair08d19992016-08-10 15:25:31 -07002511 self.launch_server.hold_jobs_in_build = True
James E. Blair6bc782d2015-07-17 16:20:21 -07002512
2513 # This change is fine. It's here to stop the queue long
2514 # enough for the next change to be subject to the
2515 # reconfiguration. This change will succeed and merge.
2516 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2517 A.addPatchset(['conflict'])
James E. Blair8b5408c2016-08-08 15:37:46 -07002518 A.addApproval('code-review', 2)
2519 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair6bc782d2015-07-17 16:20:21 -07002520 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002521 self.launch_server.release('.*-merge')
James E. Blair6bc782d2015-07-17 16:20:21 -07002522 self.waitUntilSettled()
2523
2524 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair08d19992016-08-10 15:25:31 -07002525 self.launch_server.failJob('project-merge', B)
James E. Blair8b5408c2016-08-08 15:37:46 -07002526 B.addApproval('code-review', 2)
2527 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair6bc782d2015-07-17 16:20:21 -07002528 self.waitUntilSettled()
2529
James E. Blair08d19992016-08-10 15:25:31 -07002530 self.launch_server.release('.*-merge')
James E. Blair6bc782d2015-07-17 16:20:21 -07002531 self.waitUntilSettled()
2532
2533 # Both -merge jobs have run, but no others.
2534 self.assertEqual(A.data['status'], 'NEW')
2535 self.assertEqual(A.reported, 1)
2536 self.assertEqual(B.data['status'], 'NEW')
2537 self.assertEqual(B.reported, 1)
2538 self.assertEqual(self.history[0].result, 'SUCCESS')
2539 self.assertEqual(self.history[0].name, 'project-merge')
2540 self.assertEqual(self.history[1].result, 'FAILURE')
2541 self.assertEqual(self.history[1].name, 'project-merge')
2542 self.assertEqual(len(self.history), 2)
2543
2544 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002545 self.updateConfigLayout(
2546 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002547 self.sched.reconfigure(self.config)
2548 self.waitUntilSettled()
2549
James E. Blair08d19992016-08-10 15:25:31 -07002550 self.launch_server.hold_jobs_in_build = False
2551 self.launch_server.release()
James E. Blair6bc782d2015-07-17 16:20:21 -07002552 self.waitUntilSettled()
2553
2554 self.assertEqual(A.data['status'], 'MERGED')
2555 self.assertEqual(A.reported, 2)
2556 self.assertEqual(B.data['status'], 'NEW')
2557 self.assertEqual(B.reported, 2)
2558 self.assertEqual(self.history[0].result, 'SUCCESS')
2559 self.assertEqual(self.history[0].name, 'project-merge')
2560 self.assertEqual(self.history[1].result, 'FAILURE')
2561 self.assertEqual(self.history[1].name, 'project-merge')
2562 self.assertEqual(self.history[2].result, 'SUCCESS')
2563 self.assertEqual(self.history[3].result, 'SUCCESS')
2564 self.assertEqual(self.history[4].result, 'SUCCESS')
2565 self.assertEqual(len(self.history), 5)
2566
James E. Blairec056492016-07-22 09:45:56 -07002567 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002568 def test_live_reconfiguration_failed_job(self):
2569 # Test that a change with a removed failing job does not
2570 # disrupt reconfiguration. If a change has a failed job and
2571 # that job is removed during a reconfiguration, we observed a
2572 # bug where the code to re-set build statuses would run on
2573 # that build and raise an exception because the job no longer
2574 # existed.
James E. Blair08d19992016-08-10 15:25:31 -07002575 self.launch_server.hold_jobs_in_build = True
James E. Blair400e8fd2015-07-30 17:44:45 -07002576
2577 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2578
2579 # This change will fail and later be removed by the reconfiguration.
James E. Blair08d19992016-08-10 15:25:31 -07002580 self.launch_server.failJob('project-test1', A)
James E. Blair400e8fd2015-07-30 17:44:45 -07002581
2582 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2583 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002584 self.launch_server.release('.*-merge')
James E. Blair400e8fd2015-07-30 17:44:45 -07002585 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002586 self.launch_server.release('project-test1')
James E. Blair400e8fd2015-07-30 17:44:45 -07002587 self.waitUntilSettled()
2588
2589 self.assertEqual(A.data['status'], 'NEW')
2590 self.assertEqual(A.reported, 0)
2591
2592 self.assertEqual(self.getJobFromHistory('project-merge').result,
2593 'SUCCESS')
2594 self.assertEqual(self.getJobFromHistory('project-test1').result,
2595 'FAILURE')
2596 self.assertEqual(len(self.history), 2)
2597
2598 # Remove the test1 job.
James E. Blairf84026c2015-12-08 16:11:46 -08002599 self.updateConfigLayout(
2600 'tests/fixtures/layout-live-reconfiguration-failed-job.yaml')
James E. Blair400e8fd2015-07-30 17:44:45 -07002601 self.sched.reconfigure(self.config)
2602 self.waitUntilSettled()
2603
James E. Blair08d19992016-08-10 15:25:31 -07002604 self.launch_server.hold_jobs_in_build = False
2605 self.launch_server.release()
James E. Blair400e8fd2015-07-30 17:44:45 -07002606 self.waitUntilSettled()
2607
2608 self.assertEqual(self.getJobFromHistory('project-test2').result,
2609 'SUCCESS')
2610 self.assertEqual(self.getJobFromHistory('project-testfile').result,
2611 'SUCCESS')
2612 self.assertEqual(len(self.history), 4)
2613
2614 self.assertEqual(A.data['status'], 'NEW')
2615 self.assertEqual(A.reported, 1)
2616 self.assertIn('Build succeeded', A.messages[0])
2617 # Ensure the removed job was not included in the report.
2618 self.assertNotIn('project-test1', A.messages[0])
2619
James E. Blairec056492016-07-22 09:45:56 -07002620 @skip("Disabled for early v3 development")
James E. Blairfe707d12015-08-05 15:18:15 -07002621 def test_live_reconfiguration_shared_queue(self):
2622 # Test that a change with a failing job which was removed from
2623 # this project but otherwise still exists in the system does
2624 # not disrupt reconfiguration.
2625
James E. Blair08d19992016-08-10 15:25:31 -07002626 self.launch_server.hold_jobs_in_build = True
James E. Blairfe707d12015-08-05 15:18:15 -07002627
2628 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2629
James E. Blair08d19992016-08-10 15:25:31 -07002630 self.launch_server.failJob('project1-project2-integration', A)
James E. Blairfe707d12015-08-05 15:18:15 -07002631
2632 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2633 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002634 self.launch_server.release('.*-merge')
James E. Blairfe707d12015-08-05 15:18:15 -07002635 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002636 self.launch_server.release('project1-project2-integration')
James E. Blairfe707d12015-08-05 15:18:15 -07002637 self.waitUntilSettled()
2638
2639 self.assertEqual(A.data['status'], 'NEW')
2640 self.assertEqual(A.reported, 0)
2641
2642 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2643 'SUCCESS')
2644 self.assertEqual(self.getJobFromHistory(
2645 'project1-project2-integration').result, 'FAILURE')
2646 self.assertEqual(len(self.history), 2)
2647
2648 # Remove the integration job.
James E. Blairf84026c2015-12-08 16:11:46 -08002649 self.updateConfigLayout(
2650 'tests/fixtures/layout-live-reconfiguration-shared-queue.yaml')
James E. Blairfe707d12015-08-05 15:18:15 -07002651 self.sched.reconfigure(self.config)
2652 self.waitUntilSettled()
2653
James E. Blair08d19992016-08-10 15:25:31 -07002654 self.launch_server.hold_jobs_in_build = False
2655 self.launch_server.release()
James E. Blairfe707d12015-08-05 15:18:15 -07002656 self.waitUntilSettled()
2657
2658 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2659 'SUCCESS')
2660 self.assertEqual(self.getJobFromHistory('project1-test1').result,
2661 'SUCCESS')
2662 self.assertEqual(self.getJobFromHistory('project1-test2').result,
2663 'SUCCESS')
2664 self.assertEqual(self.getJobFromHistory(
2665 'project1-project2-integration').result, 'FAILURE')
2666 self.assertEqual(len(self.history), 4)
2667
2668 self.assertEqual(A.data['status'], 'NEW')
2669 self.assertEqual(A.reported, 1)
2670 self.assertIn('Build succeeded', A.messages[0])
2671 # Ensure the removed job was not included in the report.
2672 self.assertNotIn('project1-project2-integration', A.messages[0])
2673
James E. Blairec056492016-07-22 09:45:56 -07002674 @skip("Disabled for early v3 development")
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002675 def test_double_live_reconfiguration_shared_queue(self):
2676 # This was a real-world regression. A change is added to
2677 # gate; a reconfigure happens, a second change which depends
2678 # on the first is added, and a second reconfiguration happens.
2679 # Ensure that both changes merge.
2680
2681 # A failure may indicate incorrect caching or cleaning up of
2682 # references during a reconfiguration.
James E. Blair08d19992016-08-10 15:25:31 -07002683 self.launch_server.hold_jobs_in_build = True
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002684
2685 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2686 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2687 B.setDependsOn(A, 1)
James E. Blair8b5408c2016-08-08 15:37:46 -07002688 A.addApproval('code-review', 2)
2689 B.addApproval('code-review', 2)
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002690
2691 # Add the parent change.
James E. Blair8b5408c2016-08-08 15:37:46 -07002692 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002693 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002694 self.launch_server.release('.*-merge')
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002695 self.waitUntilSettled()
2696
2697 # Reconfigure (with only one change in the pipeline).
2698 self.sched.reconfigure(self.config)
2699 self.waitUntilSettled()
2700
2701 # Add the child change.
James E. Blair8b5408c2016-08-08 15:37:46 -07002702 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002703 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002704 self.launch_server.release('.*-merge')
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002705 self.waitUntilSettled()
2706
2707 # Reconfigure (with both in the pipeline).
2708 self.sched.reconfigure(self.config)
2709 self.waitUntilSettled()
2710
James E. Blair08d19992016-08-10 15:25:31 -07002711 self.launch_server.hold_jobs_in_build = False
2712 self.launch_server.release()
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002713 self.waitUntilSettled()
2714
2715 self.assertEqual(len(self.history), 8)
2716
2717 self.assertEqual(A.data['status'], 'MERGED')
2718 self.assertEqual(A.reported, 2)
2719 self.assertEqual(B.data['status'], 'MERGED')
2720 self.assertEqual(B.reported, 2)
2721
James E. Blairec056492016-07-22 09:45:56 -07002722 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002723 def test_live_reconfiguration_del_project(self):
2724 # Test project deletion from layout
2725 # while changes are enqueued
2726
James E. Blair08d19992016-08-10 15:25:31 -07002727 self.launch_server.hold_jobs_in_build = True
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002728 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2729 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2730 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
2731
2732 # A Depends-On: B
2733 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
2734 A.subject, B.data['id'])
James E. Blair8b5408c2016-08-08 15:37:46 -07002735 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002736
2737 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2738 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
2739 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002740 self.launch_server.release('.*-merge')
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002741 self.waitUntilSettled()
2742 self.assertEqual(len(self.builds), 5)
2743
2744 # This layout defines only org/project, not org/project1
James E. Blairf84026c2015-12-08 16:11:46 -08002745 self.updateConfigLayout(
2746 'tests/fixtures/layout-live-reconfiguration-del-project.yaml')
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002747 self.sched.reconfigure(self.config)
2748 self.waitUntilSettled()
2749
2750 # Builds for C aborted, builds for A succeed,
2751 # and have change B applied ahead
2752 job_c = self.getJobFromHistory('project1-test1')
2753 self.assertEqual(job_c.changes, '3,1')
2754 self.assertEqual(job_c.result, 'ABORTED')
2755
James E. Blair08d19992016-08-10 15:25:31 -07002756 self.launch_server.hold_jobs_in_build = False
2757 self.launch_server.release()
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002758 self.waitUntilSettled()
2759
2760 self.assertEqual(self.getJobFromHistory('project-test1').changes,
2761 '2,1 1,1')
2762
2763 self.assertEqual(A.data['status'], 'NEW')
2764 self.assertEqual(B.data['status'], 'NEW')
2765 self.assertEqual(C.data['status'], 'NEW')
2766 self.assertEqual(A.reported, 1)
2767 self.assertEqual(B.reported, 0)
2768 self.assertEqual(C.reported, 0)
2769
2770 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
2771 self.assertIn('Build succeeded', A.messages[0])
2772
James E. Blairec056492016-07-22 09:45:56 -07002773 @skip("Disabled for early v3 development")
James E. Blaire712d9f2013-07-31 11:40:11 -07002774 def test_live_reconfiguration_functions(self):
2775 "Test live reconfiguration with a custom function"
2776 self.worker.registerFunction('build:node-project-test1:debian')
2777 self.worker.registerFunction('build:node-project-test1:wheezy')
2778 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07002779 A.addApproval('code-review', 2)
2780 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blaire712d9f2013-07-31 11:40:11 -07002781 self.waitUntilSettled()
2782
2783 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2784 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2785 'debian')
2786 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2787
James E. Blairf84026c2015-12-08 16:11:46 -08002788 self.updateConfigLayout(
2789 'tests/fixtures/layout-live-reconfiguration-functions.yaml')
James E. Blaire712d9f2013-07-31 11:40:11 -07002790 self.sched.reconfigure(self.config)
2791 self.worker.build_history = []
2792
2793 B = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07002794 B.addApproval('code-review', 2)
2795 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blaire712d9f2013-07-31 11:40:11 -07002796 self.waitUntilSettled()
2797
2798 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2799 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2800 'wheezy')
2801 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2802
James E. Blairec056492016-07-22 09:45:56 -07002803 @skip("Disabled for early v3 development")
James E. Blair287c06d2013-07-24 10:39:30 -07002804 def test_delayed_repo_init(self):
James E. Blairf84026c2015-12-08 16:11:46 -08002805 self.updateConfigLayout(
2806 'tests/fixtures/layout-delayed-repo-init.yaml')
James E. Blair287c06d2013-07-24 10:39:30 -07002807 self.sched.reconfigure(self.config)
2808
2809 self.init_repo("org/new-project")
2810 A = self.fake_gerrit.addFakeChange('org/new-project', 'master', 'A')
2811
James E. Blair8b5408c2016-08-08 15:37:46 -07002812 A.addApproval('code-review', 2)
2813 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair287c06d2013-07-24 10:39:30 -07002814 self.waitUntilSettled()
2815 self.assertEqual(self.getJobFromHistory('project-merge').result,
2816 'SUCCESS')
2817 self.assertEqual(self.getJobFromHistory('project-test1').result,
2818 'SUCCESS')
2819 self.assertEqual(self.getJobFromHistory('project-test2').result,
2820 'SUCCESS')
2821 self.assertEqual(A.data['status'], 'MERGED')
2822 self.assertEqual(A.reported, 2)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002823
Clark Boylan6dbbc482013-10-18 10:57:31 -07002824 def test_repo_deleted(self):
Paul Belanger66e95962016-11-11 12:11:06 -05002825 self.updateConfigLayout('layout-repo-deleted')
Clark Boylan6dbbc482013-10-18 10:57:31 -07002826 self.sched.reconfigure(self.config)
2827
2828 self.init_repo("org/delete-project")
2829 A = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'A')
2830
James E. Blair8b5408c2016-08-08 15:37:46 -07002831 A.addApproval('code-review', 2)
2832 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Clark Boylan6dbbc482013-10-18 10:57:31 -07002833 self.waitUntilSettled()
2834 self.assertEqual(self.getJobFromHistory('project-merge').result,
2835 'SUCCESS')
2836 self.assertEqual(self.getJobFromHistory('project-test1').result,
2837 'SUCCESS')
2838 self.assertEqual(self.getJobFromHistory('project-test2').result,
2839 'SUCCESS')
2840 self.assertEqual(A.data['status'], 'MERGED')
2841 self.assertEqual(A.reported, 2)
2842
2843 # Delete org/new-project zuul repo. Should be recloned.
2844 shutil.rmtree(os.path.join(self.git_root, "org/delete-project"))
2845
2846 B = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'B')
2847
James E. Blair8b5408c2016-08-08 15:37:46 -07002848 B.addApproval('code-review', 2)
2849 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
Clark Boylan6dbbc482013-10-18 10:57:31 -07002850 self.waitUntilSettled()
2851 self.assertEqual(self.getJobFromHistory('project-merge').result,
2852 'SUCCESS')
2853 self.assertEqual(self.getJobFromHistory('project-test1').result,
2854 'SUCCESS')
2855 self.assertEqual(self.getJobFromHistory('project-test2').result,
2856 'SUCCESS')
2857 self.assertEqual(B.data['status'], 'MERGED')
2858 self.assertEqual(B.reported, 2)
2859
James E. Blairec056492016-07-22 09:45:56 -07002860 @skip("Disabled for early v3 development")
James E. Blair456f2fb2016-02-09 09:29:33 -08002861 def test_tags(self):
2862 "Test job tags"
2863 self.config.set('zuul', 'layout_config',
2864 'tests/fixtures/layout-tags.yaml')
2865 self.sched.reconfigure(self.config)
2866
2867 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2868 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
2869 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2870 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2871 self.waitUntilSettled()
2872
2873 results = {'project1-merge': 'extratag merge project1',
2874 'project2-merge': 'merge'}
2875
2876 for build in self.history:
2877 self.assertEqual(results.get(build.name, ''),
2878 build.parameters.get('BUILD_TAGS'))
2879
James E. Blairec056492016-07-22 09:45:56 -07002880 @skip("Disabled for early v3 development")
James E. Blair63bb0ef2013-07-29 17:14:51 -07002881 def test_timer(self):
2882 "Test that a periodic job is triggered"
James E. Blair08d19992016-08-10 15:25:31 -07002883 self.launch_server.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08002884 self.updateConfigLayout(
2885 'tests/fixtures/layout-timer.yaml')
James E. Blair63bb0ef2013-07-29 17:14:51 -07002886 self.sched.reconfigure(self.config)
2887 self.registerJobs()
2888
Clark Boylan3ee090a2014-04-03 20:55:09 -07002889 # The pipeline triggers every second, so we should have seen
2890 # several by now.
2891 time.sleep(5)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002892 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002893
2894 self.assertEqual(len(self.builds), 2)
2895
James E. Blair63bb0ef2013-07-29 17:14:51 -07002896 port = self.webapp.server.socket.getsockname()[1]
2897
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002898 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2899 f = urllib.request.urlopen(req)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002900 data = f.read()
2901
James E. Blair08d19992016-08-10 15:25:31 -07002902 self.launch_server.hold_jobs_in_build = False
Clark Boylan3ee090a2014-04-03 20:55:09 -07002903 # Stop queuing timer triggered jobs so that the assertions
2904 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08002905 self.updateConfigLayout(
2906 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002907 self.sched.reconfigure(self.config)
2908 self.registerJobs()
James E. Blair08d19992016-08-10 15:25:31 -07002909 self.launch_server.release()
James E. Blair63bb0ef2013-07-29 17:14:51 -07002910 self.waitUntilSettled()
2911
2912 self.assertEqual(self.getJobFromHistory(
2913 'project-bitrot-stable-old').result, 'SUCCESS')
2914 self.assertEqual(self.getJobFromHistory(
2915 'project-bitrot-stable-older').result, 'SUCCESS')
2916
2917 data = json.loads(data)
2918 status_jobs = set()
2919 for p in data['pipelines']:
2920 for q in p['change_queues']:
2921 for head in q['heads']:
2922 for change in head:
Alex Gaynorddb9ef32013-09-16 21:04:58 -07002923 self.assertEqual(change['id'], None)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002924 for job in change['jobs']:
2925 status_jobs.add(job['name'])
2926 self.assertIn('project-bitrot-stable-old', status_jobs)
2927 self.assertIn('project-bitrot-stable-older', status_jobs)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002928
James E. Blairec056492016-07-22 09:45:56 -07002929 @skip("Disabled for early v3 development")
James E. Blair4f6033c2014-03-27 15:49:09 -07002930 def test_idle(self):
2931 "Test that frequent periodic jobs work"
James E. Blair08d19992016-08-10 15:25:31 -07002932 self.launch_server.hold_jobs_in_build = True
James E. Blair4f6033c2014-03-27 15:49:09 -07002933
Clark Boylan3ee090a2014-04-03 20:55:09 -07002934 for x in range(1, 3):
2935 # Test that timer triggers periodic jobs even across
2936 # layout config reloads.
2937 # Start timer trigger
James E. Blairf84026c2015-12-08 16:11:46 -08002938 self.updateConfigLayout(
2939 'tests/fixtures/layout-idle.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002940 self.sched.reconfigure(self.config)
2941 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08002942 self.waitUntilSettled()
James E. Blair4f6033c2014-03-27 15:49:09 -07002943
Clark Boylan3ee090a2014-04-03 20:55:09 -07002944 # The pipeline triggers every second, so we should have seen
2945 # several by now.
2946 time.sleep(5)
Clark Boylan3ee090a2014-04-03 20:55:09 -07002947
2948 # Stop queuing timer triggered jobs so that the assertions
2949 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08002950 self.updateConfigLayout(
2951 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002952 self.sched.reconfigure(self.config)
2953 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08002954 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002955
2956 self.assertEqual(len(self.builds), 2)
James E. Blair08d19992016-08-10 15:25:31 -07002957 self.launch_server.release('.*')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002958 self.waitUntilSettled()
2959 self.assertEqual(len(self.builds), 0)
2960 self.assertEqual(len(self.history), x * 2)
James E. Blair4f6033c2014-03-27 15:49:09 -07002961
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002962 def test_check_smtp_pool(self):
Paul Belanger01be8ca2016-11-11 12:21:06 -05002963 self.updateConfigLayout('layout-smtp')
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002964 self.sched.reconfigure(self.config)
2965
2966 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2967 self.waitUntilSettled()
2968
2969 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2970 self.waitUntilSettled()
2971
James E. Blairff80a2f2013-12-27 13:24:06 -08002972 self.assertEqual(len(self.smtp_messages), 2)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002973
2974 # A.messages only holds what FakeGerrit places in it. Thus we
2975 # work on the knowledge of what the first message should be as
2976 # it is only configured to go to SMTP.
2977
2978 self.assertEqual('zuul@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08002979 self.smtp_messages[0]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002980 self.assertEqual(['you@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08002981 self.smtp_messages[0]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002982 self.assertEqual('Starting check jobs.',
James E. Blairff80a2f2013-12-27 13:24:06 -08002983 self.smtp_messages[0]['body'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002984
2985 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08002986 self.smtp_messages[1]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002987 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08002988 self.smtp_messages[1]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002989 self.assertEqual(A.messages[0],
James E. Blairff80a2f2013-12-27 13:24:06 -08002990 self.smtp_messages[1]['body'])
James E. Blairad28e912013-11-27 10:43:22 -08002991
James E. Blairec056492016-07-22 09:45:56 -07002992 @skip("Disabled for early v3 development")
James E. Blaire5910202013-12-27 09:50:31 -08002993 def test_timer_smtp(self):
2994 "Test that a periodic job is triggered"
James E. Blair08d19992016-08-10 15:25:31 -07002995 self.launch_server.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08002996 self.updateConfigLayout(
2997 'tests/fixtures/layout-timer-smtp.yaml')
James E. Blaire5910202013-12-27 09:50:31 -08002998 self.sched.reconfigure(self.config)
2999 self.registerJobs()
3000
Clark Boylan3ee090a2014-04-03 20:55:09 -07003001 # The pipeline triggers every second, so we should have seen
3002 # several by now.
3003 time.sleep(5)
James E. Blaire5910202013-12-27 09:50:31 -08003004 self.waitUntilSettled()
3005
Clark Boylan3ee090a2014-04-03 20:55:09 -07003006 self.assertEqual(len(self.builds), 2)
James E. Blair08d19992016-08-10 15:25:31 -07003007 self.launch_server.release('.*')
Clark Boylan3ee090a2014-04-03 20:55:09 -07003008 self.waitUntilSettled()
3009 self.assertEqual(len(self.history), 2)
3010
James E. Blaire5910202013-12-27 09:50:31 -08003011 self.assertEqual(self.getJobFromHistory(
3012 'project-bitrot-stable-old').result, 'SUCCESS')
3013 self.assertEqual(self.getJobFromHistory(
3014 'project-bitrot-stable-older').result, 'SUCCESS')
3015
James E. Blairff80a2f2013-12-27 13:24:06 -08003016 self.assertEqual(len(self.smtp_messages), 1)
James E. Blaire5910202013-12-27 09:50:31 -08003017
3018 # A.messages only holds what FakeGerrit places in it. Thus we
3019 # work on the knowledge of what the first message should be as
3020 # it is only configured to go to SMTP.
3021
3022 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003023 self.smtp_messages[0]['from_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003024 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003025 self.smtp_messages[0]['to_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003026 self.assertIn('Subject: Periodic check for org/project succeeded',
James E. Blairff80a2f2013-12-27 13:24:06 -08003027 self.smtp_messages[0]['headers'])
James E. Blaire5910202013-12-27 09:50:31 -08003028
Clark Boylan3ee090a2014-04-03 20:55:09 -07003029 # Stop queuing timer triggered jobs and let any that may have
3030 # queued through so that end of test assertions pass.
James E. Blairf84026c2015-12-08 16:11:46 -08003031 self.updateConfigLayout(
3032 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07003033 self.sched.reconfigure(self.config)
3034 self.registerJobs()
James E. Blairf8058972014-08-15 16:09:16 -07003035 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003036 self.launch_server.release('.*')
Clark Boylan3ee090a2014-04-03 20:55:09 -07003037 self.waitUntilSettled()
3038
James E. Blair91e34592015-07-31 16:45:59 -07003039 def test_client_enqueue_change(self):
James E. Blairad28e912013-11-27 10:43:22 -08003040 "Test that the RPC client can enqueue a change"
3041 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07003042 A.addApproval('code-review', 2)
3043 A.addApproval('approved', 1)
James E. Blairad28e912013-11-27 10:43:22 -08003044
3045 client = zuul.rpcclient.RPCClient('127.0.0.1',
3046 self.gearman_server.port)
Paul Belangerbaca3132016-11-04 12:49:54 -04003047 r = client.enqueue(tenant='tenant-one',
3048 pipeline='gate',
James E. Blairad28e912013-11-27 10:43:22 -08003049 project='org/project',
3050 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003051 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003052 self.waitUntilSettled()
3053 self.assertEqual(self.getJobFromHistory('project-merge').result,
3054 'SUCCESS')
3055 self.assertEqual(self.getJobFromHistory('project-test1').result,
3056 'SUCCESS')
3057 self.assertEqual(self.getJobFromHistory('project-test2').result,
3058 'SUCCESS')
3059 self.assertEqual(A.data['status'], 'MERGED')
3060 self.assertEqual(A.reported, 2)
3061 self.assertEqual(r, True)
3062
James E. Blairec056492016-07-22 09:45:56 -07003063 @skip("Disabled for early v3 development")
James E. Blair91e34592015-07-31 16:45:59 -07003064 def test_client_enqueue_ref(self):
3065 "Test that the RPC client can enqueue a ref"
3066
3067 client = zuul.rpcclient.RPCClient('127.0.0.1',
3068 self.gearman_server.port)
3069 r = client.enqueue_ref(
Paul Belangerbaca3132016-11-04 12:49:54 -04003070 tenant='tenant-one',
James E. Blair91e34592015-07-31 16:45:59 -07003071 pipeline='post',
3072 project='org/project',
3073 trigger='gerrit',
3074 ref='master',
3075 oldrev='90f173846e3af9154517b88543ffbd1691f31366',
3076 newrev='d479a0bfcb34da57a31adb2a595c0cf687812543')
3077 self.waitUntilSettled()
3078 job_names = [x.name for x in self.history]
3079 self.assertEqual(len(self.history), 1)
3080 self.assertIn('project-post', job_names)
3081 self.assertEqual(r, True)
3082
James E. Blairad28e912013-11-27 10:43:22 -08003083 def test_client_enqueue_negative(self):
3084 "Test that the RPC client returns errors"
3085 client = zuul.rpcclient.RPCClient('127.0.0.1',
3086 self.gearman_server.port)
3087 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
Paul Belangerbaca3132016-11-04 12:49:54 -04003088 "Invalid tenant"):
3089 r = client.enqueue(tenant='tenant-foo',
3090 pipeline='gate',
3091 project='org/project',
3092 trigger='gerrit',
3093 change='1,1')
3094 client.shutdown()
3095 self.assertEqual(r, False)
3096
3097 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
James E. Blairad28e912013-11-27 10:43:22 -08003098 "Invalid project"):
Paul Belangerbaca3132016-11-04 12:49:54 -04003099 r = client.enqueue(tenant='tenant-one',
3100 pipeline='gate',
James E. Blairad28e912013-11-27 10:43:22 -08003101 project='project-does-not-exist',
3102 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003103 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003104 client.shutdown()
3105 self.assertEqual(r, False)
3106
3107 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3108 "Invalid pipeline"):
Paul Belangerbaca3132016-11-04 12:49:54 -04003109 r = client.enqueue(tenant='tenant-one',
3110 pipeline='pipeline-does-not-exist',
James E. Blairad28e912013-11-27 10:43:22 -08003111 project='org/project',
3112 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003113 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003114 client.shutdown()
3115 self.assertEqual(r, False)
3116
3117 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3118 "Invalid trigger"):
Paul Belangerbaca3132016-11-04 12:49:54 -04003119 r = client.enqueue(tenant='tenant-one',
3120 pipeline='gate',
James E. Blairad28e912013-11-27 10:43:22 -08003121 project='org/project',
3122 trigger='trigger-does-not-exist',
James E. Blair36658cf2013-12-06 17:53:48 -08003123 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003124 client.shutdown()
3125 self.assertEqual(r, False)
3126
3127 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3128 "Invalid change"):
Paul Belangerbaca3132016-11-04 12:49:54 -04003129 r = client.enqueue(tenant='tenant-one',
3130 pipeline='gate',
James E. Blairad28e912013-11-27 10:43:22 -08003131 project='org/project',
3132 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003133 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003134 client.shutdown()
3135 self.assertEqual(r, False)
3136
3137 self.waitUntilSettled()
3138 self.assertEqual(len(self.history), 0)
3139 self.assertEqual(len(self.builds), 0)
James E. Blair36658cf2013-12-06 17:53:48 -08003140
3141 def test_client_promote(self):
3142 "Test that the RPC client can promote a change"
James E. Blair08d19992016-08-10 15:25:31 -07003143 self.launch_server.hold_jobs_in_build = True
James E. Blair36658cf2013-12-06 17:53:48 -08003144 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3145 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3146 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07003147 A.addApproval('code-review', 2)
3148 B.addApproval('code-review', 2)
3149 C.addApproval('code-review', 2)
James E. Blair36658cf2013-12-06 17:53:48 -08003150
James E. Blair8b5408c2016-08-08 15:37:46 -07003151 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
3152 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
3153 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair36658cf2013-12-06 17:53:48 -08003154
3155 self.waitUntilSettled()
3156
Paul Belangerbaca3132016-11-04 12:49:54 -04003157 tenant = self.sched.abide.tenants.get('tenant-one')
3158 items = tenant.layout.pipelines['gate'].getAllItems()
Sean Daguef39b9ca2014-01-10 21:34:35 -05003159 enqueue_times = {}
3160 for item in items:
3161 enqueue_times[str(item.change)] = item.enqueue_time
3162
James E. Blair36658cf2013-12-06 17:53:48 -08003163 client = zuul.rpcclient.RPCClient('127.0.0.1',
3164 self.gearman_server.port)
Paul Belangerbaca3132016-11-04 12:49:54 -04003165 r = client.promote(tenant='tenant-one',
3166 pipeline='gate',
James E. Blair36658cf2013-12-06 17:53:48 -08003167 change_ids=['2,1', '3,1'])
3168
Sean Daguef39b9ca2014-01-10 21:34:35 -05003169 # ensure that enqueue times are durable
Paul Belangerbaca3132016-11-04 12:49:54 -04003170 items = tenant.layout.pipelines['gate'].getAllItems()
Sean Daguef39b9ca2014-01-10 21:34:35 -05003171 for item in items:
3172 self.assertEqual(
3173 enqueue_times[str(item.change)], item.enqueue_time)
3174
James E. Blair78acec92014-02-06 07:11:32 -08003175 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003176 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003177 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003178 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003179 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003180 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003181 self.waitUntilSettled()
3182
3183 self.assertEqual(len(self.builds), 6)
3184 self.assertEqual(self.builds[0].name, 'project-test1')
3185 self.assertEqual(self.builds[1].name, 'project-test2')
3186 self.assertEqual(self.builds[2].name, 'project-test1')
3187 self.assertEqual(self.builds[3].name, 'project-test2')
3188 self.assertEqual(self.builds[4].name, 'project-test1')
3189 self.assertEqual(self.builds[5].name, 'project-test2')
3190
Paul Belangerbaca3132016-11-04 12:49:54 -04003191 self.assertTrue(self.builds[0].hasChanges(B))
3192 self.assertFalse(self.builds[0].hasChanges(A))
3193 self.assertFalse(self.builds[0].hasChanges(C))
James E. Blair36658cf2013-12-06 17:53:48 -08003194
Paul Belangerbaca3132016-11-04 12:49:54 -04003195 self.assertTrue(self.builds[2].hasChanges(B))
3196 self.assertTrue(self.builds[2].hasChanges(C))
3197 self.assertFalse(self.builds[2].hasChanges(A))
James E. Blair36658cf2013-12-06 17:53:48 -08003198
Paul Belangerbaca3132016-11-04 12:49:54 -04003199 self.assertTrue(self.builds[4].hasChanges(B))
3200 self.assertTrue(self.builds[4].hasChanges(C))
3201 self.assertTrue(self.builds[4].hasChanges(A))
James E. Blair36658cf2013-12-06 17:53:48 -08003202
James E. Blair08d19992016-08-10 15:25:31 -07003203 self.launch_server.release()
James E. Blair36658cf2013-12-06 17:53:48 -08003204 self.waitUntilSettled()
3205
3206 self.assertEqual(A.data['status'], 'MERGED')
3207 self.assertEqual(A.reported, 2)
3208 self.assertEqual(B.data['status'], 'MERGED')
3209 self.assertEqual(B.reported, 2)
3210 self.assertEqual(C.data['status'], 'MERGED')
3211 self.assertEqual(C.reported, 2)
3212
3213 client.shutdown()
3214 self.assertEqual(r, True)
3215
3216 def test_client_promote_dependent(self):
3217 "Test that the RPC client can promote a dependent change"
3218 # C (depends on B) -> B -> A ; then promote C to get:
3219 # A -> C (depends on B) -> B
James E. Blair08d19992016-08-10 15:25:31 -07003220 self.launch_server.hold_jobs_in_build = True
James E. Blair36658cf2013-12-06 17:53:48 -08003221 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3222 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3223 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3224
3225 C.setDependsOn(B, 1)
3226
James E. Blair8b5408c2016-08-08 15:37:46 -07003227 A.addApproval('code-review', 2)
3228 B.addApproval('code-review', 2)
3229 C.addApproval('code-review', 2)
James E. Blair36658cf2013-12-06 17:53:48 -08003230
James E. Blair8b5408c2016-08-08 15:37:46 -07003231 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
3232 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
3233 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair36658cf2013-12-06 17:53:48 -08003234
3235 self.waitUntilSettled()
3236
3237 client = zuul.rpcclient.RPCClient('127.0.0.1',
3238 self.gearman_server.port)
Paul Belangerbaca3132016-11-04 12:49:54 -04003239 r = client.promote(tenant='tenant-one',
3240 pipeline='gate',
James E. Blair36658cf2013-12-06 17:53:48 -08003241 change_ids=['3,1'])
3242
James E. Blair78acec92014-02-06 07:11:32 -08003243 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003244 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003245 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003246 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003247 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003248 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003249 self.waitUntilSettled()
3250
3251 self.assertEqual(len(self.builds), 6)
3252 self.assertEqual(self.builds[0].name, 'project-test1')
3253 self.assertEqual(self.builds[1].name, 'project-test2')
3254 self.assertEqual(self.builds[2].name, 'project-test1')
3255 self.assertEqual(self.builds[3].name, 'project-test2')
3256 self.assertEqual(self.builds[4].name, 'project-test1')
3257 self.assertEqual(self.builds[5].name, 'project-test2')
3258
Paul Belangerbaca3132016-11-04 12:49:54 -04003259 self.assertTrue(self.builds[0].hasChanges(B))
3260 self.assertFalse(self.builds[0].hasChanges(A))
3261 self.assertFalse(self.builds[0].hasChanges(C))
James E. Blair36658cf2013-12-06 17:53:48 -08003262
Paul Belangerbaca3132016-11-04 12:49:54 -04003263 self.assertTrue(self.builds[2].hasChanges(B))
3264 self.assertTrue(self.builds[2].hasChanges(C))
3265 self.assertFalse(self.builds[2].hasChanges(A))
James E. Blair36658cf2013-12-06 17:53:48 -08003266
Paul Belangerbaca3132016-11-04 12:49:54 -04003267 self.assertTrue(self.builds[4].hasChanges(B))
3268 self.assertTrue(self.builds[4].hasChanges(C))
3269 self.assertTrue(self.builds[4].hasChanges(A))
James E. Blair36658cf2013-12-06 17:53:48 -08003270
James E. Blair08d19992016-08-10 15:25:31 -07003271 self.launch_server.release()
James E. Blair36658cf2013-12-06 17:53:48 -08003272 self.waitUntilSettled()
3273
3274 self.assertEqual(A.data['status'], 'MERGED')
3275 self.assertEqual(A.reported, 2)
3276 self.assertEqual(B.data['status'], 'MERGED')
3277 self.assertEqual(B.reported, 2)
3278 self.assertEqual(C.data['status'], 'MERGED')
3279 self.assertEqual(C.reported, 2)
3280
3281 client.shutdown()
3282 self.assertEqual(r, True)
3283
3284 def test_client_promote_negative(self):
3285 "Test that the RPC client returns errors for promotion"
James E. Blair08d19992016-08-10 15:25:31 -07003286 self.launch_server.hold_jobs_in_build = True
James E. Blair36658cf2013-12-06 17:53:48 -08003287 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07003288 A.addApproval('code-review', 2)
3289 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair36658cf2013-12-06 17:53:48 -08003290 self.waitUntilSettled()
3291
3292 client = zuul.rpcclient.RPCClient('127.0.0.1',
3293 self.gearman_server.port)
3294
3295 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
Paul Belangerbaca3132016-11-04 12:49:54 -04003296 r = client.promote(tenant='tenant-one',
3297 pipeline='nonexistent',
James E. Blair36658cf2013-12-06 17:53:48 -08003298 change_ids=['2,1', '3,1'])
3299 client.shutdown()
3300 self.assertEqual(r, False)
3301
3302 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
Paul Belangerbaca3132016-11-04 12:49:54 -04003303 r = client.promote(tenant='tenant-one',
3304 pipeline='gate',
James E. Blair36658cf2013-12-06 17:53:48 -08003305 change_ids=['4,1'])
3306 client.shutdown()
3307 self.assertEqual(r, False)
3308
James E. Blair08d19992016-08-10 15:25:31 -07003309 self.launch_server.hold_jobs_in_build = False
3310 self.launch_server.release()
James E. Blair36658cf2013-12-06 17:53:48 -08003311 self.waitUntilSettled()
Clark Boylan7603a372014-01-21 11:43:20 -08003312
James E. Blairec056492016-07-22 09:45:56 -07003313 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003314 def test_queue_rate_limiting(self):
3315 "Test that DependentPipelines are rate limited with dep across window"
James E. Blairf84026c2015-12-08 16:11:46 -08003316 self.updateConfigLayout(
3317 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003318 self.sched.reconfigure(self.config)
James E. Blair08d19992016-08-10 15:25:31 -07003319 self.launch_server.hold_jobs_in_build = True
Clark Boylan7603a372014-01-21 11:43:20 -08003320 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3321 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3322 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3323
3324 C.setDependsOn(B, 1)
James E. Blair08d19992016-08-10 15:25:31 -07003325 self.launch_server.failJob('project-test1', A)
Clark Boylan7603a372014-01-21 11:43:20 -08003326
James E. Blair8b5408c2016-08-08 15:37:46 -07003327 A.addApproval('code-review', 2)
3328 B.addApproval('code-review', 2)
3329 C.addApproval('code-review', 2)
Clark Boylan7603a372014-01-21 11:43:20 -08003330
James E. Blair8b5408c2016-08-08 15:37:46 -07003331 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
3332 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
3333 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
Clark Boylan7603a372014-01-21 11:43:20 -08003334 self.waitUntilSettled()
3335
3336 # Only A and B will have their merge jobs queued because
3337 # window is 2.
3338 self.assertEqual(len(self.builds), 2)
3339 self.assertEqual(self.builds[0].name, 'project-merge')
3340 self.assertEqual(self.builds[1].name, 'project-merge')
3341
James E. Blair08d19992016-08-10 15:25:31 -07003342 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003343 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003344 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003345 self.waitUntilSettled()
3346
3347 # Only A and B will have their test jobs queued because
3348 # window is 2.
3349 self.assertEqual(len(self.builds), 4)
3350 self.assertEqual(self.builds[0].name, 'project-test1')
3351 self.assertEqual(self.builds[1].name, 'project-test2')
3352 self.assertEqual(self.builds[2].name, 'project-test1')
3353 self.assertEqual(self.builds[3].name, 'project-test2')
3354
James E. Blair08d19992016-08-10 15:25:31 -07003355 self.launch_server.release('project-.*')
Clark Boylan7603a372014-01-21 11:43:20 -08003356 self.waitUntilSettled()
3357
3358 queue = self.sched.layout.pipelines['gate'].queues[0]
3359 # A failed so window is reduced by 1 to 1.
3360 self.assertEqual(queue.window, 1)
3361 self.assertEqual(queue.window_floor, 1)
3362 self.assertEqual(A.data['status'], 'NEW')
3363
3364 # Gate is reset and only B's merge job is queued because
3365 # window shrunk to 1.
3366 self.assertEqual(len(self.builds), 1)
3367 self.assertEqual(self.builds[0].name, 'project-merge')
3368
James E. Blair08d19992016-08-10 15:25:31 -07003369 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003370 self.waitUntilSettled()
3371
3372 # Only B's test jobs are queued because window is still 1.
3373 self.assertEqual(len(self.builds), 2)
3374 self.assertEqual(self.builds[0].name, 'project-test1')
3375 self.assertEqual(self.builds[1].name, 'project-test2')
3376
James E. Blair08d19992016-08-10 15:25:31 -07003377 self.launch_server.release('project-.*')
Clark Boylan7603a372014-01-21 11:43:20 -08003378 self.waitUntilSettled()
3379
3380 # B was successfully merged so window is increased to 2.
3381 self.assertEqual(queue.window, 2)
3382 self.assertEqual(queue.window_floor, 1)
3383 self.assertEqual(B.data['status'], 'MERGED')
3384
3385 # Only C is left and its merge job is queued.
3386 self.assertEqual(len(self.builds), 1)
3387 self.assertEqual(self.builds[0].name, 'project-merge')
3388
James E. Blair08d19992016-08-10 15:25:31 -07003389 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003390 self.waitUntilSettled()
3391
3392 # After successful merge job the test jobs for C are queued.
3393 self.assertEqual(len(self.builds), 2)
3394 self.assertEqual(self.builds[0].name, 'project-test1')
3395 self.assertEqual(self.builds[1].name, 'project-test2')
3396
James E. Blair08d19992016-08-10 15:25:31 -07003397 self.launch_server.release('project-.*')
Clark Boylan7603a372014-01-21 11:43:20 -08003398 self.waitUntilSettled()
3399
3400 # C successfully merged so window is bumped to 3.
3401 self.assertEqual(queue.window, 3)
3402 self.assertEqual(queue.window_floor, 1)
3403 self.assertEqual(C.data['status'], 'MERGED')
3404
James E. Blairec056492016-07-22 09:45:56 -07003405 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003406 def test_queue_rate_limiting_dependent(self):
3407 "Test that DependentPipelines are rate limited with dep in window"
James E. Blairf84026c2015-12-08 16:11:46 -08003408 self.updateConfigLayout(
3409 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003410 self.sched.reconfigure(self.config)
James E. Blair08d19992016-08-10 15:25:31 -07003411 self.launch_server.hold_jobs_in_build = True
Clark Boylan7603a372014-01-21 11:43:20 -08003412 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3413 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3414 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3415
3416 B.setDependsOn(A, 1)
3417
James E. Blair08d19992016-08-10 15:25:31 -07003418 self.launch_server.failJob('project-test1', A)
Clark Boylan7603a372014-01-21 11:43:20 -08003419
James E. Blair8b5408c2016-08-08 15:37:46 -07003420 A.addApproval('code-review', 2)
3421 B.addApproval('code-review', 2)
3422 C.addApproval('code-review', 2)
Clark Boylan7603a372014-01-21 11:43:20 -08003423
James E. Blair8b5408c2016-08-08 15:37:46 -07003424 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
3425 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
3426 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
Clark Boylan7603a372014-01-21 11:43:20 -08003427 self.waitUntilSettled()
3428
3429 # Only A and B will have their merge jobs queued because
3430 # window is 2.
3431 self.assertEqual(len(self.builds), 2)
3432 self.assertEqual(self.builds[0].name, 'project-merge')
3433 self.assertEqual(self.builds[1].name, 'project-merge')
3434
James E. Blair08d19992016-08-10 15:25:31 -07003435 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003436 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003437 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003438 self.waitUntilSettled()
3439
3440 # Only A and B will have their test jobs queued because
3441 # window is 2.
3442 self.assertEqual(len(self.builds), 4)
3443 self.assertEqual(self.builds[0].name, 'project-test1')
3444 self.assertEqual(self.builds[1].name, 'project-test2')
3445 self.assertEqual(self.builds[2].name, 'project-test1')
3446 self.assertEqual(self.builds[3].name, 'project-test2')
3447
James E. Blair08d19992016-08-10 15:25:31 -07003448 self.launch_server.release('project-.*')
Clark Boylan7603a372014-01-21 11:43:20 -08003449 self.waitUntilSettled()
3450
3451 queue = self.sched.layout.pipelines['gate'].queues[0]
3452 # A failed so window is reduced by 1 to 1.
3453 self.assertEqual(queue.window, 1)
3454 self.assertEqual(queue.window_floor, 1)
3455 self.assertEqual(A.data['status'], 'NEW')
3456 self.assertEqual(B.data['status'], 'NEW')
3457
3458 # Gate is reset and only C's merge job is queued because
3459 # window shrunk to 1 and A and B were dequeued.
3460 self.assertEqual(len(self.builds), 1)
3461 self.assertEqual(self.builds[0].name, 'project-merge')
3462
James E. Blair08d19992016-08-10 15:25:31 -07003463 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003464 self.waitUntilSettled()
3465
3466 # Only C's test jobs are queued because window is still 1.
3467 self.assertEqual(len(self.builds), 2)
3468 self.assertEqual(self.builds[0].name, 'project-test1')
3469 self.assertEqual(self.builds[1].name, 'project-test2')
3470
James E. Blair08d19992016-08-10 15:25:31 -07003471 self.launch_server.release('project-.*')
Clark Boylan7603a372014-01-21 11:43:20 -08003472 self.waitUntilSettled()
3473
3474 # C was successfully merged so window is increased to 2.
3475 self.assertEqual(queue.window, 2)
3476 self.assertEqual(queue.window_floor, 1)
3477 self.assertEqual(C.data['status'], 'MERGED')
Joshua Heskethba8776a2014-01-12 14:35:40 +08003478
James E. Blairec056492016-07-22 09:45:56 -07003479 @skip("Disabled for early v3 development")
Joshua Heskethba8776a2014-01-12 14:35:40 +08003480 def test_worker_update_metadata(self):
3481 "Test if a worker can send back metadata about itself"
James E. Blair08d19992016-08-10 15:25:31 -07003482 self.launch_server.hold_jobs_in_build = True
Joshua Heskethba8776a2014-01-12 14:35:40 +08003483
3484 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07003485 A.addApproval('code-review', 2)
3486 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Heskethba8776a2014-01-12 14:35:40 +08003487 self.waitUntilSettled()
3488
3489 self.assertEqual(len(self.launcher.builds), 1)
3490
3491 self.log.debug('Current builds:')
3492 self.log.debug(self.launcher.builds)
3493
3494 start = time.time()
3495 while True:
3496 if time.time() - start > 10:
3497 raise Exception("Timeout waiting for gearman server to report "
3498 + "back to the client")
3499 build = self.launcher.builds.values()[0]
3500 if build.worker.name == "My Worker":
3501 break
3502 else:
3503 time.sleep(0)
3504
3505 self.log.debug(build)
3506 self.assertEqual("My Worker", build.worker.name)
3507 self.assertEqual("localhost", build.worker.hostname)
3508 self.assertEqual(['127.0.0.1', '192.168.1.1'], build.worker.ips)
3509 self.assertEqual("zuul.example.org", build.worker.fqdn)
3510 self.assertEqual("FakeBuilder", build.worker.program)
3511 self.assertEqual("v1.1", build.worker.version)
3512 self.assertEqual({'something': 'else'}, build.worker.extra)
3513
James E. Blair08d19992016-08-10 15:25:31 -07003514 self.launch_server.hold_jobs_in_build = False
3515 self.launch_server.release()
Joshua Heskethba8776a2014-01-12 14:35:40 +08003516 self.waitUntilSettled()
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003517
James E. Blairec056492016-07-22 09:45:56 -07003518 @skip("Disabled for early v3 development")
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003519 def test_footer_message(self):
3520 "Test a pipeline's footer message is correctly added to the report."
James E. Blairf84026c2015-12-08 16:11:46 -08003521 self.updateConfigLayout(
3522 'tests/fixtures/layout-footer-message.yaml')
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003523 self.sched.reconfigure(self.config)
3524 self.registerJobs()
3525
3526 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07003527 A.addApproval('code-review', 2)
James E. Blair08d19992016-08-10 15:25:31 -07003528 self.launch_server.failJob('test1', A)
James E. Blair8b5408c2016-08-08 15:37:46 -07003529 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003530 self.waitUntilSettled()
3531
3532 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07003533 B.addApproval('code-review', 2)
3534 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003535 self.waitUntilSettled()
3536
3537 self.assertEqual(2, len(self.smtp_messages))
3538
3539 failure_body = """\
3540Build failed. For information on how to proceed, see \
3541http://wiki.example.org/Test_Failures
3542
3543- test1 http://logs.example.com/1/1/gate/test1/0 : FAILURE in 0s
3544- test2 http://logs.example.com/1/1/gate/test2/1 : SUCCESS in 0s
3545
3546For CI problems and help debugging, contact ci@example.org"""
3547
3548 success_body = """\
3549Build succeeded.
3550
3551- test1 http://logs.example.com/2/1/gate/test1/2 : SUCCESS in 0s
3552- test2 http://logs.example.com/2/1/gate/test2/3 : SUCCESS in 0s
3553
3554For CI problems and help debugging, contact ci@example.org"""
3555
3556 self.assertEqual(failure_body, self.smtp_messages[0]['body'])
3557 self.assertEqual(success_body, self.smtp_messages[1]['body'])
Joshua Heskethb7179772014-01-30 23:30:46 +11003558
James E. Blairec056492016-07-22 09:45:56 -07003559 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003560 def test_merge_failure_reporters(self):
3561 """Check that the config is set up correctly"""
3562
James E. Blairf84026c2015-12-08 16:11:46 -08003563 self.updateConfigLayout(
3564 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003565 self.sched.reconfigure(self.config)
3566 self.registerJobs()
3567
3568 self.assertEqual(
Jeremy Stanley1c2c3c22015-06-15 21:23:19 +00003569 "Merge Failed.\n\nThis change or one of its cross-repo "
3570 "dependencies was unable to be automatically merged with the "
3571 "current state of its repository. Please rebase the change and "
3572 "upload a new patchset.",
Joshua Heskethb7179772014-01-30 23:30:46 +11003573 self.sched.layout.pipelines['check'].merge_failure_message)
3574 self.assertEqual(
3575 "The merge failed! For more information...",
3576 self.sched.layout.pipelines['gate'].merge_failure_message)
3577
3578 self.assertEqual(
3579 len(self.sched.layout.pipelines['check'].merge_failure_actions), 1)
3580 self.assertEqual(
3581 len(self.sched.layout.pipelines['gate'].merge_failure_actions), 2)
3582
3583 self.assertTrue(isinstance(
Joshua Heskethde958652015-11-10 19:19:50 +11003584 self.sched.layout.pipelines['check'].merge_failure_actions[0],
3585 zuul.reporter.gerrit.GerritReporter))
Joshua Heskethb7179772014-01-30 23:30:46 +11003586
3587 self.assertTrue(
3588 (
3589 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003590 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003591 zuul.reporter.smtp.SMTPReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003592 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003593 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003594 zuul.reporter.gerrit.GerritReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003595 ) or (
3596 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003597 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003598 zuul.reporter.gerrit.GerritReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003599 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003600 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003601 zuul.reporter.smtp.SMTPReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003602 )
3603 )
3604
James E. Blairec056492016-07-22 09:45:56 -07003605 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003606 def test_merge_failure_reports(self):
3607 """Check that when a change fails to merge the correct message is sent
3608 to the correct reporter"""
James E. Blairf84026c2015-12-08 16:11:46 -08003609 self.updateConfigLayout(
3610 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003611 self.sched.reconfigure(self.config)
3612 self.registerJobs()
3613
3614 # Check a test failure isn't reported to SMTP
3615 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07003616 A.addApproval('code-review', 2)
James E. Blair08d19992016-08-10 15:25:31 -07003617 self.launch_server.failJob('project-test1', A)
James E. Blair8b5408c2016-08-08 15:37:46 -07003618 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Heskethb7179772014-01-30 23:30:46 +11003619 self.waitUntilSettled()
3620
3621 self.assertEqual(3, len(self.history)) # 3 jobs
3622 self.assertEqual(0, len(self.smtp_messages))
3623
3624 # Check a merge failure is reported to SMTP
3625 # B should be merged, but C will conflict with B
3626 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3627 B.addPatchset(['conflict'])
3628 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3629 C.addPatchset(['conflict'])
James E. Blair8b5408c2016-08-08 15:37:46 -07003630 B.addApproval('code-review', 2)
3631 C.addApproval('code-review', 2)
3632 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
3633 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
Joshua Heskethb7179772014-01-30 23:30:46 +11003634 self.waitUntilSettled()
3635
3636 self.assertEqual(6, len(self.history)) # A and B jobs
3637 self.assertEqual(1, len(self.smtp_messages))
3638 self.assertEqual('The merge failed! For more information...',
3639 self.smtp_messages[0]['body'])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003640
James E. Blairec056492016-07-22 09:45:56 -07003641 @skip("Disabled for early v3 development")
James E. Blairf760f0e2016-02-09 08:44:52 -08003642 def test_default_merge_failure_reports(self):
3643 """Check that the default merge failure reports are correct."""
3644
3645 # A should report success, B should report merge failure.
3646 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3647 A.addPatchset(['conflict'])
3648 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3649 B.addPatchset(['conflict'])
James E. Blair8b5408c2016-08-08 15:37:46 -07003650 A.addApproval('code-review', 2)
3651 B.addApproval('code-review', 2)
3652 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
3653 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blairf760f0e2016-02-09 08:44:52 -08003654 self.waitUntilSettled()
3655
3656 self.assertEqual(3, len(self.history)) # A jobs
3657 self.assertEqual(A.reported, 2)
3658 self.assertEqual(B.reported, 2)
3659 self.assertEqual(A.data['status'], 'MERGED')
3660 self.assertEqual(B.data['status'], 'NEW')
3661 self.assertIn('Build succeeded', A.messages[1])
3662 self.assertIn('Merge Failed', B.messages[1])
3663 self.assertIn('automatically merged', B.messages[1])
3664 self.assertNotIn('logs.example.com', B.messages[1])
3665 self.assertNotIn('SKIPPED', B.messages[1])
3666
James E. Blairec056492016-07-22 09:45:56 -07003667 @skip("Disabled for early v3 development")
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003668 def test_swift_instructions(self):
3669 "Test that the correct swift instructions are sent to the workers"
James E. Blairf84026c2015-12-08 16:11:46 -08003670 self.updateConfigLayout(
3671 'tests/fixtures/layout-swift.yaml')
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003672 self.sched.reconfigure(self.config)
3673 self.registerJobs()
3674
James E. Blair08d19992016-08-10 15:25:31 -07003675 self.launch_server.hold_jobs_in_build = True
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003676 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3677
James E. Blair8b5408c2016-08-08 15:37:46 -07003678 A.addApproval('code-review', 2)
3679 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003680 self.waitUntilSettled()
3681
3682 self.assertEqual(
3683 "https://storage.example.org/V1/AUTH_account/merge_logs/1/1/1/"
3684 "gate/test-merge/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003685 self.builds[0].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003686 self.assertEqual(5,
3687 len(self.builds[0].parameters['SWIFT_logs_HMAC_BODY'].
3688 split('\n')))
3689 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[0].parameters)
3690
3691 self.assertEqual(
3692 "https://storage.example.org/V1/AUTH_account/logs/1/1/1/"
3693 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003694 self.builds[1].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003695 self.assertEqual(5,
3696 len(self.builds[1].parameters['SWIFT_logs_HMAC_BODY'].
3697 split('\n')))
3698 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[1].parameters)
3699
3700 self.assertEqual(
3701 "https://storage.example.org/V1/AUTH_account/stash/1/1/1/"
3702 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003703 self.builds[1].parameters['SWIFT_MOSTLY_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003704 self.assertEqual(5,
3705 len(self.builds[1].
3706 parameters['SWIFT_MOSTLY_HMAC_BODY'].split('\n')))
3707 self.assertIn('SWIFT_MOSTLY_SIGNATURE', self.builds[1].parameters)
3708
James E. Blair08d19992016-08-10 15:25:31 -07003709 self.launch_server.hold_jobs_in_build = False
3710 self.launch_server.release()
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003711 self.waitUntilSettled()
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003712
3713 def test_client_get_running_jobs(self):
3714 "Test that the RPC client can get a list of running jobs"
James E. Blair08d19992016-08-10 15:25:31 -07003715 self.launch_server.hold_jobs_in_build = True
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003716 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07003717 A.addApproval('code-review', 2)
3718 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003719 self.waitUntilSettled()
3720
3721 client = zuul.rpcclient.RPCClient('127.0.0.1',
3722 self.gearman_server.port)
3723
3724 # Wait for gearman server to send the initial workData back to zuul
3725 start = time.time()
3726 while True:
3727 if time.time() - start > 10:
3728 raise Exception("Timeout waiting for gearman server to report "
3729 + "back to the client")
Clint Byrum78a69772016-12-05 10:52:07 -08003730 build = self.launch_client.builds.values()[0]
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003731 if build.worker.name == "My Worker":
3732 break
3733 else:
3734 time.sleep(0)
3735
3736 running_items = client.get_running_jobs()
3737
3738 self.assertEqual(1, len(running_items))
3739 running_item = running_items[0]
3740 self.assertEqual([], running_item['failing_reasons'])
3741 self.assertEqual([], running_item['items_behind'])
3742 self.assertEqual('https://hostname/1', running_item['url'])
3743 self.assertEqual(None, running_item['item_ahead'])
3744 self.assertEqual('org/project', running_item['project'])
3745 self.assertEqual(None, running_item['remaining_time'])
3746 self.assertEqual(True, running_item['active'])
3747 self.assertEqual('1,1', running_item['id'])
3748
3749 self.assertEqual(3, len(running_item['jobs']))
3750 for job in running_item['jobs']:
3751 if job['name'] == 'project-merge':
3752 self.assertEqual('project-merge', job['name'])
3753 self.assertEqual('gate', job['pipeline'])
3754 self.assertEqual(False, job['retry'])
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003755 self.assertEqual('https://server/job/project-merge/0/',
3756 job['url'])
3757 self.assertEqual(7, len(job['worker']))
3758 self.assertEqual(False, job['canceled'])
3759 self.assertEqual(True, job['voting'])
3760 self.assertEqual(None, job['result'])
3761 self.assertEqual('gate', job['pipeline'])
3762 break
3763
James E. Blair08d19992016-08-10 15:25:31 -07003764 self.launch_server.hold_jobs_in_build = False
3765 self.launch_server.release()
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003766 self.waitUntilSettled()
3767
3768 running_items = client.get_running_jobs()
3769 self.assertEqual(0, len(running_items))
James E. Blairbadc1ad2014-04-28 13:55:14 -07003770
3771 def test_nonvoting_pipeline(self):
3772 "Test that a nonvoting pipeline (experimental) can still report"
3773
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003774 A = self.fake_gerrit.addFakeChange('org/experimental-project',
3775 'master', 'A')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003776 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
3777 self.waitUntilSettled()
Paul Belanger15e3e202016-10-14 16:27:34 -04003778
3779 self.assertEqual(self.getJobFromHistory('project-merge').result,
3780 'SUCCESS')
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003781 self.assertEqual(
3782 self.getJobFromHistory('experimental-project-test').result,
3783 'SUCCESS')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003784 self.assertEqual(A.reported, 1)
James E. Blair5ee24252014-12-30 10:12:29 -08003785
3786 def test_crd_gate(self):
3787 "Test cross-repo dependencies"
3788 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3789 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07003790 A.addApproval('code-review', 2)
3791 B.addApproval('code-review', 2)
James E. Blair5ee24252014-12-30 10:12:29 -08003792
3793 AM2 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM2')
3794 AM1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM1')
3795 AM2.setMerged()
3796 AM1.setMerged()
3797
3798 BM2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM2')
3799 BM1 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM1')
3800 BM2.setMerged()
3801 BM1.setMerged()
3802
3803 # A -> AM1 -> AM2
3804 # B -> BM1 -> BM2
3805 # A Depends-On: B
3806 # M2 is here to make sure it is never queried. If it is, it
3807 # means zuul is walking down the entire history of merged
3808 # changes.
3809
3810 B.setDependsOn(BM1, 1)
3811 BM1.setDependsOn(BM2, 1)
3812
3813 A.setDependsOn(AM1, 1)
3814 AM1.setDependsOn(AM2, 1)
3815
3816 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3817 A.subject, B.data['id'])
3818
James E. Blair8b5408c2016-08-08 15:37:46 -07003819 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08003820 self.waitUntilSettled()
3821
3822 self.assertEqual(A.data['status'], 'NEW')
3823 self.assertEqual(B.data['status'], 'NEW')
3824
Paul Belanger5dccbe72016-11-14 11:17:37 -05003825 for connection in self.connections.connections.values():
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11003826 connection.maintainCache([])
James E. Blair5ee24252014-12-30 10:12:29 -08003827
James E. Blair08d19992016-08-10 15:25:31 -07003828 self.launch_server.hold_jobs_in_build = True
James E. Blair8b5408c2016-08-08 15:37:46 -07003829 B.addApproval('approved', 1)
3830 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08003831 self.waitUntilSettled()
3832
James E. Blair08d19992016-08-10 15:25:31 -07003833 self.launch_server.release('.*-merge')
James E. Blair5ee24252014-12-30 10:12:29 -08003834 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003835 self.launch_server.release('.*-merge')
James E. Blair5ee24252014-12-30 10:12:29 -08003836 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003837 self.launch_server.hold_jobs_in_build = False
3838 self.launch_server.release()
James E. Blair5ee24252014-12-30 10:12:29 -08003839 self.waitUntilSettled()
3840
3841 self.assertEqual(AM2.queried, 0)
3842 self.assertEqual(BM2.queried, 0)
3843 self.assertEqual(A.data['status'], 'MERGED')
3844 self.assertEqual(B.data['status'], 'MERGED')
3845 self.assertEqual(A.reported, 2)
3846 self.assertEqual(B.reported, 2)
3847
Paul Belanger5dccbe72016-11-14 11:17:37 -05003848 changes = self.getJobFromHistory(
3849 'project-merge', 'org/project1').changes
3850 self.assertEqual(changes, '2,1 1,1')
James E. Blair8f78d882015-02-05 08:51:37 -08003851
3852 def test_crd_branch(self):
3853 "Test cross-repo dependencies in multiple branches"
Paul Belanger6379db12016-11-14 13:57:54 -05003854
3855 self.create_branch('org/project2', 'mp')
James E. Blair8f78d882015-02-05 08:51:37 -08003856 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3857 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3858 C = self.fake_gerrit.addFakeChange('org/project2', 'mp', 'C')
3859 C.data['id'] = B.data['id']
James E. Blair8b5408c2016-08-08 15:37:46 -07003860 A.addApproval('code-review', 2)
3861 B.addApproval('code-review', 2)
3862 C.addApproval('code-review', 2)
James E. Blair8f78d882015-02-05 08:51:37 -08003863
3864 # A Depends-On: B+C
3865 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3866 A.subject, B.data['id'])
3867
James E. Blair08d19992016-08-10 15:25:31 -07003868 self.launch_server.hold_jobs_in_build = True
James E. Blair8b5408c2016-08-08 15:37:46 -07003869 B.addApproval('approved', 1)
3870 C.addApproval('approved', 1)
3871 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair8f78d882015-02-05 08:51:37 -08003872 self.waitUntilSettled()
3873
James E. Blair08d19992016-08-10 15:25:31 -07003874 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003875 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003876 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003877 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003878 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003879 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003880 self.launch_server.hold_jobs_in_build = False
3881 self.launch_server.release()
James E. Blair8f78d882015-02-05 08:51:37 -08003882 self.waitUntilSettled()
3883
3884 self.assertEqual(A.data['status'], 'MERGED')
3885 self.assertEqual(B.data['status'], 'MERGED')
3886 self.assertEqual(C.data['status'], 'MERGED')
3887 self.assertEqual(A.reported, 2)
3888 self.assertEqual(B.reported, 2)
3889 self.assertEqual(C.reported, 2)
3890
Paul Belanger6379db12016-11-14 13:57:54 -05003891 changes = self.getJobFromHistory(
3892 'project-merge', 'org/project1').changes
3893 self.assertEqual(changes, '2,1 3,1 1,1')
James E. Blair8f78d882015-02-05 08:51:37 -08003894
3895 def test_crd_multiline(self):
3896 "Test multiple depends-on lines in commit"
3897 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3898 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3899 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07003900 A.addApproval('code-review', 2)
3901 B.addApproval('code-review', 2)
3902 C.addApproval('code-review', 2)
James E. Blair8f78d882015-02-05 08:51:37 -08003903
3904 # A Depends-On: B+C
3905 A.data['commitMessage'] = '%s\n\nDepends-On: %s\nDepends-On: %s\n' % (
3906 A.subject, B.data['id'], C.data['id'])
3907
James E. Blair08d19992016-08-10 15:25:31 -07003908 self.launch_server.hold_jobs_in_build = True
James E. Blair8b5408c2016-08-08 15:37:46 -07003909 B.addApproval('approved', 1)
3910 C.addApproval('approved', 1)
3911 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair8f78d882015-02-05 08:51:37 -08003912 self.waitUntilSettled()
3913
James E. Blair08d19992016-08-10 15:25:31 -07003914 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003915 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003916 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003917 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003918 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003919 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003920 self.launch_server.hold_jobs_in_build = False
3921 self.launch_server.release()
James E. Blair8f78d882015-02-05 08:51:37 -08003922 self.waitUntilSettled()
3923
3924 self.assertEqual(A.data['status'], 'MERGED')
3925 self.assertEqual(B.data['status'], 'MERGED')
3926 self.assertEqual(C.data['status'], 'MERGED')
3927 self.assertEqual(A.reported, 2)
3928 self.assertEqual(B.reported, 2)
3929 self.assertEqual(C.reported, 2)
3930
Paul Belanger5dccbe72016-11-14 11:17:37 -05003931 changes = self.getJobFromHistory(
3932 'project-merge', 'org/project1').changes
3933 self.assertEqual(changes, '2,1 3,1 1,1')
James E. Blair5ee24252014-12-30 10:12:29 -08003934
3935 def test_crd_unshared_gate(self):
3936 "Test cross-repo dependencies in unshared gate queues"
3937 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3938 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07003939 A.addApproval('code-review', 2)
3940 B.addApproval('code-review', 2)
James E. Blair5ee24252014-12-30 10:12:29 -08003941
3942 # A Depends-On: B
3943 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3944 A.subject, B.data['id'])
3945
3946 # A and B do not share a queue, make sure that A is unable to
3947 # enqueue B (and therefore, A is unable to be enqueued).
James E. Blair8b5408c2016-08-08 15:37:46 -07003948 B.addApproval('approved', 1)
3949 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08003950 self.waitUntilSettled()
3951
3952 self.assertEqual(A.data['status'], 'NEW')
3953 self.assertEqual(B.data['status'], 'NEW')
3954 self.assertEqual(A.reported, 0)
3955 self.assertEqual(B.reported, 0)
3956 self.assertEqual(len(self.history), 0)
3957
3958 # Enqueue and merge B alone.
James E. Blair8b5408c2016-08-08 15:37:46 -07003959 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08003960 self.waitUntilSettled()
3961
3962 self.assertEqual(B.data['status'], 'MERGED')
3963 self.assertEqual(B.reported, 2)
3964
3965 # Now that B is merged, A should be able to be enqueued and
3966 # merged.
James E. Blair8b5408c2016-08-08 15:37:46 -07003967 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08003968 self.waitUntilSettled()
3969
3970 self.assertEqual(A.data['status'], 'MERGED')
3971 self.assertEqual(A.reported, 2)
3972
James E. Blair96698e22015-04-02 07:48:21 -07003973 def test_crd_gate_reverse(self):
3974 "Test reverse cross-repo dependencies"
3975 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3976 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07003977 A.addApproval('code-review', 2)
3978 B.addApproval('code-review', 2)
James E. Blair96698e22015-04-02 07:48:21 -07003979
3980 # A Depends-On: B
3981
3982 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3983 A.subject, B.data['id'])
3984
James E. Blair8b5408c2016-08-08 15:37:46 -07003985 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair96698e22015-04-02 07:48:21 -07003986 self.waitUntilSettled()
3987
3988 self.assertEqual(A.data['status'], 'NEW')
3989 self.assertEqual(B.data['status'], 'NEW')
3990
James E. Blair08d19992016-08-10 15:25:31 -07003991 self.launch_server.hold_jobs_in_build = True
James E. Blair8b5408c2016-08-08 15:37:46 -07003992 A.addApproval('approved', 1)
3993 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair96698e22015-04-02 07:48:21 -07003994 self.waitUntilSettled()
3995
James E. Blair08d19992016-08-10 15:25:31 -07003996 self.launch_server.release('.*-merge')
James E. Blair96698e22015-04-02 07:48:21 -07003997 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003998 self.launch_server.release('.*-merge')
James E. Blair96698e22015-04-02 07:48:21 -07003999 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07004000 self.launch_server.hold_jobs_in_build = False
4001 self.launch_server.release()
James E. Blair96698e22015-04-02 07:48:21 -07004002 self.waitUntilSettled()
4003
4004 self.assertEqual(A.data['status'], 'MERGED')
4005 self.assertEqual(B.data['status'], 'MERGED')
4006 self.assertEqual(A.reported, 2)
4007 self.assertEqual(B.reported, 2)
4008
Paul Belanger5dccbe72016-11-14 11:17:37 -05004009 changes = self.getJobFromHistory(
4010 'project-merge', 'org/project1').changes
4011 self.assertEqual(changes, '2,1 1,1')
James E. Blair96698e22015-04-02 07:48:21 -07004012
James E. Blair5ee24252014-12-30 10:12:29 -08004013 def test_crd_cycle(self):
4014 "Test cross-repo dependency cycles"
4015 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4016 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07004017 A.addApproval('code-review', 2)
4018 B.addApproval('code-review', 2)
James E. Blair5ee24252014-12-30 10:12:29 -08004019
4020 # A -> B -> A (via commit-depends)
4021
4022 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4023 A.subject, B.data['id'])
4024 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4025 B.subject, A.data['id'])
4026
James E. Blair8b5408c2016-08-08 15:37:46 -07004027 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08004028 self.waitUntilSettled()
4029
4030 self.assertEqual(A.reported, 0)
4031 self.assertEqual(B.reported, 0)
4032 self.assertEqual(A.data['status'], 'NEW')
4033 self.assertEqual(B.data['status'], 'NEW')
James E. Blairbfb8e042014-12-30 17:01:44 -08004034
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004035 def test_crd_gate_unknown(self):
4036 "Test unknown projects in dependent pipeline"
4037 self.init_repo("org/unknown")
4038 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4039 B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07004040 A.addApproval('code-review', 2)
4041 B.addApproval('code-review', 2)
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004042
4043 # A Depends-On: B
4044 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4045 A.subject, B.data['id'])
4046
James E. Blair8b5408c2016-08-08 15:37:46 -07004047 B.addApproval('approved', 1)
4048 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004049 self.waitUntilSettled()
4050
4051 # Unknown projects cannot share a queue with any other
4052 # since they don't have common jobs with any other (they have no jobs).
4053 # Changes which depend on unknown project changes
4054 # should not be processed in dependent pipeline
4055 self.assertEqual(A.data['status'], 'NEW')
4056 self.assertEqual(B.data['status'], 'NEW')
4057 self.assertEqual(A.reported, 0)
4058 self.assertEqual(B.reported, 0)
4059 self.assertEqual(len(self.history), 0)
4060
4061 # Simulate change B being gated outside this layout
James E. Blair8b5408c2016-08-08 15:37:46 -07004062 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004063 B.setMerged()
4064 self.waitUntilSettled()
4065 self.assertEqual(len(self.history), 0)
4066
4067 # Now that B is merged, A should be able to be enqueued and
4068 # merged.
James E. Blair8b5408c2016-08-08 15:37:46 -07004069 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004070 self.waitUntilSettled()
4071
4072 self.assertEqual(A.data['status'], 'MERGED')
4073 self.assertEqual(A.reported, 2)
4074 self.assertEqual(B.data['status'], 'MERGED')
4075 self.assertEqual(B.reported, 0)
4076
James E. Blairbfb8e042014-12-30 17:01:44 -08004077 def test_crd_check(self):
4078 "Test cross-repo dependencies in independent pipelines"
4079
Paul Belangerb30342b2016-11-14 12:30:43 -05004080 self.launch_server.hold_jobs_in_build = True
James E. Blairbfb8e042014-12-30 17:01:44 -08004081 self.gearman_server.hold_jobs_in_queue = True
4082 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4083 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4084
4085 # A Depends-On: B
4086 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4087 A.subject, B.data['id'])
4088
4089 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4090 self.waitUntilSettled()
4091
4092 queue = self.gearman_server.getQueue()
4093 ref = self.getParameter(queue[-1], 'ZUUL_REF')
4094 self.gearman_server.hold_jobs_in_queue = False
4095 self.gearman_server.release()
4096 self.waitUntilSettled()
4097
Paul Belangerb30342b2016-11-14 12:30:43 -05004098 self.launch_server.release('.*-merge')
4099 self.waitUntilSettled()
4100
4101 path = os.path.join(self.builds[0].jobdir.git_root, "org/project1")
James E. Blairbfb8e042014-12-30 17:01:44 -08004102 repo = git.Repo(path)
4103 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4104 repo_messages.reverse()
Paul Belangerb30342b2016-11-14 12:30:43 -05004105 correct_messages = [
4106 'initial commit', 'add content from fixture', 'A-1']
James E. Blairbfb8e042014-12-30 17:01:44 -08004107 self.assertEqual(repo_messages, correct_messages)
4108
Paul Belangerb30342b2016-11-14 12:30:43 -05004109 path = os.path.join(self.builds[0].jobdir.git_root, "org/project2")
James E. Blairbfb8e042014-12-30 17:01:44 -08004110 repo = git.Repo(path)
4111 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4112 repo_messages.reverse()
Paul Belangerb30342b2016-11-14 12:30:43 -05004113 correct_messages = [
4114 'initial commit', 'add content from fixture', 'B-1']
James E. Blairbfb8e042014-12-30 17:01:44 -08004115 self.assertEqual(repo_messages, correct_messages)
4116
Paul Belangerb30342b2016-11-14 12:30:43 -05004117 self.launch_server.hold_jobs_in_build = False
4118 self.launch_server.release()
4119 self.waitUntilSettled()
4120
James E. Blairbfb8e042014-12-30 17:01:44 -08004121 self.assertEqual(A.data['status'], 'NEW')
4122 self.assertEqual(B.data['status'], 'NEW')
4123 self.assertEqual(A.reported, 1)
4124 self.assertEqual(B.reported, 0)
4125
4126 self.assertEqual(self.history[0].changes, '2,1 1,1')
Paul Belangerb30342b2016-11-14 12:30:43 -05004127 tenant = self.sched.abide.tenants.get('tenant-one')
4128 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
James E. Blair8f78d882015-02-05 08:51:37 -08004129
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004130 def test_crd_check_git_depends(self):
4131 "Test single-repo dependencies in independent pipelines"
James E. Blairb8c16472015-05-05 14:55:26 -07004132 self.gearman_server.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004133 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4134 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4135
4136 # Add two git-dependent changes and make sure they both report
4137 # success.
4138 B.setDependsOn(A, 1)
4139 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4140 self.waitUntilSettled()
4141 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4142 self.waitUntilSettled()
4143
James E. Blairb8c16472015-05-05 14:55:26 -07004144 self.orderedRelease()
4145 self.gearman_server.hold_jobs_in_build = False
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004146 self.waitUntilSettled()
4147
4148 self.assertEqual(A.data['status'], 'NEW')
4149 self.assertEqual(B.data['status'], 'NEW')
4150 self.assertEqual(A.reported, 1)
4151 self.assertEqual(B.reported, 1)
4152
4153 self.assertEqual(self.history[0].changes, '1,1')
4154 self.assertEqual(self.history[-1].changes, '1,1 2,1')
Paul Belanger08136962016-11-03 17:57:38 -04004155 tenant = self.sched.abide.tenants.get('tenant-one')
4156 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004157
4158 self.assertIn('Build succeeded', A.messages[0])
4159 self.assertIn('Build succeeded', B.messages[0])
4160
4161 def test_crd_check_duplicate(self):
4162 "Test duplicate check in independent pipelines"
James E. Blair08d19992016-08-10 15:25:31 -07004163 self.launch_server.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004164 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4165 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
Paul Belanger08136962016-11-03 17:57:38 -04004166 tenant = self.sched.abide.tenants.get('tenant-one')
4167 check_pipeline = tenant.layout.pipelines['check']
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004168
4169 # Add two git-dependent changes...
4170 B.setDependsOn(A, 1)
4171 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4172 self.waitUntilSettled()
4173 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4174
4175 # ...make sure the live one is not duplicated...
4176 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4177 self.waitUntilSettled()
4178 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4179
4180 # ...but the non-live one is able to be.
4181 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4182 self.waitUntilSettled()
4183 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4184
Clark Boylandd849822015-03-02 12:38:14 -08004185 # Release jobs in order to avoid races with change A jobs
4186 # finishing before change B jobs.
James E. Blaird7650852015-05-07 15:47:37 -07004187 self.orderedRelease()
James E. Blair08d19992016-08-10 15:25:31 -07004188 self.launch_server.hold_jobs_in_build = False
4189 self.launch_server.release()
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004190 self.waitUntilSettled()
4191
4192 self.assertEqual(A.data['status'], 'NEW')
4193 self.assertEqual(B.data['status'], 'NEW')
4194 self.assertEqual(A.reported, 1)
4195 self.assertEqual(B.reported, 1)
4196
4197 self.assertEqual(self.history[0].changes, '1,1 2,1')
4198 self.assertEqual(self.history[1].changes, '1,1')
Paul Belanger08136962016-11-03 17:57:38 -04004199 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004200
4201 self.assertIn('Build succeeded', A.messages[0])
4202 self.assertIn('Build succeeded', B.messages[0])
4203
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004204 def _test_crd_check_reconfiguration(self, project1, project2):
James E. Blair8f78d882015-02-05 08:51:37 -08004205 "Test cross-repo dependencies re-enqueued in independent pipelines"
4206
4207 self.gearman_server.hold_jobs_in_queue = True
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004208 A = self.fake_gerrit.addFakeChange(project1, 'master', 'A')
4209 B = self.fake_gerrit.addFakeChange(project2, 'master', 'B')
James E. Blair8f78d882015-02-05 08:51:37 -08004210
4211 # A Depends-On: B
4212 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4213 A.subject, B.data['id'])
4214
4215 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4216 self.waitUntilSettled()
4217
4218 self.sched.reconfigure(self.config)
4219
4220 # Make sure the items still share a change queue, and the
4221 # first one is not live.
Paul Belangerce4485f2016-11-11 17:01:56 -05004222 tenant = self.sched.abide.tenants.get('tenant-one')
4223 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 1)
4224 queue = tenant.layout.pipelines['check'].queues[0]
James E. Blair8f78d882015-02-05 08:51:37 -08004225 first_item = queue.queue[0]
4226 for item in queue.queue:
4227 self.assertEqual(item.queue, first_item.queue)
4228 self.assertFalse(first_item.live)
4229 self.assertTrue(queue.queue[1].live)
4230
4231 self.gearman_server.hold_jobs_in_queue = False
4232 self.gearman_server.release()
4233 self.waitUntilSettled()
4234
4235 self.assertEqual(A.data['status'], 'NEW')
4236 self.assertEqual(B.data['status'], 'NEW')
4237 self.assertEqual(A.reported, 1)
4238 self.assertEqual(B.reported, 0)
4239
4240 self.assertEqual(self.history[0].changes, '2,1 1,1')
Paul Belangerce4485f2016-11-11 17:01:56 -05004241 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
James E. Blair17dd6772015-02-09 14:45:18 -08004242
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004243 def test_crd_check_reconfiguration(self):
4244 self._test_crd_check_reconfiguration('org/project1', 'org/project2')
4245
4246 def test_crd_undefined_project(self):
4247 """Test that undefined projects in dependencies are handled for
4248 independent pipelines"""
4249 # It's a hack for fake gerrit,
4250 # as it implies repo creation upon the creation of any change
4251 self.init_repo("org/unknown")
4252 self._test_crd_check_reconfiguration('org/project1', 'org/unknown')
4253
James E. Blairec056492016-07-22 09:45:56 -07004254 @skip("Disabled for early v3 development")
James E. Blair17dd6772015-02-09 14:45:18 -08004255 def test_crd_check_ignore_dependencies(self):
4256 "Test cross-repo dependencies can be ignored"
James E. Blairf84026c2015-12-08 16:11:46 -08004257 self.updateConfigLayout(
4258 'tests/fixtures/layout-ignore-dependencies.yaml')
James E. Blair17dd6772015-02-09 14:45:18 -08004259 self.sched.reconfigure(self.config)
4260 self.registerJobs()
4261
4262 self.gearman_server.hold_jobs_in_queue = True
4263 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4264 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4265 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
4266
4267 # A Depends-On: B
4268 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4269 A.subject, B.data['id'])
4270 # C git-depends on B
4271 C.setDependsOn(B, 1)
4272 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4273 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4274 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4275 self.waitUntilSettled()
4276
4277 # Make sure none of the items share a change queue, and all
4278 # are live.
4279 check_pipeline = self.sched.layout.pipelines['check']
4280 self.assertEqual(len(check_pipeline.queues), 3)
4281 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4282 for item in check_pipeline.getAllItems():
4283 self.assertTrue(item.live)
4284
4285 self.gearman_server.hold_jobs_in_queue = False
4286 self.gearman_server.release()
4287 self.waitUntilSettled()
4288
4289 self.assertEqual(A.data['status'], 'NEW')
4290 self.assertEqual(B.data['status'], 'NEW')
4291 self.assertEqual(C.data['status'], 'NEW')
4292 self.assertEqual(A.reported, 1)
4293 self.assertEqual(B.reported, 1)
4294 self.assertEqual(C.reported, 1)
4295
4296 # Each job should have tested exactly one change
4297 for job in self.history:
4298 self.assertEqual(len(job.changes.split()), 1)
James E. Blair96698e22015-04-02 07:48:21 -07004299
James E. Blairec056492016-07-22 09:45:56 -07004300 @skip("Disabled for early v3 development")
James E. Blair96698e22015-04-02 07:48:21 -07004301 def test_crd_check_transitive(self):
4302 "Test transitive cross-repo dependencies"
4303 # Specifically, if A -> B -> C, and C gets a new patchset and
4304 # A gets a new patchset, ensure the test of A,2 includes B,1
4305 # and C,2 (not C,1 which would indicate stale data in the
4306 # cache for B).
4307 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4308 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4309 C = self.fake_gerrit.addFakeChange('org/project3', 'master', 'C')
4310
4311 # A Depends-On: B
4312 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4313 A.subject, B.data['id'])
4314
4315 # B Depends-On: C
4316 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4317 B.subject, C.data['id'])
4318
4319 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4320 self.waitUntilSettled()
4321 self.assertEqual(self.history[-1].changes, '3,1 2,1 1,1')
4322
4323 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4324 self.waitUntilSettled()
4325 self.assertEqual(self.history[-1].changes, '3,1 2,1')
4326
4327 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4328 self.waitUntilSettled()
4329 self.assertEqual(self.history[-1].changes, '3,1')
4330
4331 C.addPatchset()
4332 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(2))
4333 self.waitUntilSettled()
4334 self.assertEqual(self.history[-1].changes, '3,2')
4335
4336 A.addPatchset()
4337 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
4338 self.waitUntilSettled()
4339 self.assertEqual(self.history[-1].changes, '3,2 2,1 1,2')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004340
James E. Blaira8b90b32016-08-24 15:18:50 -07004341 def test_crd_check_unknown(self):
4342 "Test unknown projects in independent pipeline"
4343 self.init_repo("org/unknown")
4344 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4345 B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'D')
4346 # A Depends-On: B
4347 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4348 A.subject, B.data['id'])
4349
4350 # Make sure zuul has seen an event on B.
4351 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4352 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4353 self.waitUntilSettled()
4354
4355 self.assertEqual(A.data['status'], 'NEW')
4356 self.assertEqual(A.reported, 1)
4357 self.assertEqual(B.data['status'], 'NEW')
4358 self.assertEqual(B.reported, 0)
4359
James E. Blair92464a22016-04-05 10:21:26 -07004360 def test_crd_cycle_join(self):
4361 "Test an updated change creates a cycle"
4362 A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A')
4363
4364 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4365 self.waitUntilSettled()
4366
4367 # Create B->A
4368 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4369 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4370 B.subject, A.data['id'])
4371 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4372 self.waitUntilSettled()
4373
4374 # Update A to add A->B (a cycle).
4375 A.addPatchset()
4376 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4377 A.subject, B.data['id'])
4378 # Normally we would submit the patchset-created event for
4379 # processing here, however, we have no way of noting whether
4380 # the dependency cycle detection correctly raised an
4381 # exception, so instead, we reach into the source driver and
4382 # call the method that would ultimately be called by the event
4383 # processing.
4384
Paul Belanger0e155e22016-11-14 14:12:23 -05004385 tenant = self.sched.abide.tenants.get('tenant-one')
4386 source = tenant.layout.pipelines['gate'].source
4387
4388 # TODO(pabelanger): As we add more source / trigger APIs we should make
4389 # it easier for users to create events for testing.
4390 event = zuul.model.TriggerEvent()
4391 event.trigger_name = 'gerrit'
4392 event.change_number = '1'
4393 event.patch_number = '2'
James E. Blair92464a22016-04-05 10:21:26 -07004394 with testtools.ExpectedException(
4395 Exception, "Dependency cycle detected"):
Paul Belanger0e155e22016-11-14 14:12:23 -05004396 source.getChange(event, True)
James E. Blair92464a22016-04-05 10:21:26 -07004397 self.log.debug("Got expected dependency cycle exception")
4398
4399 # Now if we update B to remove the depends-on, everything
4400 # should be okay. B; A->B
4401
4402 B.addPatchset()
4403 B.data['commitMessage'] = '%s\n' % (B.subject,)
Paul Belanger0e155e22016-11-14 14:12:23 -05004404
4405 source.getChange(event, True)
4406 event.change_number = '2'
4407 source.getChange(event, True)
James E. Blair92464a22016-04-05 10:21:26 -07004408
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004409 def test_disable_at(self):
4410 "Test a pipeline will only report to the disabled trigger when failing"
4411
Paul Belanger7dc76e82016-11-11 16:51:08 -05004412 self.updateConfigLayout('layout-disabled-at')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004413 self.sched.reconfigure(self.config)
4414
Paul Belanger7dc76e82016-11-11 16:51:08 -05004415 tenant = self.sched.abide.tenants.get('openstack')
4416 self.assertEqual(3, tenant.layout.pipelines['check'].disable_at)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004417 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004418 0, tenant.layout.pipelines['check']._consecutive_failures)
4419 self.assertFalse(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004420
4421 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4422 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
4423 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
4424 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
4425 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
4426 F = self.fake_gerrit.addFakeChange('org/project', 'master', 'F')
4427 G = self.fake_gerrit.addFakeChange('org/project', 'master', 'G')
4428 H = self.fake_gerrit.addFakeChange('org/project', 'master', 'H')
4429 I = self.fake_gerrit.addFakeChange('org/project', 'master', 'I')
4430 J = self.fake_gerrit.addFakeChange('org/project', 'master', 'J')
4431 K = self.fake_gerrit.addFakeChange('org/project', 'master', 'K')
4432
James E. Blair08d19992016-08-10 15:25:31 -07004433 self.launch_server.failJob('project-test1', A)
4434 self.launch_server.failJob('project-test1', B)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004435 # Let C pass, resetting the counter
James E. Blair08d19992016-08-10 15:25:31 -07004436 self.launch_server.failJob('project-test1', D)
4437 self.launch_server.failJob('project-test1', E)
4438 self.launch_server.failJob('project-test1', F)
4439 self.launch_server.failJob('project-test1', G)
4440 self.launch_server.failJob('project-test1', H)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004441 # I also passes but should only report to the disabled reporters
James E. Blair08d19992016-08-10 15:25:31 -07004442 self.launch_server.failJob('project-test1', J)
4443 self.launch_server.failJob('project-test1', K)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004444
4445 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4446 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4447 self.waitUntilSettled()
4448
4449 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004450 2, tenant.layout.pipelines['check']._consecutive_failures)
4451 self.assertFalse(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004452
4453 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4454 self.waitUntilSettled()
4455
4456 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004457 0, tenant.layout.pipelines['check']._consecutive_failures)
4458 self.assertFalse(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004459
4460 self.fake_gerrit.addEvent(D.getPatchsetCreatedEvent(1))
4461 self.fake_gerrit.addEvent(E.getPatchsetCreatedEvent(1))
4462 self.fake_gerrit.addEvent(F.getPatchsetCreatedEvent(1))
4463 self.waitUntilSettled()
4464
4465 # We should be disabled now
4466 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004467 3, tenant.layout.pipelines['check']._consecutive_failures)
4468 self.assertTrue(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004469
4470 # We need to wait between each of these patches to make sure the
4471 # smtp messages come back in an expected order
4472 self.fake_gerrit.addEvent(G.getPatchsetCreatedEvent(1))
4473 self.waitUntilSettled()
4474 self.fake_gerrit.addEvent(H.getPatchsetCreatedEvent(1))
4475 self.waitUntilSettled()
4476 self.fake_gerrit.addEvent(I.getPatchsetCreatedEvent(1))
4477 self.waitUntilSettled()
4478
4479 # The first 6 (ABCDEF) jobs should have reported back to gerrt thus
4480 # leaving a message on each change
4481 self.assertEqual(1, len(A.messages))
4482 self.assertIn('Build failed.', A.messages[0])
4483 self.assertEqual(1, len(B.messages))
4484 self.assertIn('Build failed.', B.messages[0])
4485 self.assertEqual(1, len(C.messages))
4486 self.assertIn('Build succeeded.', C.messages[0])
4487 self.assertEqual(1, len(D.messages))
4488 self.assertIn('Build failed.', D.messages[0])
4489 self.assertEqual(1, len(E.messages))
4490 self.assertIn('Build failed.', E.messages[0])
4491 self.assertEqual(1, len(F.messages))
4492 self.assertIn('Build failed.', F.messages[0])
4493
4494 # The last 3 (GHI) would have only reported via smtp.
4495 self.assertEqual(3, len(self.smtp_messages))
4496 self.assertEqual(0, len(G.messages))
4497 self.assertIn('Build failed.', self.smtp_messages[0]['body'])
Paul Belanger7dc76e82016-11-11 16:51:08 -05004498 self.assertIn(
4499 'project-test1 https://server/job', self.smtp_messages[0]['body'])
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004500 self.assertEqual(0, len(H.messages))
4501 self.assertIn('Build failed.', self.smtp_messages[1]['body'])
Paul Belanger7dc76e82016-11-11 16:51:08 -05004502 self.assertIn(
4503 'project-test1 https://server/job', self.smtp_messages[1]['body'])
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004504 self.assertEqual(0, len(I.messages))
4505 self.assertIn('Build succeeded.', self.smtp_messages[2]['body'])
Paul Belanger7dc76e82016-11-11 16:51:08 -05004506 self.assertIn(
4507 'project-test1 https://server/job', self.smtp_messages[2]['body'])
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004508
4509 # Now reload the configuration (simulate a HUP) to check the pipeline
4510 # comes out of disabled
4511 self.sched.reconfigure(self.config)
4512
Paul Belanger7dc76e82016-11-11 16:51:08 -05004513 tenant = self.sched.abide.tenants.get('openstack')
4514
4515 self.assertEqual(3, tenant.layout.pipelines['check'].disable_at)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004516 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004517 0, tenant.layout.pipelines['check']._consecutive_failures)
4518 self.assertFalse(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004519
4520 self.fake_gerrit.addEvent(J.getPatchsetCreatedEvent(1))
4521 self.fake_gerrit.addEvent(K.getPatchsetCreatedEvent(1))
4522 self.waitUntilSettled()
4523
4524 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004525 2, tenant.layout.pipelines['check']._consecutive_failures)
4526 self.assertFalse(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004527
4528 # J and K went back to gerrit
4529 self.assertEqual(1, len(J.messages))
4530 self.assertIn('Build failed.', J.messages[0])
4531 self.assertEqual(1, len(K.messages))
4532 self.assertIn('Build failed.', K.messages[0])
4533 # No more messages reported via smtp
4534 self.assertEqual(3, len(self.smtp_messages))
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004535
Paul Belanger71d98172016-11-08 10:56:31 -05004536 def test_rerun_on_abort(self):
Clint Byrumdf0a55b2016-12-05 06:39:11 -08004537 "Test that if a launch server fails to run a job, it is run again"
Paul Belanger71d98172016-11-08 10:56:31 -05004538
4539 self.config.set('zuul', 'layout_config',
4540 'tests/fixtures/layout-abort-attempts.yaml')
4541 self.sched.reconfigure(self.config)
Clint Byrumdf0a55b2016-12-05 06:39:11 -08004542 self.launch_server.hold_jobs_in_build = True
Paul Belanger71d98172016-11-08 10:56:31 -05004543 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4544 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4545 self.waitUntilSettled()
4546
Clint Byrumdf0a55b2016-12-05 06:39:11 -08004547 self.launch_server.release('.*-merge')
Paul Belanger71d98172016-11-08 10:56:31 -05004548 self.waitUntilSettled()
4549
4550 self.assertEqual(len(self.builds), 2)
4551 self.builds[0].requeue = True
Clint Byrumdf0a55b2016-12-05 06:39:11 -08004552 self.launch_server.release('.*-test*')
Paul Belanger71d98172016-11-08 10:56:31 -05004553 self.waitUntilSettled()
4554
Clint Byrumdf0a55b2016-12-05 06:39:11 -08004555 for x in range(2):
4556 self.assertEqual(len(self.builds), 1,
4557 'len of builds at x=%d is wrong' % x)
Paul Belanger71d98172016-11-08 10:56:31 -05004558 self.builds[0].requeue = True
Clint Byrumdf0a55b2016-12-05 06:39:11 -08004559 self.launch_server.release('.*-test1')
Paul Belanger71d98172016-11-08 10:56:31 -05004560 self.waitUntilSettled()
4561
Clint Byrumdf0a55b2016-12-05 06:39:11 -08004562 self.launch_server.hold_jobs_in_build = False
4563 self.launch_server.release()
Paul Belanger71d98172016-11-08 10:56:31 -05004564 self.waitUntilSettled()
Clint Byrumdf0a55b2016-12-05 06:39:11 -08004565 self.assertEqual(len(self.history), 5)
Paul Belanger71d98172016-11-08 10:56:31 -05004566 self.assertEqual(self.countJobResults(self.history, 'SUCCESS'), 2)
4567 self.assertEqual(A.reported, 1)
4568 self.assertIn('RETRY_LIMIT', A.messages[0])
Joshua Hesketh3f7def32016-11-21 17:36:44 +11004569
Arieb6f068c2016-10-09 13:11:06 +03004570
4571class TestDuplicatePipeline(ZuulTestCase):
4572 tenant_config_file = 'config/duplicate-pipeline/main.yaml'
4573
4574 def test_duplicate_pipelines(self):
4575 "Test that a change matching multiple pipelines works"
4576
4577 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4578 self.fake_gerrit.addEvent(A.getChangeRestoredEvent())
4579 self.waitUntilSettled()
4580
4581 self.assertHistory([
4582 dict(name='project-test1', result='SUCCESS', changes='1,1',
4583 pipeline='dup1'),
4584 dict(name='project-test1', result='SUCCESS', changes='1,1',
4585 pipeline='dup2'),
Paul Belanger73a7d8e2016-11-09 11:12:42 -05004586 ], ordered=False)
Arieb6f068c2016-10-09 13:11:06 +03004587
4588 self.assertEqual(len(A.messages), 2)
4589
Paul Belangera46a3742016-11-09 14:23:03 -05004590 if 'dup1' in A.messages[0]:
4591 self.assertIn('dup1', A.messages[0])
4592 self.assertNotIn('dup2', A.messages[0])
4593 self.assertIn('project-test1', A.messages[0])
4594 self.assertIn('dup2', A.messages[1])
4595 self.assertNotIn('dup1', A.messages[1])
4596 self.assertIn('project-test1', A.messages[1])
4597 else:
4598 self.assertIn('dup1', A.messages[1])
4599 self.assertNotIn('dup2', A.messages[1])
4600 self.assertIn('project-test1', A.messages[1])
4601 self.assertIn('dup2', A.messages[0])
4602 self.assertNotIn('dup1', A.messages[0])
4603 self.assertIn('project-test1', A.messages[0])
Paul Belangerfac69ba2016-11-03 09:03:13 -04004604
4605
4606class TestSchedulerOneJobProject(ZuulTestCase):
4607 tenant_config_file = 'config/one-job-project/main.yaml'
4608
4609 def test_one_job_project(self):
4610 "Test that queueing works with one job"
4611 A = self.fake_gerrit.addFakeChange('org/one-job-project',
4612 'master', 'A')
4613 B = self.fake_gerrit.addFakeChange('org/one-job-project',
4614 'master', 'B')
4615 A.addApproval('code-review', 2)
4616 B.addApproval('code-review', 2)
4617 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
4618 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
4619 self.waitUntilSettled()
4620
4621 self.assertEqual(A.data['status'], 'MERGED')
4622 self.assertEqual(A.reported, 2)
4623 self.assertEqual(B.data['status'], 'MERGED')
4624 self.assertEqual(B.reported, 2)
Paul Belanger86085b32016-11-03 12:48:57 -04004625
4626
4627class TestSchedulerTemplatedProject(ZuulTestCase):
4628 tenant_config_file = 'config/templated-project/main.yaml'
4629
4630 def test_job_from_templates_launched(self):
4631 "Test whether a job generated via a template can be launched"
4632
4633 A = self.fake_gerrit.addFakeChange(
4634 'org/templated-project', 'master', 'A')
4635 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4636 self.waitUntilSettled()
4637
4638 self.assertEqual(self.getJobFromHistory('project-test1').result,
4639 'SUCCESS')
4640 self.assertEqual(self.getJobFromHistory('project-test2').result,
4641 'SUCCESS')
Paul Belanger3adf72f2016-11-03 14:57:31 -04004642
4643 def test_layered_templates(self):
4644 "Test whether a job generated via a template can be launched"
4645
4646 A = self.fake_gerrit.addFakeChange(
4647 'org/layered-project', 'master', 'A')
4648 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4649 self.waitUntilSettled()
4650
4651 self.assertEqual(self.getJobFromHistory('project-test1').result,
4652 'SUCCESS')
4653 self.assertEqual(self.getJobFromHistory('project-test2').result,
4654 'SUCCESS')
4655 self.assertEqual(self.getJobFromHistory('layered-project-test3'
4656 ).result, 'SUCCESS')
4657 self.assertEqual(self.getJobFromHistory('layered-project-test4'
4658 ).result, 'SUCCESS')
4659 self.assertEqual(self.getJobFromHistory('layered-project-foo-test5'
4660 ).result, 'SUCCESS')
4661 self.assertEqual(self.getJobFromHistory('project-test6').result,
4662 'SUCCESS')
Adam Gandelman94a60062016-11-21 16:43:14 -08004663
4664
4665class TestSchedulerSuccessURL(ZuulTestCase):
4666 tenant_config_file = 'config/success-url/main.yaml'
4667
4668 def test_success_url(self):
4669 "Ensure bad build params are ignored"
4670 self.sched.reconfigure(self.config)
4671 self.init_repo('org/docs')
4672
4673 A = self.fake_gerrit.addFakeChange('org/docs', 'master', 'A')
4674 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4675 self.waitUntilSettled()
4676
4677 # Both builds ran: docs-draft-test + docs-draft-test2
4678 self.assertEqual(len(self.history), 2)
4679
4680 # Grab build id
4681 uuid = self.history[0].uuid[:7]
4682
4683 # Two msgs: 'Starting...' + results
4684 self.assertEqual(len(self.smtp_messages), 2)
4685 body = self.smtp_messages[1]['body'].splitlines()
4686 self.assertEqual('Build succeeded.', body[0])
4687
4688 self.assertIn(
4689 '- docs-draft-test http://docs-draft.example.org/1/1/1/check/'
4690 'docs-draft-test/%s/publish-docs/' % uuid,
4691 body[2])
4692
4693 # NOTE: This default URL is currently hard-coded in launcher/server.py
4694 self.assertIn(
4695 '- docs-draft-test2 https://server/job',
4696 body[3])
Adam Gandelman8bd57102016-12-02 12:58:42 -08004697
4698
4699class TestSchedulerMergeModes(ZuulTestCase):
4700 tenant_config_file = 'config/merge-modes/main.yaml'
4701
4702 def _test_project_merge_mode(self, mode):
4703 self.launch_server.keep_jobdir = False
4704 project = 'org/project-%s' % mode
4705 self.launch_server.hold_jobs_in_build = True
4706 A = self.fake_gerrit.addFakeChange(project, 'master', 'A')
4707 B = self.fake_gerrit.addFakeChange(project, 'master', 'B')
4708 C = self.fake_gerrit.addFakeChange(project, 'master', 'C')
4709 A.addApproval('code-review', 2)
4710 B.addApproval('code-review', 2)
4711 C.addApproval('code-review', 2)
4712 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
4713 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
4714 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
4715 self.waitUntilSettled()
4716
4717 build = self.builds[-1]
4718 ref = self.getParameter(build, 'ZUUL_REF')
4719
4720 path = os.path.join(build.jobdir.git_root, project)
4721 repo = git.Repo(path)
4722 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4723 repo_messages.reverse()
4724
4725 self.launch_server.hold_jobs_in_build = False
4726 self.launch_server.release()
4727 self.waitUntilSettled()
4728
4729 return repo_messages
4730
4731 def _test_merge(self, mode):
4732 us_path = os.path.join(
4733 self.upstream_root, 'org/project-%s' % mode)
4734 expected_messages = [
4735 'initial commit',
4736 'add content from fixture',
4737 # the intermediate commits order is nondeterministic
4738 "Merge commit 'refs/changes/1/2/1' of %s into HEAD" % us_path,
4739 "Merge commit 'refs/changes/1/3/1' of %s into HEAD" % us_path,
4740 ]
4741 result = self._test_project_merge_mode(mode)
4742 self.assertEqual(result[:2], expected_messages[:2])
4743 self.assertEqual(result[-2:], expected_messages[-2:])
4744
4745 def test_project_merge_mode_merge(self):
4746 self._test_merge('merge')
4747
4748 def test_project_merge_mode_merge_resolve(self):
4749 self._test_merge('merge-resolve')
4750
4751 def test_project_merge_mode_cherrypick(self):
4752 expected_messages = [
4753 'initial commit',
4754 'add content from fixture',
4755 'A-1',
4756 'B-1',
4757 'C-1']
4758 result = self._test_project_merge_mode('cherry-pick')
4759 self.assertEqual(result, expected_messages)