blob: 8f27cd93a6a905b102cc2b05f7546756ef3d62a8 [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. Blairec056492016-07-22 09:45:56 -0700507 @skip("Disabled for early v3 development")
James E. Blaird466dc42012-07-31 10:42:56 -0700508 def test_failed_change_at_head_with_queue(self):
509 "Test that if a change at the head fails, queued jobs are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700510
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700511 self.gearman_server.hold_jobs_in_queue = True
James E. Blaird466dc42012-07-31 10:42:56 -0700512 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
513 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
514 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700515 A.addApproval('code-review', 2)
516 B.addApproval('code-review', 2)
517 C.addApproval('code-review', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700518
James E. Blair08d19992016-08-10 15:25:31 -0700519 self.launch_server.failJob('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700520
James E. Blair8b5408c2016-08-08 15:37:46 -0700521 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
522 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
523 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blaird466dc42012-07-31 10:42:56 -0700524
525 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700526 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400527 self.assertEqual(len(self.builds), 0)
528 self.assertEqual(len(queue), 1)
529 self.assertEqual(queue[0].name, 'build:project-merge')
530 self.assertTrue(self.job_has_changes(queue[0], A))
James E. Blaird466dc42012-07-31 10:42:56 -0700531
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700532 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700533 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700534 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700535 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700536 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700537 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700538 queue = self.gearman_server.getQueue()
James E. Blaird466dc42012-07-31 10:42:56 -0700539
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400540 self.assertEqual(len(self.builds), 0)
541 self.assertEqual(len(queue), 6)
542 self.assertEqual(queue[0].name, 'build:project-test1')
543 self.assertEqual(queue[1].name, 'build:project-test2')
544 self.assertEqual(queue[2].name, 'build:project-test1')
545 self.assertEqual(queue[3].name, 'build:project-test2')
546 self.assertEqual(queue[4].name, 'build:project-test1')
547 self.assertEqual(queue[5].name, 'build:project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700548
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700549 self.release(queue[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700550 self.waitUntilSettled()
551
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400552 self.assertEqual(len(self.builds), 0)
James E. Blair701c5b42013-06-06 09:34:59 -0700553 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400554 self.assertEqual(len(queue), 2) # project-test2, project-merge for B
555 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 0)
James E. Blaird466dc42012-07-31 10:42:56 -0700556
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700557 self.gearman_server.hold_jobs_in_queue = False
558 self.gearman_server.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700559 self.waitUntilSettled()
560
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400561 self.assertEqual(len(self.builds), 0)
562 self.assertEqual(len(self.history), 11)
563 self.assertEqual(A.data['status'], 'NEW')
564 self.assertEqual(B.data['status'], 'MERGED')
565 self.assertEqual(C.data['status'], 'MERGED')
566 self.assertEqual(A.reported, 2)
567 self.assertEqual(B.reported, 2)
568 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700569
James E. Blairec056492016-07-22 09:45:56 -0700570 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700571 def _test_time_database(self, iteration):
James E. Blair08d19992016-08-10 15:25:31 -0700572 self.launch_server.hold_jobs_in_build = True
James E. Blairce8a2132016-05-19 15:21:52 -0700573 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -0700574 A.addApproval('code-review', 2)
575 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blairce8a2132016-05-19 15:21:52 -0700576 self.waitUntilSettled()
577 time.sleep(2)
578
579 data = json.loads(self.sched.formatStatusJSON())
580 found_job = None
581 for pipeline in data['pipelines']:
582 if pipeline['name'] != 'gate':
583 continue
584 for queue in pipeline['change_queues']:
585 for head in queue['heads']:
586 for item in head:
587 for job in item['jobs']:
588 if job['name'] == 'project-merge':
589 found_job = job
590 break
591
592 self.assertIsNotNone(found_job)
593 if iteration == 1:
594 self.assertIsNotNone(found_job['estimated_time'])
595 self.assertIsNone(found_job['remaining_time'])
596 else:
597 self.assertIsNotNone(found_job['estimated_time'])
598 self.assertTrue(found_job['estimated_time'] >= 2)
599 self.assertIsNotNone(found_job['remaining_time'])
600
James E. Blair08d19992016-08-10 15:25:31 -0700601 self.launch_server.hold_jobs_in_build = False
602 self.launch_server.release()
James E. Blairce8a2132016-05-19 15:21:52 -0700603 self.waitUntilSettled()
604
James E. Blairec056492016-07-22 09:45:56 -0700605 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700606 def test_time_database(self):
607 "Test the time database"
608
609 self._test_time_database(1)
610 self._test_time_database(2)
611
James E. Blairfef71632013-09-23 11:15:47 -0700612 def test_two_failed_changes_at_head(self):
613 "Test that changes are reparented correctly if 2 fail at head"
614
James E. Blair08d19992016-08-10 15:25:31 -0700615 self.launch_server.hold_jobs_in_build = True
James E. Blairfef71632013-09-23 11:15:47 -0700616 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
617 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
618 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700619 A.addApproval('code-review', 2)
620 B.addApproval('code-review', 2)
621 C.addApproval('code-review', 2)
James E. Blairfef71632013-09-23 11:15:47 -0700622
James E. Blair08d19992016-08-10 15:25:31 -0700623 self.launch_server.failJob('project-test1', A)
624 self.launch_server.failJob('project-test1', B)
James E. Blairfef71632013-09-23 11:15:47 -0700625
James E. Blair8b5408c2016-08-08 15:37:46 -0700626 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
627 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
628 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blairfef71632013-09-23 11:15:47 -0700629 self.waitUntilSettled()
630
James E. Blair08d19992016-08-10 15:25:31 -0700631 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700632 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700633 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700634 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700635 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700636 self.waitUntilSettled()
637
638 self.assertEqual(len(self.builds), 6)
639 self.assertEqual(self.builds[0].name, 'project-test1')
640 self.assertEqual(self.builds[1].name, 'project-test2')
641 self.assertEqual(self.builds[2].name, 'project-test1')
642 self.assertEqual(self.builds[3].name, 'project-test2')
643 self.assertEqual(self.builds[4].name, 'project-test1')
644 self.assertEqual(self.builds[5].name, 'project-test2')
645
Paul Belanger71dd2fc2016-11-04 19:05:55 -0400646 self.assertTrue(self.builds[0].hasChanges(A))
647 self.assertTrue(self.builds[2].hasChanges(A))
648 self.assertTrue(self.builds[2].hasChanges(B))
649 self.assertTrue(self.builds[4].hasChanges(A))
650 self.assertTrue(self.builds[4].hasChanges(B))
651 self.assertTrue(self.builds[4].hasChanges(C))
James E. Blairfef71632013-09-23 11:15:47 -0700652
653 # Fail change B first
654 self.release(self.builds[2])
655 self.waitUntilSettled()
656
657 # restart of C after B failure
James E. Blair08d19992016-08-10 15:25:31 -0700658 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700659 self.waitUntilSettled()
660
661 self.assertEqual(len(self.builds), 5)
662 self.assertEqual(self.builds[0].name, 'project-test1')
663 self.assertEqual(self.builds[1].name, 'project-test2')
664 self.assertEqual(self.builds[2].name, 'project-test2')
665 self.assertEqual(self.builds[3].name, 'project-test1')
666 self.assertEqual(self.builds[4].name, 'project-test2')
667
Paul Belanger71dd2fc2016-11-04 19:05:55 -0400668 self.assertTrue(self.builds[1].hasChanges(A))
669 self.assertTrue(self.builds[2].hasChanges(A))
670 self.assertTrue(self.builds[2].hasChanges(B))
671 self.assertTrue(self.builds[4].hasChanges(A))
672 self.assertFalse(self.builds[4].hasChanges(B))
673 self.assertTrue(self.builds[4].hasChanges(C))
James E. Blairfef71632013-09-23 11:15:47 -0700674
675 # Finish running all passing jobs for change A
676 self.release(self.builds[1])
677 self.waitUntilSettled()
678 # Fail and report change A
679 self.release(self.builds[0])
680 self.waitUntilSettled()
681
682 # restart of B,C after A failure
James E. Blair08d19992016-08-10 15:25:31 -0700683 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700684 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700685 self.launch_server.release('.*-merge')
James E. Blairfef71632013-09-23 11:15:47 -0700686 self.waitUntilSettled()
687
688 self.assertEqual(len(self.builds), 4)
689 self.assertEqual(self.builds[0].name, 'project-test1') # B
690 self.assertEqual(self.builds[1].name, 'project-test2') # B
691 self.assertEqual(self.builds[2].name, 'project-test1') # C
692 self.assertEqual(self.builds[3].name, 'project-test2') # C
693
Paul Belanger71dd2fc2016-11-04 19:05:55 -0400694 self.assertFalse(self.builds[1].hasChanges(A))
695 self.assertTrue(self.builds[1].hasChanges(B))
696 self.assertFalse(self.builds[1].hasChanges(C))
James E. Blairfef71632013-09-23 11:15:47 -0700697
Paul Belanger71dd2fc2016-11-04 19:05:55 -0400698 self.assertFalse(self.builds[2].hasChanges(A))
James E. Blairfef71632013-09-23 11:15:47 -0700699 # After A failed and B and C restarted, B should be back in
700 # C's tests because it has not failed yet.
Paul Belanger71dd2fc2016-11-04 19:05:55 -0400701 self.assertTrue(self.builds[2].hasChanges(B))
702 self.assertTrue(self.builds[2].hasChanges(C))
James E. Blairfef71632013-09-23 11:15:47 -0700703
James E. Blair08d19992016-08-10 15:25:31 -0700704 self.launch_server.hold_jobs_in_build = False
705 self.launch_server.release()
James E. Blairfef71632013-09-23 11:15:47 -0700706 self.waitUntilSettled()
707
708 self.assertEqual(len(self.builds), 0)
709 self.assertEqual(len(self.history), 21)
710 self.assertEqual(A.data['status'], 'NEW')
711 self.assertEqual(B.data['status'], 'NEW')
712 self.assertEqual(C.data['status'], 'MERGED')
713 self.assertEqual(A.reported, 2)
714 self.assertEqual(B.reported, 2)
715 self.assertEqual(C.reported, 2)
716
James E. Blair8c803f82012-07-31 16:25:42 -0700717 def test_patch_order(self):
718 "Test that dependent patches are tested in the right order"
719 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
720 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
721 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700722 A.addApproval('code-review', 2)
723 B.addApproval('code-review', 2)
724 C.addApproval('code-review', 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700725
726 M2 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M2')
727 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
728 M2.setMerged()
729 M1.setMerged()
730
731 # C -> B -> A -> M1 -> M2
732 # M2 is here to make sure it is never queried. If it is, it
733 # means zuul is walking down the entire history of merged
734 # changes.
735
736 C.setDependsOn(B, 1)
737 B.setDependsOn(A, 1)
738 A.setDependsOn(M1, 1)
739 M1.setDependsOn(M2, 1)
740
James E. Blair8b5408c2016-08-08 15:37:46 -0700741 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair8c803f82012-07-31 16:25:42 -0700742
743 self.waitUntilSettled()
744
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400745 self.assertEqual(A.data['status'], 'NEW')
746 self.assertEqual(B.data['status'], 'NEW')
747 self.assertEqual(C.data['status'], 'NEW')
James E. Blair8c803f82012-07-31 16:25:42 -0700748
James E. Blair8b5408c2016-08-08 15:37:46 -0700749 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
750 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair8c803f82012-07-31 16:25:42 -0700751
752 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400753 self.assertEqual(M2.queried, 0)
754 self.assertEqual(A.data['status'], 'MERGED')
755 self.assertEqual(B.data['status'], 'MERGED')
756 self.assertEqual(C.data['status'], 'MERGED')
757 self.assertEqual(A.reported, 2)
758 self.assertEqual(B.reported, 2)
759 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700760
James E. Blair063672f2015-01-29 13:09:12 -0800761 def test_needed_changes_enqueue(self):
762 "Test that a needed change is enqueued ahead"
763 # A Given a git tree like this, if we enqueue
764 # / \ change C, we should walk up and down the tree
765 # B G and enqueue changes in the order ABCDEFG.
766 # /|\ This is also the order that you would get if
767 # *C E F you enqueued changes in the order ABCDEFG, so
768 # / the ordering is stable across re-enqueue events.
769 # D
770
771 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
772 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
773 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
774 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
775 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
776 F = self.fake_gerrit.addFakeChange('org/project', 'master', 'F')
777 G = self.fake_gerrit.addFakeChange('org/project', 'master', 'G')
778 B.setDependsOn(A, 1)
779 C.setDependsOn(B, 1)
780 D.setDependsOn(C, 1)
781 E.setDependsOn(B, 1)
782 F.setDependsOn(B, 1)
783 G.setDependsOn(A, 1)
784
James E. Blair8b5408c2016-08-08 15:37:46 -0700785 A.addApproval('code-review', 2)
786 B.addApproval('code-review', 2)
787 C.addApproval('code-review', 2)
788 D.addApproval('code-review', 2)
789 E.addApproval('code-review', 2)
790 F.addApproval('code-review', 2)
791 G.addApproval('code-review', 2)
792 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair063672f2015-01-29 13:09:12 -0800793
794 self.waitUntilSettled()
795
796 self.assertEqual(A.data['status'], 'NEW')
797 self.assertEqual(B.data['status'], 'NEW')
798 self.assertEqual(C.data['status'], 'NEW')
799 self.assertEqual(D.data['status'], 'NEW')
800 self.assertEqual(E.data['status'], 'NEW')
801 self.assertEqual(F.data['status'], 'NEW')
802 self.assertEqual(G.data['status'], 'NEW')
803
804 # We're about to add approvals to changes without adding the
805 # triggering events to Zuul, so that we can be sure that it is
806 # enqueing the changes based on dependencies, not because of
807 # triggering events. Since it will have the changes cached
808 # already (without approvals), we need to clear the cache
809 # first.
Paul Belanger593480a2016-11-02 19:06:28 -0400810 for connection in self.connections.connections.values():
Joshua Hesketh4bd7da32016-02-17 20:58:47 +1100811 connection.maintainCache([])
James E. Blair063672f2015-01-29 13:09:12 -0800812
James E. Blair08d19992016-08-10 15:25:31 -0700813 self.launch_server.hold_jobs_in_build = True
James E. Blair8b5408c2016-08-08 15:37:46 -0700814 A.addApproval('approved', 1)
815 B.addApproval('approved', 1)
816 D.addApproval('approved', 1)
817 E.addApproval('approved', 1)
818 F.addApproval('approved', 1)
819 G.addApproval('approved', 1)
820 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair063672f2015-01-29 13:09:12 -0800821
822 for x in range(8):
James E. Blair08d19992016-08-10 15:25:31 -0700823 self.launch_server.release('.*-merge')
James E. Blair063672f2015-01-29 13:09:12 -0800824 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -0700825 self.launch_server.hold_jobs_in_build = False
826 self.launch_server.release()
James E. Blair063672f2015-01-29 13:09:12 -0800827 self.waitUntilSettled()
828
829 self.assertEqual(A.data['status'], 'MERGED')
830 self.assertEqual(B.data['status'], 'MERGED')
831 self.assertEqual(C.data['status'], 'MERGED')
832 self.assertEqual(D.data['status'], 'MERGED')
833 self.assertEqual(E.data['status'], 'MERGED')
834 self.assertEqual(F.data['status'], 'MERGED')
835 self.assertEqual(G.data['status'], 'MERGED')
836 self.assertEqual(A.reported, 2)
837 self.assertEqual(B.reported, 2)
838 self.assertEqual(C.reported, 2)
839 self.assertEqual(D.reported, 2)
840 self.assertEqual(E.reported, 2)
841 self.assertEqual(F.reported, 2)
842 self.assertEqual(G.reported, 2)
843 self.assertEqual(self.history[6].changes,
844 '1,1 2,1 3,1 4,1 5,1 6,1 7,1')
845
Joshua Hesketh850ccb62014-11-27 11:31:02 +1100846 def test_source_cache(self):
847 "Test that the source cache operates correctly"
James E. Blair08d19992016-08-10 15:25:31 -0700848 self.launch_server.hold_jobs_in_build = True
James E. Blair0e933c52013-07-11 10:18:52 -0700849
850 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
851 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
852 X = self.fake_gerrit.addFakeChange('org/project', 'master', 'X')
James E. Blair8b5408c2016-08-08 15:37:46 -0700853 A.addApproval('code-review', 2)
854 B.addApproval('code-review', 2)
James E. Blair0e933c52013-07-11 10:18:52 -0700855
856 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
857 M1.setMerged()
858
859 B.setDependsOn(A, 1)
860 A.setDependsOn(M1, 1)
861
James E. Blair8b5408c2016-08-08 15:37:46 -0700862 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair0e933c52013-07-11 10:18:52 -0700863 self.fake_gerrit.addEvent(X.getPatchsetCreatedEvent(1))
864
865 self.waitUntilSettled()
866
867 for build in self.builds:
868 if build.parameters['ZUUL_PIPELINE'] == 'check':
869 build.release()
870 self.waitUntilSettled()
871 for build in self.builds:
872 if build.parameters['ZUUL_PIPELINE'] == 'check':
873 build.release()
874 self.waitUntilSettled()
875
James E. Blair8b5408c2016-08-08 15:37:46 -0700876 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair0e933c52013-07-11 10:18:52 -0700877 self.waitUntilSettled()
878
Joshua Hesketh352264b2015-08-11 23:42:08 +1000879 self.log.debug("len %s" % self.fake_gerrit._change_cache.keys())
James E. Blair0e933c52013-07-11 10:18:52 -0700880 # there should still be changes in the cache
Joshua Hesketh352264b2015-08-11 23:42:08 +1000881 self.assertNotEqual(len(self.fake_gerrit._change_cache.keys()), 0)
James E. Blair0e933c52013-07-11 10:18:52 -0700882
James E. Blair08d19992016-08-10 15:25:31 -0700883 self.launch_server.hold_jobs_in_build = False
884 self.launch_server.release()
James E. Blair0e933c52013-07-11 10:18:52 -0700885 self.waitUntilSettled()
886
887 self.assertEqual(A.data['status'], 'MERGED')
888 self.assertEqual(B.data['status'], 'MERGED')
889 self.assertEqual(A.queried, 2) # Initial and isMerged
890 self.assertEqual(B.queried, 3) # Initial A, refresh from B, isMerged
891
James E. Blair8c803f82012-07-31 16:25:42 -0700892 def test_can_merge(self):
James E. Blair4886cc12012-07-18 15:39:41 -0700893 "Test whether a change is ready to merge"
James E. Blair8c803f82012-07-31 16:25:42 -0700894 # TODO: move to test_gerrit (this is a unit test!)
895 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
Paul Belanger9bba4902016-11-02 16:07:33 -0400896 tenant = self.sched.abide.tenants.get('tenant-one')
897 source = tenant.layout.pipelines['gate'].source
898
899 # TODO(pabelanger): As we add more source / trigger APIs we should make
900 # it easier for users to create events for testing.
901 event = zuul.model.TriggerEvent()
902 event.trigger_name = 'gerrit'
903 event.change_number = '1'
904 event.patch_number = '2'
905
906 a = source.getChange(event)
907 mgr = tenant.layout.pipelines['gate'].manager
James E. Blairc0dedf82014-08-06 09:37:52 -0700908 self.assertFalse(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700909
James E. Blair8b5408c2016-08-08 15:37:46 -0700910 A.addApproval('code-review', 2)
Paul Belanger9bba4902016-11-02 16:07:33 -0400911 a = source.getChange(event, refresh=True)
James E. Blairc0dedf82014-08-06 09:37:52 -0700912 self.assertFalse(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700913
James E. Blair8b5408c2016-08-08 15:37:46 -0700914 A.addApproval('approved', 1)
Paul Belanger9bba4902016-11-02 16:07:33 -0400915 a = source.getChange(event, refresh=True)
James E. Blairc0dedf82014-08-06 09:37:52 -0700916 self.assertTrue(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair4886cc12012-07-18 15:39:41 -0700917
James E. Blairec056492016-07-22 09:45:56 -0700918 @skip("Disabled for early v3 development")
James E. Blair4886cc12012-07-18 15:39:41 -0700919 def test_build_configuration(self):
920 "Test that zuul merges the right commits for testing"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700921
922 self.gearman_server.hold_jobs_in_queue = True
James E. Blair4886cc12012-07-18 15:39:41 -0700923 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
924 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
925 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700926 A.addApproval('code-review', 2)
927 B.addApproval('code-review', 2)
928 C.addApproval('code-review', 2)
929 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
930 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
931 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair4886cc12012-07-18 15:39:41 -0700932 self.waitUntilSettled()
933
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700934 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700935 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700936 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700937 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700938 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700939 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700940 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700941 ref = self.getParameter(queue[-1], 'ZUUL_REF')
942 self.gearman_server.hold_jobs_in_queue = False
943 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700944 self.waitUntilSettled()
James E. Blair4886cc12012-07-18 15:39:41 -0700945
Monty Taylorbc758832013-06-17 17:22:42 -0400946 path = os.path.join(self.git_root, "org/project")
James E. Blair4886cc12012-07-18 15:39:41 -0700947 repo = git.Repo(path)
948 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
949 repo_messages.reverse()
James E. Blair4886cc12012-07-18 15:39:41 -0700950 correct_messages = ['initial commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400951 self.assertEqual(repo_messages, correct_messages)
James E. Blair973721f2012-08-15 10:19:43 -0700952
James E. Blairec056492016-07-22 09:45:56 -0700953 @skip("Disabled for early v3 development")
James E. Blair973721f2012-08-15 10:19:43 -0700954 def test_build_configuration_conflict(self):
955 "Test that merge conflicts are handled"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700956
957 self.gearman_server.hold_jobs_in_queue = True
James E. Blair6736beb2013-07-11 15:18:15 -0700958 A = self.fake_gerrit.addFakeChange('org/conflict-project',
959 'master', 'A')
James E. Blair973721f2012-08-15 10:19:43 -0700960 A.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700961 B = self.fake_gerrit.addFakeChange('org/conflict-project',
962 'master', 'B')
James E. Blair973721f2012-08-15 10:19:43 -0700963 B.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700964 C = self.fake_gerrit.addFakeChange('org/conflict-project',
965 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -0700966 A.addApproval('code-review', 2)
967 B.addApproval('code-review', 2)
968 C.addApproval('code-review', 2)
969 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
970 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
971 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair973721f2012-08-15 10:19:43 -0700972 self.waitUntilSettled()
973
James E. Blair6736beb2013-07-11 15:18:15 -0700974 self.assertEqual(A.reported, 1)
975 self.assertEqual(B.reported, 1)
976 self.assertEqual(C.reported, 1)
977
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700978 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700979 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700980 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700981 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700982 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700983 self.waitUntilSettled()
James E. Blair972e3c72013-08-29 12:04:55 -0700984
985 self.assertEqual(len(self.history), 2) # A and C merge jobs
986
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700987 self.gearman_server.hold_jobs_in_queue = False
988 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700989 self.waitUntilSettled()
990
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400991 self.assertEqual(A.data['status'], 'MERGED')
992 self.assertEqual(B.data['status'], 'NEW')
993 self.assertEqual(C.data['status'], 'MERGED')
994 self.assertEqual(A.reported, 2)
995 self.assertEqual(B.reported, 2)
996 self.assertEqual(C.reported, 2)
James E. Blair972e3c72013-08-29 12:04:55 -0700997 self.assertEqual(len(self.history), 6)
James E. Blair6736beb2013-07-11 15:18:15 -0700998
James E. Blairec056492016-07-22 09:45:56 -0700999 @skip("Disabled for early v3 development")
James E. Blairdaabed22012-08-15 15:38:57 -07001000 def test_post(self):
1001 "Test that post jobs run"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001002
Zhongyue Luo5d556072012-09-21 02:00:47 +09001003 e = {
1004 "type": "ref-updated",
1005 "submitter": {
1006 "name": "User Name",
1007 },
1008 "refUpdate": {
1009 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
1010 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
1011 "refName": "master",
1012 "project": "org/project",
1013 }
1014 }
James E. Blairdaabed22012-08-15 15:38:57 -07001015 self.fake_gerrit.addEvent(e)
1016 self.waitUntilSettled()
1017
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001018 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001019 self.assertEqual(len(self.history), 1)
1020 self.assertIn('project-post', job_names)
James E. Blairc6294a52012-08-17 10:19:48 -07001021
James E. Blairec056492016-07-22 09:45:56 -07001022 @skip("Disabled for early v3 development")
K Jonathan Harkerf95e7232015-04-29 13:33:16 -07001023 def test_post_ignore_deletes(self):
1024 "Test that deleting refs does not trigger post jobs"
1025
1026 e = {
1027 "type": "ref-updated",
1028 "submitter": {
1029 "name": "User Name",
1030 },
1031 "refUpdate": {
1032 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
1033 "newRev": "0000000000000000000000000000000000000000",
1034 "refName": "master",
1035 "project": "org/project",
1036 }
1037 }
1038 self.fake_gerrit.addEvent(e)
1039 self.waitUntilSettled()
1040
1041 job_names = [x.name for x in self.history]
1042 self.assertEqual(len(self.history), 0)
1043 self.assertNotIn('project-post', job_names)
1044
James E. Blairec056492016-07-22 09:45:56 -07001045 @skip("Disabled for early v3 development")
K Jonathan Harkerf95e7232015-04-29 13:33:16 -07001046 def test_post_ignore_deletes_negative(self):
1047 "Test that deleting refs does trigger post jobs"
1048
James E. Blairf84026c2015-12-08 16:11:46 -08001049 self.updateConfigLayout(
1050 'tests/fixtures/layout-dont-ignore-deletes.yaml')
K Jonathan Harkerf95e7232015-04-29 13:33:16 -07001051 self.sched.reconfigure(self.config)
1052
1053 e = {
1054 "type": "ref-updated",
1055 "submitter": {
1056 "name": "User Name",
1057 },
1058 "refUpdate": {
1059 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
1060 "newRev": "0000000000000000000000000000000000000000",
1061 "refName": "master",
1062 "project": "org/project",
1063 }
1064 }
1065 self.fake_gerrit.addEvent(e)
1066 self.waitUntilSettled()
1067
1068 job_names = [x.name for x in self.history]
1069 self.assertEqual(len(self.history), 1)
1070 self.assertIn('project-post', job_names)
1071
James E. Blairec056492016-07-22 09:45:56 -07001072 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001073 def test_build_configuration_branch(self):
1074 "Test that the right commits are on alternate branches"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001075
1076 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -07001077 A = self.fake_gerrit.addFakeChange('org/project', 'mp', 'A')
1078 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
1079 C = self.fake_gerrit.addFakeChange('org/project', 'mp', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07001080 A.addApproval('code-review', 2)
1081 B.addApproval('code-review', 2)
1082 C.addApproval('code-review', 2)
1083 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1084 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1085 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blairc6294a52012-08-17 10:19:48 -07001086 self.waitUntilSettled()
1087
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001088 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001089 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001090 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001091 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001092 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001093 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001094 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001095 ref = self.getParameter(queue[-1], 'ZUUL_REF')
1096 self.gearman_server.hold_jobs_in_queue = False
1097 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -07001098 self.waitUntilSettled()
1099
Monty Taylorbc758832013-06-17 17:22:42 -04001100 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001101 repo = git.Repo(path)
1102 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
1103 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001104 correct_messages = ['initial commit', 'mp commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001105 self.assertEqual(repo_messages, correct_messages)
James E. Blairc6294a52012-08-17 10:19:48 -07001106
James E. Blairec056492016-07-22 09:45:56 -07001107 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001108 def test_build_configuration_branch_interaction(self):
1109 "Test that switching between branches works"
1110 self.test_build_configuration()
1111 self.test_build_configuration_branch()
1112 # C has been merged, undo that
Monty Taylorbc758832013-06-17 17:22:42 -04001113 path = os.path.join(self.upstream_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001114 repo = git.Repo(path)
1115 repo.heads.master.commit = repo.commit('init')
1116 self.test_build_configuration()
1117
James E. Blairec056492016-07-22 09:45:56 -07001118 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001119 def test_build_configuration_multi_branch(self):
1120 "Test that dependent changes on multiple branches are merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001121
1122 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -07001123 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1124 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
1125 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07001126 A.addApproval('code-review', 2)
1127 B.addApproval('code-review', 2)
1128 C.addApproval('code-review', 2)
1129 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1130 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1131 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blairc6294a52012-08-17 10:19:48 -07001132 self.waitUntilSettled()
James E. Blairbb1fe502014-03-04 10:15:06 -08001133 queue = self.gearman_server.getQueue()
1134 job_A = None
1135 for job in queue:
1136 if 'project-merge' in job.name:
1137 job_A = job
1138 ref_A = self.getParameter(job_A, 'ZUUL_REF')
1139 commit_A = self.getParameter(job_A, 'ZUUL_COMMIT')
1140 self.log.debug("Got Zuul ref for change A: %s" % ref_A)
1141 self.log.debug("Got Zuul commit for change A: %s" % commit_A)
James E. Blairc6294a52012-08-17 10:19:48 -07001142
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001143 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001144 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001145 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -07001146 job_B = None
1147 for job in queue:
1148 if 'project-merge' in job.name:
1149 job_B = job
1150 ref_B = self.getParameter(job_B, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -08001151 commit_B = self.getParameter(job_B, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -07001152 self.log.debug("Got Zuul ref for change B: %s" % ref_B)
James E. Blairbb1fe502014-03-04 10:15:06 -08001153 self.log.debug("Got Zuul commit for change B: %s" % commit_B)
1154
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001155 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001156 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001157 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -07001158 for job in queue:
1159 if 'project-merge' in job.name:
1160 job_C = job
1161 ref_C = self.getParameter(job_C, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -08001162 commit_C = self.getParameter(job_C, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -07001163 self.log.debug("Got Zuul ref for change C: %s" % ref_C)
James E. Blairbb1fe502014-03-04 10:15:06 -08001164 self.log.debug("Got Zuul commit for change C: %s" % commit_C)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001165 self.gearman_server.hold_jobs_in_queue = False
1166 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -07001167 self.waitUntilSettled()
1168
Monty Taylorbc758832013-06-17 17:22:42 -04001169 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001170 repo = git.Repo(path)
1171
1172 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -07001173 for c in repo.iter_commits(ref_C)]
James E. Blairbb1fe502014-03-04 10:15:06 -08001174 repo_shas = [c.hexsha for c in repo.iter_commits(ref_C)]
James E. Blairc6294a52012-08-17 10:19:48 -07001175 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001176 correct_messages = ['initial commit', 'A-1', 'C-1']
James E. Blairbb1fe502014-03-04 10:15:06 -08001177 # Ensure the right commits are in the history for this ref
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001178 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -08001179 # Ensure ZUUL_REF -> ZUUL_COMMIT
1180 self.assertEqual(repo_shas[0], commit_C)
James E. Blairc6294a52012-08-17 10:19:48 -07001181
1182 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -07001183 for c in repo.iter_commits(ref_B)]
James E. Blairbb1fe502014-03-04 10:15:06 -08001184 repo_shas = [c.hexsha for c in repo.iter_commits(ref_B)]
James E. Blairc6294a52012-08-17 10:19:48 -07001185 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001186 correct_messages = ['initial commit', 'mp commit', 'B-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001187 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -08001188 self.assertEqual(repo_shas[0], commit_B)
1189
1190 repo_messages = [c.message.strip()
1191 for c in repo.iter_commits(ref_A)]
1192 repo_shas = [c.hexsha for c in repo.iter_commits(ref_A)]
1193 repo_messages.reverse()
1194 correct_messages = ['initial commit', 'A-1']
1195 self.assertEqual(repo_messages, correct_messages)
1196 self.assertEqual(repo_shas[0], commit_A)
1197
1198 self.assertNotEqual(ref_A, ref_B, ref_C)
1199 self.assertNotEqual(commit_A, commit_B, commit_C)
James E. Blair7f71c802012-08-22 13:04:32 -07001200
James E. Blaircaec0c52012-08-22 14:52:22 -07001201 def test_dependent_changes_dequeue(self):
1202 "Test that dependent patches are not needlessly tested"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001203
James E. Blaircaec0c52012-08-22 14:52:22 -07001204 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1205 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1206 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07001207 A.addApproval('code-review', 2)
1208 B.addApproval('code-review', 2)
1209 C.addApproval('code-review', 2)
James E. Blaircaec0c52012-08-22 14:52:22 -07001210
1211 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
1212 M1.setMerged()
1213
1214 # C -> B -> A -> M1
1215
1216 C.setDependsOn(B, 1)
1217 B.setDependsOn(A, 1)
1218 A.setDependsOn(M1, 1)
1219
James E. Blair08d19992016-08-10 15:25:31 -07001220 self.launch_server.failJob('project-merge', A)
James E. Blaircaec0c52012-08-22 14:52:22 -07001221
James E. Blair8b5408c2016-08-08 15:37:46 -07001222 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
1223 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1224 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blaircaec0c52012-08-22 14:52:22 -07001225
1226 self.waitUntilSettled()
1227
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001228 self.assertEqual(A.data['status'], 'NEW')
1229 self.assertEqual(A.reported, 2)
1230 self.assertEqual(B.data['status'], 'NEW')
1231 self.assertEqual(B.reported, 2)
1232 self.assertEqual(C.data['status'], 'NEW')
1233 self.assertEqual(C.reported, 2)
1234 self.assertEqual(len(self.history), 1)
James E. Blairec590122012-08-22 15:19:31 -07001235
James E. Blair972e3c72013-08-29 12:04:55 -07001236 def test_failing_dependent_changes(self):
1237 "Test that failing dependent patches are taken out of stream"
James E. Blair08d19992016-08-10 15:25:31 -07001238 self.launch_server.hold_jobs_in_build = True
James E. Blair972e3c72013-08-29 12:04:55 -07001239 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1240 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1241 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1242 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1243 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
James E. Blair8b5408c2016-08-08 15:37:46 -07001244 A.addApproval('code-review', 2)
1245 B.addApproval('code-review', 2)
1246 C.addApproval('code-review', 2)
1247 D.addApproval('code-review', 2)
1248 E.addApproval('code-review', 2)
James E. Blair972e3c72013-08-29 12:04:55 -07001249
1250 # E, D -> C -> B, A
1251
1252 D.setDependsOn(C, 1)
1253 C.setDependsOn(B, 1)
1254
James E. Blair08d19992016-08-10 15:25:31 -07001255 self.launch_server.failJob('project-test1', B)
James E. Blair972e3c72013-08-29 12:04:55 -07001256
James E. Blair8b5408c2016-08-08 15:37:46 -07001257 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1258 self.fake_gerrit.addEvent(D.addApproval('approved', 1))
1259 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
1260 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1261 self.fake_gerrit.addEvent(E.addApproval('approved', 1))
James E. Blair972e3c72013-08-29 12:04:55 -07001262
1263 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001264 self.launch_server.release('.*-merge')
James E. Blair972e3c72013-08-29 12:04:55 -07001265 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001266 self.launch_server.release('.*-merge')
James E. Blair972e3c72013-08-29 12:04:55 -07001267 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001268 self.launch_server.release('.*-merge')
James E. Blair972e3c72013-08-29 12:04:55 -07001269 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001270 self.launch_server.release('.*-merge')
James E. Blair972e3c72013-08-29 12:04:55 -07001271 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001272 self.launch_server.release('.*-merge')
James E. Blair972e3c72013-08-29 12:04:55 -07001273 self.waitUntilSettled()
1274
James E. Blair08d19992016-08-10 15:25:31 -07001275 self.launch_server.hold_jobs_in_build = False
James E. Blair972e3c72013-08-29 12:04:55 -07001276 for build in self.builds:
1277 if build.parameters['ZUUL_CHANGE'] != '1':
1278 build.release()
1279 self.waitUntilSettled()
1280
James E. Blair08d19992016-08-10 15:25:31 -07001281 self.launch_server.release()
James E. Blair972e3c72013-08-29 12:04:55 -07001282 self.waitUntilSettled()
1283
1284 self.assertEqual(A.data['status'], 'MERGED')
1285 self.assertEqual(A.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001286 self.assertIn('Build succeeded', A.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001287 self.assertEqual(B.data['status'], 'NEW')
1288 self.assertEqual(B.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001289 self.assertIn('Build failed', B.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001290 self.assertEqual(C.data['status'], 'NEW')
1291 self.assertEqual(C.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001292 self.assertIn('depends on a change', C.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001293 self.assertEqual(D.data['status'], 'NEW')
1294 self.assertEqual(D.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001295 self.assertIn('depends on a change', D.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001296 self.assertEqual(E.data['status'], 'MERGED')
1297 self.assertEqual(E.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001298 self.assertIn('Build succeeded', E.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001299 self.assertEqual(len(self.history), 18)
1300
James E. Blairec590122012-08-22 15:19:31 -07001301 def test_head_is_dequeued_once(self):
James E. Blair2fa50962013-01-30 21:50:41 -08001302 "Test that if a change at the head fails it is dequeued only once"
James E. Blairec590122012-08-22 15:19:31 -07001303 # If it's dequeued more than once, we should see extra
1304 # aborted jobs.
James E. Blairec590122012-08-22 15:19:31 -07001305
James E. Blair08d19992016-08-10 15:25:31 -07001306 self.launch_server.hold_jobs_in_build = True
James E. Blairec590122012-08-22 15:19:31 -07001307 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1308 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1309 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07001310 A.addApproval('code-review', 2)
1311 B.addApproval('code-review', 2)
1312 C.addApproval('code-review', 2)
James E. Blairec590122012-08-22 15:19:31 -07001313
Paul Belanger58bf6912016-11-11 19:36:01 -05001314 self.launch_server.failJob('project-test1', A)
1315 self.launch_server.failJob('project-test2', A)
James E. Blair08d19992016-08-10 15:25:31 -07001316 self.launch_server.failJob('project1-project2-integration', A)
James E. Blairec590122012-08-22 15:19:31 -07001317
James E. Blair8b5408c2016-08-08 15:37:46 -07001318 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1319 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1320 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blairec590122012-08-22 15:19:31 -07001321
1322 self.waitUntilSettled()
James E. Blairec590122012-08-22 15:19:31 -07001323
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001324 self.assertEqual(len(self.builds), 1)
Paul Belanger58bf6912016-11-11 19:36:01 -05001325 self.assertEqual(self.builds[0].name, 'project-merge')
1326 self.assertTrue(self.builds[0].hasChanges(A))
James E. Blairec590122012-08-22 15:19:31 -07001327
James E. Blair08d19992016-08-10 15:25:31 -07001328 self.launch_server.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001329 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001330 self.launch_server.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001331 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001332 self.launch_server.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001333 self.waitUntilSettled()
1334
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001335 self.assertEqual(len(self.builds), 9)
Paul Belanger58bf6912016-11-11 19:36:01 -05001336 self.assertEqual(self.builds[0].name, 'project-test1')
1337 self.assertEqual(self.builds[1].name, 'project-test2')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001338 self.assertEqual(self.builds[2].name, 'project1-project2-integration')
Paul Belanger58bf6912016-11-11 19:36:01 -05001339 self.assertEqual(self.builds[3].name, 'project-test1')
1340 self.assertEqual(self.builds[4].name, 'project-test2')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001341 self.assertEqual(self.builds[5].name, 'project1-project2-integration')
Paul Belanger58bf6912016-11-11 19:36:01 -05001342 self.assertEqual(self.builds[6].name, 'project-test1')
1343 self.assertEqual(self.builds[7].name, 'project-test2')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001344 self.assertEqual(self.builds[8].name, 'project1-project2-integration')
James E. Blairec590122012-08-22 15:19:31 -07001345
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001346 self.release(self.builds[0])
James E. Blairec590122012-08-22 15:19:31 -07001347 self.waitUntilSettled()
1348
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001349 self.assertEqual(len(self.builds), 3) # test2,integration, merge for B
1350 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 6)
James E. Blairec590122012-08-22 15:19:31 -07001351
James E. Blair08d19992016-08-10 15:25:31 -07001352 self.launch_server.hold_jobs_in_build = False
1353 self.launch_server.release()
James E. Blairec590122012-08-22 15:19:31 -07001354 self.waitUntilSettled()
1355
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001356 self.assertEqual(len(self.builds), 0)
1357 self.assertEqual(len(self.history), 20)
James E. Blaircaec0c52012-08-22 14:52:22 -07001358
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001359 self.assertEqual(A.data['status'], 'NEW')
1360 self.assertEqual(B.data['status'], 'MERGED')
1361 self.assertEqual(C.data['status'], 'MERGED')
1362 self.assertEqual(A.reported, 2)
1363 self.assertEqual(B.reported, 2)
1364 self.assertEqual(C.reported, 2)
James E. Blair4ec821f2012-08-23 15:28:28 -07001365
James E. Blairec056492016-07-22 09:45:56 -07001366 @skip("Disabled for early v3 development")
James E. Blair4ec821f2012-08-23 15:28:28 -07001367 def test_nonvoting_job(self):
1368 "Test that non-voting jobs don't vote."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001369
James E. Blair4ec821f2012-08-23 15:28:28 -07001370 A = self.fake_gerrit.addFakeChange('org/nonvoting-project',
1371 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001372 A.addApproval('code-review', 2)
James E. Blair08d19992016-08-10 15:25:31 -07001373 self.launch_server.failJob('nonvoting-project-test2', A)
James E. Blair8b5408c2016-08-08 15:37:46 -07001374 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair4ec821f2012-08-23 15:28:28 -07001375
1376 self.waitUntilSettled()
James E. Blair4ec821f2012-08-23 15:28:28 -07001377
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001378 self.assertEqual(A.data['status'], 'MERGED')
1379 self.assertEqual(A.reported, 2)
1380 self.assertEqual(
1381 self.getJobFromHistory('nonvoting-project-merge').result,
1382 'SUCCESS')
1383 self.assertEqual(
1384 self.getJobFromHistory('nonvoting-project-test1').result,
1385 'SUCCESS')
1386 self.assertEqual(
1387 self.getJobFromHistory('nonvoting-project-test2').result,
1388 'FAILURE')
James E. Blaire0487072012-08-29 17:38:31 -07001389
James E. Blair5821bd92015-09-16 08:48:15 -07001390 for build in self.builds:
1391 self.assertEqual(build.parameters['ZUUL_VOTING'], '0')
1392
James E. Blaire0487072012-08-29 17:38:31 -07001393 def test_check_queue_success(self):
1394 "Test successful check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001395
James E. Blaire0487072012-08-29 17:38:31 -07001396 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1397 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1398
1399 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001400
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001401 self.assertEqual(A.data['status'], 'NEW')
1402 self.assertEqual(A.reported, 1)
1403 self.assertEqual(self.getJobFromHistory('project-merge').result,
1404 'SUCCESS')
1405 self.assertEqual(self.getJobFromHistory('project-test1').result,
1406 'SUCCESS')
1407 self.assertEqual(self.getJobFromHistory('project-test2').result,
1408 'SUCCESS')
James E. Blaire0487072012-08-29 17:38:31 -07001409
1410 def test_check_queue_failure(self):
1411 "Test failed check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001412
James E. Blaire0487072012-08-29 17:38:31 -07001413 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair08d19992016-08-10 15:25:31 -07001414 self.launch_server.failJob('project-test2', A)
James E. Blaire0487072012-08-29 17:38:31 -07001415 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1416
1417 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001418
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001419 self.assertEqual(A.data['status'], 'NEW')
1420 self.assertEqual(A.reported, 1)
1421 self.assertEqual(self.getJobFromHistory('project-merge').result,
James E. Blair78e31b32013-07-09 09:11:34 -07001422 'SUCCESS')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001423 self.assertEqual(self.getJobFromHistory('project-test1').result,
1424 'SUCCESS')
1425 self.assertEqual(self.getJobFromHistory('project-test2').result,
1426 'FAILURE')
James E. Blair127bc182012-08-28 15:55:15 -07001427
James E. Blairec056492016-07-22 09:45:56 -07001428 @skip("Disabled for early v3 development")
James E. Blair127bc182012-08-28 15:55:15 -07001429 def test_dependent_behind_dequeue(self):
1430 "test that dependent changes behind dequeued changes work"
1431 # This complicated test is a reproduction of a real life bug
1432 self.sched.reconfigure(self.config)
James E. Blair127bc182012-08-28 15:55:15 -07001433
James E. Blair08d19992016-08-10 15:25:31 -07001434 self.launch_server.hold_jobs_in_build = True
James E. Blair127bc182012-08-28 15:55:15 -07001435 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1436 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1437 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
1438 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
1439 E = self.fake_gerrit.addFakeChange('org/project2', 'master', 'E')
1440 F = self.fake_gerrit.addFakeChange('org/project3', 'master', 'F')
1441 D.setDependsOn(C, 1)
1442 E.setDependsOn(D, 1)
James E. Blair8b5408c2016-08-08 15:37:46 -07001443 A.addApproval('code-review', 2)
1444 B.addApproval('code-review', 2)
1445 C.addApproval('code-review', 2)
1446 D.addApproval('code-review', 2)
1447 E.addApproval('code-review', 2)
1448 F.addApproval('code-review', 2)
James E. Blair127bc182012-08-28 15:55:15 -07001449
1450 A.fail_merge = True
James E. Blair127bc182012-08-28 15:55:15 -07001451
1452 # Change object re-use in the gerrit trigger is hidden if
1453 # changes are added in quick succession; waiting makes it more
1454 # like real life.
James E. Blair8b5408c2016-08-08 15:37:46 -07001455 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001456 self.waitUntilSettled()
James E. Blair8b5408c2016-08-08 15:37:46 -07001457 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001458 self.waitUntilSettled()
1459
James E. Blair08d19992016-08-10 15:25:31 -07001460 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001461 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001462 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001463 self.waitUntilSettled()
1464
James E. Blair8b5408c2016-08-08 15:37:46 -07001465 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001466 self.waitUntilSettled()
James E. Blair8b5408c2016-08-08 15:37:46 -07001467 self.fake_gerrit.addEvent(D.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001468 self.waitUntilSettled()
James E. Blair8b5408c2016-08-08 15:37:46 -07001469 self.fake_gerrit.addEvent(E.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001470 self.waitUntilSettled()
James E. Blair8b5408c2016-08-08 15:37:46 -07001471 self.fake_gerrit.addEvent(F.addApproval('approved', 1))
James E. Blair127bc182012-08-28 15:55:15 -07001472 self.waitUntilSettled()
1473
James E. Blair08d19992016-08-10 15:25:31 -07001474 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001475 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001476 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001477 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001478 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001479 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001480 self.launch_server.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001481 self.waitUntilSettled()
1482
1483 # all jobs running
James E. Blaire955e062012-10-08 09:49:03 -07001484
1485 # Grab pointers to the jobs we want to release before
1486 # releasing any, because list indexes may change as
1487 # the jobs complete.
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001488 a, b, c = self.builds[:3]
James E. Blaire955e062012-10-08 09:49:03 -07001489 a.release()
1490 b.release()
1491 c.release()
James E. Blair127bc182012-08-28 15:55:15 -07001492 self.waitUntilSettled()
1493
James E. Blair08d19992016-08-10 15:25:31 -07001494 self.launch_server.hold_jobs_in_build = False
1495 self.launch_server.release()
James E. Blair127bc182012-08-28 15:55:15 -07001496 self.waitUntilSettled()
1497
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001498 self.assertEqual(A.data['status'], 'NEW')
1499 self.assertEqual(B.data['status'], 'MERGED')
1500 self.assertEqual(C.data['status'], 'MERGED')
1501 self.assertEqual(D.data['status'], 'MERGED')
1502 self.assertEqual(E.data['status'], 'MERGED')
1503 self.assertEqual(F.data['status'], 'MERGED')
James E. Blair127bc182012-08-28 15:55:15 -07001504
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001505 self.assertEqual(A.reported, 2)
1506 self.assertEqual(B.reported, 2)
1507 self.assertEqual(C.reported, 2)
1508 self.assertEqual(D.reported, 2)
1509 self.assertEqual(E.reported, 2)
1510 self.assertEqual(F.reported, 2)
James E. Blair127bc182012-08-28 15:55:15 -07001511
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001512 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 15)
1513 self.assertEqual(len(self.history), 44)
James E. Blair05fed602012-09-07 12:45:24 -07001514
1515 def test_merger_repack(self):
1516 "Test that the merger works after a repack"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001517
James E. Blair05fed602012-09-07 12:45:24 -07001518 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001519 A.addApproval('code-review', 2)
1520 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair05fed602012-09-07 12:45:24 -07001521 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001522 self.assertEqual(self.getJobFromHistory('project-merge').result,
1523 'SUCCESS')
1524 self.assertEqual(self.getJobFromHistory('project-test1').result,
1525 'SUCCESS')
1526 self.assertEqual(self.getJobFromHistory('project-test2').result,
1527 'SUCCESS')
1528 self.assertEqual(A.data['status'], 'MERGED')
1529 self.assertEqual(A.reported, 2)
James E. Blair05fed602012-09-07 12:45:24 -07001530 self.assertEmptyQueues()
Paul Belanger5bfe9e72016-11-04 19:20:04 -04001531 self.build_history = []
James E. Blair05fed602012-09-07 12:45:24 -07001532
Monty Taylorbc758832013-06-17 17:22:42 -04001533 path = os.path.join(self.git_root, "org/project")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001534 print(repack_repo(path))
James E. Blair05fed602012-09-07 12:45:24 -07001535
1536 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001537 A.addApproval('code-review', 2)
1538 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair05fed602012-09-07 12:45:24 -07001539 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001540 self.assertEqual(self.getJobFromHistory('project-merge').result,
1541 'SUCCESS')
1542 self.assertEqual(self.getJobFromHistory('project-test1').result,
1543 'SUCCESS')
1544 self.assertEqual(self.getJobFromHistory('project-test2').result,
1545 'SUCCESS')
1546 self.assertEqual(A.data['status'], 'MERGED')
1547 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001548
James E. Blair4886f282012-11-15 09:27:33 -08001549 def test_merger_repack_large_change(self):
1550 "Test that the merger works with large changes after a repack"
1551 # https://bugs.launchpad.net/zuul/+bug/1078946
James E. Blairac2c3242014-01-24 13:38:51 -08001552 # This test assumes the repo is already cloned; make sure it is
Paul Belanger503bded2016-11-11 19:43:38 -05001553 tenant = self.sched.abide.tenants.get('tenant-one')
Joshua Hesketh352264b2015-08-11 23:42:08 +10001554 url = self.fake_gerrit.getGitUrl(
Paul Belanger503bded2016-11-11 19:43:38 -05001555 tenant.layout.project_configs.get('org/project1'))
James E. Blair4076e2b2014-01-28 12:42:20 -08001556 self.merge_server.merger.addProject('org/project1', url)
James E. Blair4886f282012-11-15 09:27:33 -08001557 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1558 A.addPatchset(large=True)
Monty Taylorbc758832013-06-17 17:22:42 -04001559 path = os.path.join(self.upstream_root, "org/project1")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001560 print(repack_repo(path))
Monty Taylorbc758832013-06-17 17:22:42 -04001561 path = os.path.join(self.git_root, "org/project1")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001562 print(repack_repo(path))
James E. Blair4886f282012-11-15 09:27:33 -08001563
James E. Blair8b5408c2016-08-08 15:37:46 -07001564 A.addApproval('code-review', 2)
1565 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair4886f282012-11-15 09:27:33 -08001566 self.waitUntilSettled()
Paul Belanger503bded2016-11-11 19:43:38 -05001567 self.assertEqual(self.getJobFromHistory('project-merge').result,
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001568 'SUCCESS')
Paul Belanger503bded2016-11-11 19:43:38 -05001569 self.assertEqual(self.getJobFromHistory('project-test1').result,
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001570 'SUCCESS')
Paul Belanger503bded2016-11-11 19:43:38 -05001571 self.assertEqual(self.getJobFromHistory('project-test2').result,
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001572 'SUCCESS')
1573 self.assertEqual(A.data['status'], 'MERGED')
1574 self.assertEqual(A.reported, 2)
James E. Blair4886f282012-11-15 09:27:33 -08001575
James E. Blairec056492016-07-22 09:45:56 -07001576 @skip("Disabled for early v3 development")
James E. Blair7ee88a22012-09-12 18:59:31 +02001577 def test_nonexistent_job(self):
1578 "Test launching a job that doesn't exist"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001579 # Set to the state immediately after a restart
1580 self.resetGearmanServer()
1581 self.launcher.negative_function_cache_ttl = 0
James E. Blair7ee88a22012-09-12 18:59:31 +02001582
1583 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001584 A.addApproval('code-review', 2)
1585 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair7ee88a22012-09-12 18:59:31 +02001586 # There may be a thread about to report a lost change
1587 while A.reported < 2:
1588 self.waitUntilSettled()
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001589 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001590 self.assertFalse(job_names)
1591 self.assertEqual(A.data['status'], 'NEW')
1592 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001593 self.assertEmptyQueues()
1594
1595 # Make sure things still work:
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001596 self.registerJobs()
James E. Blair7ee88a22012-09-12 18:59:31 +02001597 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001598 A.addApproval('code-review', 2)
1599 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair7ee88a22012-09-12 18:59:31 +02001600 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001601 self.assertEqual(self.getJobFromHistory('project-merge').result,
1602 'SUCCESS')
1603 self.assertEqual(self.getJobFromHistory('project-test1').result,
1604 'SUCCESS')
1605 self.assertEqual(self.getJobFromHistory('project-test2').result,
1606 'SUCCESS')
1607 self.assertEqual(A.data['status'], 'MERGED')
1608 self.assertEqual(A.reported, 2)
James E. Blairf62d4282012-12-31 17:01:50 -08001609
James E. Blair2fa50962013-01-30 21:50:41 -08001610 def test_new_patchset_dequeues_old(self):
1611 "Test that a new patchset causes the old to be dequeued"
1612 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair08d19992016-08-10 15:25:31 -07001613 self.launch_server.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001614 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1615 M.setMerged()
1616
1617 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1618 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1619 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1620 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
James E. Blair8b5408c2016-08-08 15:37:46 -07001621 A.addApproval('code-review', 2)
1622 B.addApproval('code-review', 2)
1623 C.addApproval('code-review', 2)
1624 D.addApproval('code-review', 2)
James E. Blair2fa50962013-01-30 21:50:41 -08001625
1626 C.setDependsOn(B, 1)
1627 B.setDependsOn(A, 1)
1628 A.setDependsOn(M, 1)
1629
James E. Blair8b5408c2016-08-08 15:37:46 -07001630 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1631 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1632 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
1633 self.fake_gerrit.addEvent(D.addApproval('approved', 1))
James E. Blair2fa50962013-01-30 21:50:41 -08001634 self.waitUntilSettled()
1635
1636 B.addPatchset()
1637 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1638 self.waitUntilSettled()
1639
James E. Blair08d19992016-08-10 15:25:31 -07001640 self.launch_server.hold_jobs_in_build = False
1641 self.launch_server.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001642 self.waitUntilSettled()
1643
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001644 self.assertEqual(A.data['status'], 'MERGED')
1645 self.assertEqual(A.reported, 2)
1646 self.assertEqual(B.data['status'], 'NEW')
1647 self.assertEqual(B.reported, 2)
1648 self.assertEqual(C.data['status'], 'NEW')
1649 self.assertEqual(C.reported, 2)
1650 self.assertEqual(D.data['status'], 'MERGED')
1651 self.assertEqual(D.reported, 2)
1652 self.assertEqual(len(self.history), 9) # 3 each for A, B, D.
James E. Blair2fa50962013-01-30 21:50:41 -08001653
James E. Blairba437362015-02-07 11:41:52 -08001654 def test_new_patchset_check(self):
1655 "Test a new patchset in check"
Antoine Mussobd86a312014-01-08 14:51:33 +01001656
James E. Blair08d19992016-08-10 15:25:31 -07001657 self.launch_server.hold_jobs_in_build = True
Antoine Mussobd86a312014-01-08 14:51:33 +01001658
1659 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairba437362015-02-07 11:41:52 -08001660 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
Paul Belanger18e5f632016-11-03 15:24:16 -04001661 tenant = self.sched.abide.tenants.get('tenant-one')
1662 check_pipeline = tenant.layout.pipelines['check']
James E. Blairba437362015-02-07 11:41:52 -08001663
1664 # Add two git-dependent changes
1665 B.setDependsOn(A, 1)
1666 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1667 self.waitUntilSettled()
Antoine Mussobd86a312014-01-08 14:51:33 +01001668 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1669 self.waitUntilSettled()
James E. Blairba437362015-02-07 11:41:52 -08001670
1671 # A live item, and a non-live/live pair
1672 items = check_pipeline.getAllItems()
1673 self.assertEqual(len(items), 3)
1674
1675 self.assertEqual(items[0].change.number, '1')
1676 self.assertEqual(items[0].change.patchset, '1')
1677 self.assertFalse(items[0].live)
1678
1679 self.assertEqual(items[1].change.number, '2')
1680 self.assertEqual(items[1].change.patchset, '1')
1681 self.assertTrue(items[1].live)
1682
1683 self.assertEqual(items[2].change.number, '1')
1684 self.assertEqual(items[2].change.patchset, '1')
1685 self.assertTrue(items[2].live)
1686
1687 # Add a new patchset to A
1688 A.addPatchset()
1689 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1690 self.waitUntilSettled()
1691
1692 # The live copy of A,1 should be gone, but the non-live and B
1693 # should continue, and we should have a new A,2
1694 items = check_pipeline.getAllItems()
1695 self.assertEqual(len(items), 3)
1696
1697 self.assertEqual(items[0].change.number, '1')
1698 self.assertEqual(items[0].change.patchset, '1')
1699 self.assertFalse(items[0].live)
1700
1701 self.assertEqual(items[1].change.number, '2')
1702 self.assertEqual(items[1].change.patchset, '1')
1703 self.assertTrue(items[1].live)
1704
1705 self.assertEqual(items[2].change.number, '1')
1706 self.assertEqual(items[2].change.patchset, '2')
1707 self.assertTrue(items[2].live)
1708
1709 # Add a new patchset to B
1710 B.addPatchset()
1711 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1712 self.waitUntilSettled()
1713
1714 # The live copy of B,1 should be gone, and it's non-live copy of A,1
1715 # but we should have a new B,2 (still based on A,1)
1716 items = check_pipeline.getAllItems()
1717 self.assertEqual(len(items), 3)
1718
1719 self.assertEqual(items[0].change.number, '1')
1720 self.assertEqual(items[0].change.patchset, '2')
1721 self.assertTrue(items[0].live)
1722
1723 self.assertEqual(items[1].change.number, '1')
1724 self.assertEqual(items[1].change.patchset, '1')
1725 self.assertFalse(items[1].live)
1726
1727 self.assertEqual(items[2].change.number, '2')
1728 self.assertEqual(items[2].change.patchset, '2')
1729 self.assertTrue(items[2].live)
1730
1731 self.builds[0].release()
1732 self.waitUntilSettled()
1733 self.builds[0].release()
1734 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07001735 self.launch_server.hold_jobs_in_build = False
1736 self.launch_server.release()
James E. Blairba437362015-02-07 11:41:52 -08001737 self.waitUntilSettled()
1738
1739 self.assertEqual(A.reported, 1)
1740 self.assertEqual(B.reported, 1)
1741 self.assertEqual(self.history[0].result, 'ABORTED')
1742 self.assertEqual(self.history[0].changes, '1,1')
1743 self.assertEqual(self.history[1].result, 'ABORTED')
1744 self.assertEqual(self.history[1].changes, '1,1 2,1')
1745 self.assertEqual(self.history[2].result, 'SUCCESS')
1746 self.assertEqual(self.history[2].changes, '1,2')
1747 self.assertEqual(self.history[3].result, 'SUCCESS')
1748 self.assertEqual(self.history[3].changes, '1,1 2,2')
1749
1750 def test_abandoned_gate(self):
1751 "Test that an abandoned change is dequeued from gate"
1752
James E. Blair08d19992016-08-10 15:25:31 -07001753 self.launch_server.hold_jobs_in_build = True
James E. Blairba437362015-02-07 11:41:52 -08001754
1755 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001756 A.addApproval('code-review', 2)
1757 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blairba437362015-02-07 11:41:52 -08001758 self.waitUntilSettled()
Antoine Mussobd86a312014-01-08 14:51:33 +01001759 self.assertEqual(len(self.builds), 1, "One job being built (on hold)")
1760 self.assertEqual(self.builds[0].name, 'project-merge')
1761
1762 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1763 self.waitUntilSettled()
1764
James E. Blair08d19992016-08-10 15:25:31 -07001765 self.launch_server.release('.*-merge')
Antoine Mussobd86a312014-01-08 14:51:33 +01001766 self.waitUntilSettled()
1767
Arie5b4048c2016-10-05 16:12:06 +03001768 self.assertBuilds([])
1769 self.assertHistory([
1770 dict(name='project-merge', result='ABORTED', changes='1,1')],
1771 ordered=False)
James E. Blairba437362015-02-07 11:41:52 -08001772 self.assertEqual(A.reported, 1,
1773 "Abandoned gate change should report only start")
1774
1775 def test_abandoned_check(self):
1776 "Test that an abandoned change is dequeued from check"
1777
James E. Blair08d19992016-08-10 15:25:31 -07001778 self.launch_server.hold_jobs_in_build = True
James E. Blairba437362015-02-07 11:41:52 -08001779
1780 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1781 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
Paul Belanger18e5f632016-11-03 15:24:16 -04001782 tenant = self.sched.abide.tenants.get('tenant-one')
1783 check_pipeline = tenant.layout.pipelines['check']
James E. Blairba437362015-02-07 11:41:52 -08001784
1785 # Add two git-dependent changes
1786 B.setDependsOn(A, 1)
1787 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1788 self.waitUntilSettled()
1789 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1790 self.waitUntilSettled()
1791 # A live item, and a non-live/live pair
1792 items = check_pipeline.getAllItems()
1793 self.assertEqual(len(items), 3)
1794
1795 self.assertEqual(items[0].change.number, '1')
1796 self.assertFalse(items[0].live)
1797
1798 self.assertEqual(items[1].change.number, '2')
1799 self.assertTrue(items[1].live)
1800
1801 self.assertEqual(items[2].change.number, '1')
1802 self.assertTrue(items[2].live)
1803
1804 # Abandon A
1805 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1806 self.waitUntilSettled()
1807
1808 # The live copy of A should be gone, but the non-live and B
1809 # should continue
1810 items = check_pipeline.getAllItems()
1811 self.assertEqual(len(items), 2)
1812
1813 self.assertEqual(items[0].change.number, '1')
1814 self.assertFalse(items[0].live)
1815
1816 self.assertEqual(items[1].change.number, '2')
1817 self.assertTrue(items[1].live)
1818
James E. Blair08d19992016-08-10 15:25:31 -07001819 self.launch_server.hold_jobs_in_build = False
1820 self.launch_server.release()
James E. Blairba437362015-02-07 11:41:52 -08001821 self.waitUntilSettled()
1822
1823 self.assertEqual(len(self.history), 4)
1824 self.assertEqual(self.history[0].result, 'ABORTED',
Antoine Mussobd86a312014-01-08 14:51:33 +01001825 'Build should have been aborted')
1826 self.assertEqual(A.reported, 0, "Abandoned change should not report")
James E. Blairba437362015-02-07 11:41:52 -08001827 self.assertEqual(B.reported, 1, "Change should report")
Antoine Mussobd86a312014-01-08 14:51:33 +01001828
James E. Blairec056492016-07-22 09:45:56 -07001829 @skip("Disabled for early v3 development")
Steve Varnau7b78b312015-04-03 14:49:46 -07001830 def test_abandoned_not_timer(self):
1831 "Test that an abandoned change does not cancel timer jobs"
1832
James E. Blair08d19992016-08-10 15:25:31 -07001833 self.launch_server.hold_jobs_in_build = True
Steve Varnau7b78b312015-04-03 14:49:46 -07001834
1835 # Start timer trigger - also org/project
James E. Blairf84026c2015-12-08 16:11:46 -08001836 self.updateConfigLayout(
1837 'tests/fixtures/layout-idle.yaml')
Steve Varnau7b78b312015-04-03 14:49:46 -07001838 self.sched.reconfigure(self.config)
1839 self.registerJobs()
1840 # The pipeline triggers every second, so we should have seen
1841 # several by now.
1842 time.sleep(5)
1843 self.waitUntilSettled()
1844 # Stop queuing timer triggered jobs so that the assertions
1845 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08001846 self.updateConfigLayout(
1847 'tests/fixtures/layout-no-timer.yaml')
Steve Varnau7b78b312015-04-03 14:49:46 -07001848 self.sched.reconfigure(self.config)
1849 self.registerJobs()
1850 self.assertEqual(len(self.builds), 2, "Two timer jobs")
1851
1852 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1853 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1854 self.waitUntilSettled()
1855 self.assertEqual(len(self.builds), 3, "One change plus two timer jobs")
1856
1857 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1858 self.waitUntilSettled()
1859
1860 self.assertEqual(len(self.builds), 2, "Two timer jobs remain")
1861
James E. Blair08d19992016-08-10 15:25:31 -07001862 self.launch_server.release()
Steve Varnau7b78b312015-04-03 14:49:46 -07001863 self.waitUntilSettled()
1864
Arx Cruzb1b010d2013-10-28 19:49:59 -02001865 def test_zuul_url_return(self):
1866 "Test if ZUUL_URL is returning when zuul_url is set in zuul.conf"
James E. Blair4076e2b2014-01-28 12:42:20 -08001867 self.assertTrue(self.sched.config.has_option('merger', 'zuul_url'))
James E. Blair08d19992016-08-10 15:25:31 -07001868 self.launch_server.hold_jobs_in_build = True
Arx Cruzb1b010d2013-10-28 19:49:59 -02001869
1870 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001871 A.addApproval('code-review', 2)
1872 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Arx Cruzb1b010d2013-10-28 19:49:59 -02001873 self.waitUntilSettled()
1874
1875 self.assertEqual(len(self.builds), 1)
1876 for build in self.builds:
1877 self.assertTrue('ZUUL_URL' in build.parameters)
1878
James E. Blair08d19992016-08-10 15:25:31 -07001879 self.launch_server.hold_jobs_in_build = False
1880 self.launch_server.release()
Arx Cruzb1b010d2013-10-28 19:49:59 -02001881 self.waitUntilSettled()
1882
James E. Blair2fa50962013-01-30 21:50:41 -08001883 def test_new_patchset_dequeues_old_on_head(self):
1884 "Test that a new patchset causes the old to be dequeued (at head)"
1885 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair08d19992016-08-10 15:25:31 -07001886 self.launch_server.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001887 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1888 M.setMerged()
1889 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1890 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1891 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1892 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
James E. Blair8b5408c2016-08-08 15:37:46 -07001893 A.addApproval('code-review', 2)
1894 B.addApproval('code-review', 2)
1895 C.addApproval('code-review', 2)
1896 D.addApproval('code-review', 2)
James E. Blair2fa50962013-01-30 21:50:41 -08001897
1898 C.setDependsOn(B, 1)
1899 B.setDependsOn(A, 1)
1900 A.setDependsOn(M, 1)
1901
James E. Blair8b5408c2016-08-08 15:37:46 -07001902 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
1903 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1904 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
1905 self.fake_gerrit.addEvent(D.addApproval('approved', 1))
James E. Blair2fa50962013-01-30 21:50:41 -08001906 self.waitUntilSettled()
1907
1908 A.addPatchset()
1909 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1910 self.waitUntilSettled()
1911
James E. Blair08d19992016-08-10 15:25:31 -07001912 self.launch_server.hold_jobs_in_build = False
1913 self.launch_server.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001914 self.waitUntilSettled()
1915
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001916 self.assertEqual(A.data['status'], 'NEW')
1917 self.assertEqual(A.reported, 2)
1918 self.assertEqual(B.data['status'], 'NEW')
1919 self.assertEqual(B.reported, 2)
1920 self.assertEqual(C.data['status'], 'NEW')
1921 self.assertEqual(C.reported, 2)
1922 self.assertEqual(D.data['status'], 'MERGED')
1923 self.assertEqual(D.reported, 2)
1924 self.assertEqual(len(self.history), 7)
James E. Blair2fa50962013-01-30 21:50:41 -08001925
1926 def test_new_patchset_dequeues_old_without_dependents(self):
1927 "Test that a new patchset causes only the old to be dequeued"
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')
James E. Blair8b5408c2016-08-08 15:37:46 -07001932 A.addApproval('code-review', 2)
1933 B.addApproval('code-review', 2)
1934 C.addApproval('code-review', 2)
James E. Blair2fa50962013-01-30 21:50:41 -08001935
James E. Blair8b5408c2016-08-08 15:37:46 -07001936 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
1937 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
1938 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair2fa50962013-01-30 21:50:41 -08001939 self.waitUntilSettled()
1940
1941 B.addPatchset()
1942 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1943 self.waitUntilSettled()
1944
James E. Blair08d19992016-08-10 15:25:31 -07001945 self.launch_server.hold_jobs_in_build = False
1946 self.launch_server.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001947 self.waitUntilSettled()
1948
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001949 self.assertEqual(A.data['status'], 'MERGED')
1950 self.assertEqual(A.reported, 2)
1951 self.assertEqual(B.data['status'], 'NEW')
1952 self.assertEqual(B.reported, 2)
1953 self.assertEqual(C.data['status'], 'MERGED')
1954 self.assertEqual(C.reported, 2)
1955 self.assertEqual(len(self.history), 9)
James E. Blair2fa50962013-01-30 21:50:41 -08001956
1957 def test_new_patchset_dequeues_old_independent_queue(self):
1958 "Test that a new patchset causes the old to be dequeued (independent)"
James E. Blair08d19992016-08-10 15:25:31 -07001959 self.launch_server.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001960 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1961 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1962 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1963 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1964 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1965 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
1966 self.waitUntilSettled()
1967
1968 B.addPatchset()
1969 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1970 self.waitUntilSettled()
1971
James E. Blair08d19992016-08-10 15:25:31 -07001972 self.launch_server.hold_jobs_in_build = False
1973 self.launch_server.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001974 self.waitUntilSettled()
1975
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001976 self.assertEqual(A.data['status'], 'NEW')
1977 self.assertEqual(A.reported, 1)
1978 self.assertEqual(B.data['status'], 'NEW')
1979 self.assertEqual(B.reported, 1)
1980 self.assertEqual(C.data['status'], 'NEW')
1981 self.assertEqual(C.reported, 1)
1982 self.assertEqual(len(self.history), 10)
1983 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 1)
James E. Blair7d0dedc2013-02-21 17:26:09 -08001984
James E. Blair18c64442014-03-18 10:14:45 -07001985 def test_noop_job(self):
1986 "Test that the internal noop job works"
1987 A = self.fake_gerrit.addFakeChange('org/noop-project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07001988 A.addApproval('code-review', 2)
1989 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair18c64442014-03-18 10:14:45 -07001990 self.waitUntilSettled()
1991
1992 self.assertEqual(len(self.gearman_server.getQueue()), 0)
1993 self.assertTrue(self.sched._areAllBuildsComplete())
1994 self.assertEqual(len(self.history), 0)
1995 self.assertEqual(A.data['status'], 'MERGED')
1996 self.assertEqual(A.reported, 2)
1997
James E. Blairec056492016-07-22 09:45:56 -07001998 @skip("Disabled for early v3 development")
Evgeny Antyshevd6e546c2015-06-11 15:13:57 +00001999 def test_no_job_project(self):
2000 "Test that reports with no jobs don't get sent"
2001 A = self.fake_gerrit.addFakeChange('org/no-jobs-project',
2002 'master', 'A')
2003 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2004 self.waitUntilSettled()
2005
2006 # Change wasn't reported to
2007 self.assertEqual(A.reported, False)
2008
2009 # Check queue is empty afterwards
2010 check_pipeline = self.sched.layout.pipelines['check']
2011 items = check_pipeline.getAllItems()
2012 self.assertEqual(len(items), 0)
2013
2014 self.assertEqual(len(self.history), 0)
2015
James E. Blair7d0dedc2013-02-21 17:26:09 -08002016 def test_zuul_refs(self):
2017 "Test that zuul refs exist and have the right changes"
James E. Blair08d19992016-08-10 15:25:31 -07002018 self.launch_server.hold_jobs_in_build = True
James E. Blair7d0dedc2013-02-21 17:26:09 -08002019 M1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'M1')
2020 M1.setMerged()
2021 M2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'M2')
2022 M2.setMerged()
2023
2024 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2025 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2026 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
2027 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
James E. Blair8b5408c2016-08-08 15:37:46 -07002028 A.addApproval('code-review', 2)
2029 B.addApproval('code-review', 2)
2030 C.addApproval('code-review', 2)
2031 D.addApproval('code-review', 2)
2032 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
2033 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
2034 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
2035 self.fake_gerrit.addEvent(D.addApproval('approved', 1))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002036
2037 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002038 self.launch_server.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002039 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002040 self.launch_server.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002041 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002042 self.launch_server.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002043 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002044 self.launch_server.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002045 self.waitUntilSettled()
2046
James E. Blair7d0dedc2013-02-21 17:26:09 -08002047 a_zref = b_zref = c_zref = d_zref = None
Clint Byrum3343e3e2016-11-15 16:05:03 -08002048 a_build = b_build = c_build = d_build = None
Monty Taylor6bef8ef2013-06-02 08:17:12 -04002049 for x in self.builds:
James E. Blair7d0dedc2013-02-21 17:26:09 -08002050 if x.parameters['ZUUL_CHANGE'] == '3':
2051 a_zref = x.parameters['ZUUL_REF']
Clint Byrum3343e3e2016-11-15 16:05:03 -08002052 a_build = x
2053 elif x.parameters['ZUUL_CHANGE'] == '4':
James E. Blair7d0dedc2013-02-21 17:26:09 -08002054 b_zref = x.parameters['ZUUL_REF']
Clint Byrum3343e3e2016-11-15 16:05:03 -08002055 b_build = x
2056 elif x.parameters['ZUUL_CHANGE'] == '5':
James E. Blair7d0dedc2013-02-21 17:26:09 -08002057 c_zref = x.parameters['ZUUL_REF']
Clint Byrum3343e3e2016-11-15 16:05:03 -08002058 c_build = x
2059 elif x.parameters['ZUUL_CHANGE'] == '6':
James E. Blair7d0dedc2013-02-21 17:26:09 -08002060 d_zref = x.parameters['ZUUL_REF']
Clint Byrum3343e3e2016-11-15 16:05:03 -08002061 d_build = x
2062 if a_build and b_build and c_build and d_build:
2063 break
James E. Blair7d0dedc2013-02-21 17:26:09 -08002064
2065 # There are... four... refs.
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002066 self.assertIsNotNone(a_zref)
2067 self.assertIsNotNone(b_zref)
2068 self.assertIsNotNone(c_zref)
2069 self.assertIsNotNone(d_zref)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002070
2071 # And they should all be different
2072 refs = set([a_zref, b_zref, c_zref, d_zref])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002073 self.assertEqual(len(refs), 4)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002074
Clint Byrum3343e3e2016-11-15 16:05:03 -08002075 # should have a, not b, and should not be in project2
2076 self.assertTrue(a_build.hasChanges(A))
2077 self.assertFalse(a_build.hasChanges(B, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002078
Clint Byrum3343e3e2016-11-15 16:05:03 -08002079 # should have a and b, and should not be in project2
2080 self.assertTrue(b_build.hasChanges(A, B))
2081 self.assertFalse(b_build.hasChanges(M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002082
Clint Byrum3343e3e2016-11-15 16:05:03 -08002083 # should have a and b in 1, c in 2
2084 self.assertTrue(c_build.hasChanges(A, B, C))
2085 self.assertFalse(c_build.hasChanges(D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002086
Clint Byrum3343e3e2016-11-15 16:05:03 -08002087 # should have a and b in 1, c and d in 2
2088 self.assertTrue(d_build.hasChanges(A, B, C, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002089
James E. Blair08d19992016-08-10 15:25:31 -07002090 self.launch_server.hold_jobs_in_build = False
2091 self.launch_server.release()
James E. Blair7d0dedc2013-02-21 17:26:09 -08002092 self.waitUntilSettled()
2093
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002094 self.assertEqual(A.data['status'], 'MERGED')
2095 self.assertEqual(A.reported, 2)
2096 self.assertEqual(B.data['status'], 'MERGED')
2097 self.assertEqual(B.reported, 2)
2098 self.assertEqual(C.data['status'], 'MERGED')
2099 self.assertEqual(C.reported, 2)
2100 self.assertEqual(D.data['status'], 'MERGED')
2101 self.assertEqual(D.reported, 2)
James E. Blair70c71582013-03-06 08:50:50 -08002102
James E. Blairec056492016-07-22 09:45:56 -07002103 @skip("Disabled for early v3 development")
James E. Blair4a28a882013-08-23 15:17:33 -07002104 def test_rerun_on_error(self):
2105 "Test that if a worker fails to run a job, it is run again"
James E. Blair08d19992016-08-10 15:25:31 -07002106 self.launch_server.hold_jobs_in_build = True
James E. Blair4a28a882013-08-23 15:17:33 -07002107 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. Blair4a28a882013-08-23 15:17:33 -07002110 self.waitUntilSettled()
2111
2112 self.builds[0].run_error = True
James E. Blair08d19992016-08-10 15:25:31 -07002113 self.launch_server.hold_jobs_in_build = False
2114 self.launch_server.release()
James E. Blair4a28a882013-08-23 15:17:33 -07002115 self.waitUntilSettled()
2116 self.assertEqual(self.countJobResults(self.history, 'RUN_ERROR'), 1)
2117 self.assertEqual(self.countJobResults(self.history, 'SUCCESS'), 3)
2118
James E. Blair412e5582013-04-22 15:50:12 -07002119 def test_statsd(self):
2120 "Test each of the statsd methods used in the scheduler"
2121 import extras
2122 statsd = extras.try_import('statsd.statsd')
2123 statsd.incr('test-incr')
2124 statsd.timing('test-timing', 3)
Alex Gaynor813d39b2014-05-17 16:17:16 -07002125 statsd.gauge('test-gauge', 12)
James E. Blair412e5582013-04-22 15:50:12 -07002126 self.assertReportedStat('test-incr', '1|c')
2127 self.assertReportedStat('test-timing', '3|ms')
Alex Gaynor813d39b2014-05-17 16:17:16 -07002128 self.assertReportedStat('test-gauge', '12|g')
James E. Blair412e5582013-04-22 15:50:12 -07002129
James E. Blairec056492016-07-22 09:45:56 -07002130 @skip("Disabled for early v3 development")
James E. Blairdad52252014-02-07 16:59:17 -08002131 def test_stuck_job_cleanup(self):
2132 "Test that pending jobs are cleaned up if removed from layout"
James E. Blair18c64442014-03-18 10:14:45 -07002133 # This job won't be registered at startup because it is not in
2134 # the standard layout, but we need it to already be registerd
2135 # for when we reconfigure, as that is when Zuul will attempt
2136 # to run the new job.
2137 self.worker.registerFunction('build:gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002138 self.gearman_server.hold_jobs_in_queue = True
2139 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07002140 A.addApproval('code-review', 2)
2141 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blairdad52252014-02-07 16:59:17 -08002142 self.waitUntilSettled()
2143 self.assertEqual(len(self.gearman_server.getQueue()), 1)
2144
James E. Blairf84026c2015-12-08 16:11:46 -08002145 self.updateConfigLayout(
2146 'tests/fixtures/layout-no-jobs.yaml')
James E. Blairdad52252014-02-07 16:59:17 -08002147 self.sched.reconfigure(self.config)
2148 self.waitUntilSettled()
2149
James E. Blair18c64442014-03-18 10:14:45 -07002150 self.gearman_server.release('gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002151 self.waitUntilSettled()
2152 self.assertEqual(len(self.gearman_server.getQueue()), 0)
2153 self.assertTrue(self.sched._areAllBuildsComplete())
2154
2155 self.assertEqual(len(self.history), 1)
James E. Blair18c64442014-03-18 10:14:45 -07002156 self.assertEqual(self.history[0].name, 'gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002157 self.assertEqual(self.history[0].result, 'SUCCESS')
2158
James E. Blair879dafb2015-07-17 14:04:49 -07002159 def test_file_head(self):
2160 # This is a regression test for an observed bug. A change
2161 # with a file named "HEAD" in the root directory of the repo
2162 # was processed by a merger. It then was unable to reset the
2163 # repo because of:
2164 # GitCommandError: 'git reset --hard HEAD' returned
2165 # with exit code 128
2166 # stderr: 'fatal: ambiguous argument 'HEAD': both revision
2167 # and filename
2168 # Use '--' to separate filenames from revisions'
2169
2170 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
Paul Belangera91095f2016-11-04 19:28:48 -04002171 A.addPatchset({'HEAD': ''})
James E. Blair879dafb2015-07-17 14:04:49 -07002172 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2173
2174 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
2175 self.waitUntilSettled()
2176
2177 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2178 self.waitUntilSettled()
2179
2180 self.assertIn('Build succeeded', A.messages[0])
2181 self.assertIn('Build succeeded', B.messages[0])
2182
James E. Blairec056492016-07-22 09:45:56 -07002183 @skip("Disabled for early v3 development")
James E. Blair70c71582013-03-06 08:50:50 -08002184 def test_file_jobs(self):
2185 "Test that file jobs run only when appropriate"
2186 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2187 A.addPatchset(['pip-requires'])
2188 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07002189 A.addApproval('code-review', 2)
2190 B.addApproval('code-review', 2)
2191 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
2192 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair70c71582013-03-06 08:50:50 -08002193 self.waitUntilSettled()
2194
Monty Taylor6bef8ef2013-06-02 08:17:12 -04002195 testfile_jobs = [x for x in self.history
James E. Blair70c71582013-03-06 08:50:50 -08002196 if x.name == 'project-testfile']
2197
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002198 self.assertEqual(len(testfile_jobs), 1)
2199 self.assertEqual(testfile_jobs[0].changes, '1,2')
2200 self.assertEqual(A.data['status'], 'MERGED')
2201 self.assertEqual(A.reported, 2)
2202 self.assertEqual(B.data['status'], 'MERGED')
2203 self.assertEqual(B.reported, 2)
James E. Blair3c5e5b52013-04-26 11:17:03 -07002204
Clint Byrum3ee39f32016-11-17 23:45:07 -08002205 def _test_irrelevant_files_jobs(self, should_skip):
2206 "Test that jobs with irrelevant-files filter run only when appropriate"
2207 self.updateConfigLayout('layout-irrelevant-files')
Maru Newby3fe5f852015-01-13 04:22:14 +00002208 self.sched.reconfigure(self.config)
Clint Byrum3ee39f32016-11-17 23:45:07 -08002209
2210 if should_skip:
2211 files = {'ignoreme': 'ignored\n'}
2212 else:
2213 files = {'respectme': 'please!\n'}
Maru Newby3fe5f852015-01-13 04:22:14 +00002214
2215 change = self.fake_gerrit.addFakeChange('org/project',
Clint Byrum3ee39f32016-11-17 23:45:07 -08002216 'master',
2217 'test irrelevant-files',
2218 files=files)
Maru Newby3fe5f852015-01-13 04:22:14 +00002219 self.fake_gerrit.addEvent(change.getPatchsetCreatedEvent(1))
2220 self.waitUntilSettled()
2221
2222 tested_change_ids = [x.changes[0] for x in self.history
Clint Byrum3ee39f32016-11-17 23:45:07 -08002223 if x.name == 'project-test-irrelevant-files']
Maru Newby3fe5f852015-01-13 04:22:14 +00002224
2225 if should_skip:
2226 self.assertEqual([], tested_change_ids)
2227 else:
2228 self.assertIn(change.data['number'], tested_change_ids)
2229
Clint Byrum3ee39f32016-11-17 23:45:07 -08002230 def test_irrelevant_files_match_skips_job(self):
2231 self._test_irrelevant_files_jobs(should_skip=True)
Maru Newby3fe5f852015-01-13 04:22:14 +00002232
Clint Byrum3ee39f32016-11-17 23:45:07 -08002233 def test_irrelevant_files_no_match_runs_job(self):
2234 self._test_irrelevant_files_jobs(should_skip=False)
Maru Newby3fe5f852015-01-13 04:22:14 +00002235
James E. Blairec056492016-07-22 09:45:56 -07002236 @skip("Disabled for early v3 development")
James E. Blair3c5e5b52013-04-26 11:17:03 -07002237 def test_test_config(self):
2238 "Test that we can test the config"
James E. Blairf84026c2015-12-08 16:11:46 -08002239 self.sched.testConfig(self.config.get('zuul', 'tenant_config'),
Joshua Hesketh352264b2015-08-11 23:42:08 +10002240 self.connections)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002241
James E. Blairec056492016-07-22 09:45:56 -07002242 @skip("Disabled for early v3 development")
James E. Blairc8a1e052014-02-25 09:29:26 -08002243 def test_queue_names(self):
2244 "Test shared change queue names"
2245 project1 = self.sched.layout.projects['org/project1']
2246 project2 = self.sched.layout.projects['org/project2']
2247 q1 = self.sched.layout.pipelines['gate'].getQueue(project1)
2248 q2 = self.sched.layout.pipelines['gate'].getQueue(project2)
2249 self.assertEqual(q1.name, 'integration')
2250 self.assertEqual(q2.name, 'integration')
2251
James E. Blairf84026c2015-12-08 16:11:46 -08002252 self.updateConfigLayout(
2253 'tests/fixtures/layout-bad-queue.yaml')
James E. Blairc8a1e052014-02-25 09:29:26 -08002254 with testtools.ExpectedException(
2255 Exception, "More than one name assigned to change queue"):
2256 self.sched.reconfigure(self.config)
2257
James E. Blair64ed6f22013-07-10 14:07:23 -07002258 def test_queue_precedence(self):
2259 "Test that queue precedence works"
2260
2261 self.gearman_server.hold_jobs_in_queue = True
James E. Blair08d19992016-08-10 15:25:31 -07002262 self.launch_server.hold_jobs_in_build = True
James E. Blair64ed6f22013-07-10 14:07:23 -07002263 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2264 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
James E. Blair8b5408c2016-08-08 15:37:46 -07002265 A.addApproval('code-review', 2)
2266 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair64ed6f22013-07-10 14:07:23 -07002267
2268 self.waitUntilSettled()
2269 self.gearman_server.hold_jobs_in_queue = False
2270 self.gearman_server.release()
2271 self.waitUntilSettled()
2272
James E. Blair8de58bd2013-07-18 16:23:33 -07002273 # Run one build at a time to ensure non-race order:
James E. Blairb8c16472015-05-05 14:55:26 -07002274 self.orderedRelease()
James E. Blair08d19992016-08-10 15:25:31 -07002275 self.launch_server.hold_jobs_in_build = False
James E. Blair8de58bd2013-07-18 16:23:33 -07002276 self.waitUntilSettled()
2277
James E. Blair64ed6f22013-07-10 14:07:23 -07002278 self.log.debug(self.history)
2279 self.assertEqual(self.history[0].pipeline, 'gate')
2280 self.assertEqual(self.history[1].pipeline, 'check')
2281 self.assertEqual(self.history[2].pipeline, 'gate')
2282 self.assertEqual(self.history[3].pipeline, 'gate')
2283 self.assertEqual(self.history[4].pipeline, 'check')
2284 self.assertEqual(self.history[5].pipeline, 'check')
2285
James E. Blairec056492016-07-22 09:45:56 -07002286 @skip("Disabled for early v3 development")
Clark Boylana5edbe42014-06-03 16:39:10 -07002287 def test_json_status(self):
James E. Blair1843a552013-07-03 14:19:52 -07002288 "Test that we can retrieve JSON status info"
James E. Blair08d19992016-08-10 15:25:31 -07002289 self.launch_server.hold_jobs_in_build = True
James E. Blair1843a552013-07-03 14:19:52 -07002290 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07002291 A.addApproval('code-review', 2)
2292 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair1843a552013-07-03 14:19:52 -07002293 self.waitUntilSettled()
2294
James E. Blair08d19992016-08-10 15:25:31 -07002295 self.launch_server.release('project-merge')
James E. Blairb7273ef2016-04-19 08:58:51 -07002296 self.waitUntilSettled()
2297
James E. Blair1843a552013-07-03 14:19:52 -07002298 port = self.webapp.server.socket.getsockname()[1]
2299
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002300 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2301 f = urllib.request.urlopen(req)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002302 headers = f.info()
2303 self.assertIn('Content-Length', headers)
2304 self.assertIn('Content-Type', headers)
Sachi Kingdc963fc2016-03-23 16:00:33 +11002305 self.assertIsNotNone(re.match('^application/json(; charset=UTF-8)?$',
2306 headers['Content-Type']))
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002307 self.assertIn('Access-Control-Allow-Origin', headers)
2308 self.assertIn('Cache-Control', headers)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002309 self.assertIn('Last-Modified', headers)
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002310 self.assertIn('Expires', headers)
James E. Blair1843a552013-07-03 14:19:52 -07002311 data = f.read()
2312
James E. Blair08d19992016-08-10 15:25:31 -07002313 self.launch_server.hold_jobs_in_build = False
2314 self.launch_server.release()
James E. Blair1843a552013-07-03 14:19:52 -07002315 self.waitUntilSettled()
2316
2317 data = json.loads(data)
James E. Blairb7273ef2016-04-19 08:58:51 -07002318 status_jobs = []
James E. Blair1843a552013-07-03 14:19:52 -07002319 for p in data['pipelines']:
2320 for q in p['change_queues']:
James E. Blairbfb8e042014-12-30 17:01:44 -08002321 if p['name'] in ['gate', 'conflict']:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002322 self.assertEqual(q['window'], 20)
2323 else:
2324 self.assertEqual(q['window'], 0)
James E. Blair1843a552013-07-03 14:19:52 -07002325 for head in q['heads']:
2326 for change in head:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002327 self.assertTrue(change['active'])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002328 self.assertEqual(change['id'], '1,1')
James E. Blair1843a552013-07-03 14:19:52 -07002329 for job in change['jobs']:
James E. Blairb7273ef2016-04-19 08:58:51 -07002330 status_jobs.append(job)
2331 self.assertEqual('project-merge', status_jobs[0]['name'])
2332 self.assertEqual('https://server/job/project-merge/0/',
2333 status_jobs[0]['url'])
2334 self.assertEqual('http://logs.example.com/1/1/gate/project-merge/0',
2335 status_jobs[0]['report_url'])
2336
2337 self.assertEqual('project-test1', status_jobs[1]['name'])
2338 self.assertEqual('https://server/job/project-test1/1/',
2339 status_jobs[1]['url'])
2340 self.assertEqual('http://logs.example.com/1/1/gate/project-test1/1',
2341 status_jobs[1]['report_url'])
2342
2343 self.assertEqual('project-test2', status_jobs[2]['name'])
2344 self.assertEqual('https://server/job/project-test2/2/',
2345 status_jobs[2]['url'])
2346 self.assertEqual('http://logs.example.com/1/1/gate/project-test2/2',
2347 status_jobs[2]['report_url'])
James E. Blair1843a552013-07-03 14:19:52 -07002348
James E. Blairec056492016-07-22 09:45:56 -07002349 @skip("Disabled for early v3 development")
James E. Blairc3d428e2013-12-03 15:06:48 -08002350 def test_merging_queues(self):
2351 "Test that transitively-connected change queues are merged"
James E. Blairf84026c2015-12-08 16:11:46 -08002352 self.updateConfigLayout(
2353 'tests/fixtures/layout-merge-queues.yaml')
James E. Blairc3d428e2013-12-03 15:06:48 -08002354 self.sched.reconfigure(self.config)
2355 self.assertEqual(len(self.sched.layout.pipelines['gate'].queues), 1)
2356
James E. Blairec056492016-07-22 09:45:56 -07002357 @skip("Disabled for early v3 development")
James E. Blairaf17a972016-02-03 15:07:18 -08002358 def test_mutex(self):
2359 "Test job mutexes"
2360 self.config.set('zuul', 'layout_config',
2361 'tests/fixtures/layout-mutex.yaml')
2362 self.sched.reconfigure(self.config)
2363
James E. Blair08d19992016-08-10 15:25:31 -07002364 self.launch_server.hold_jobs_in_build = True
James E. Blairaf17a972016-02-03 15:07:18 -08002365 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2366 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2367 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2368
2369 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2370 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2371 self.waitUntilSettled()
2372 self.assertEqual(len(self.builds), 3)
2373 self.assertEqual(self.builds[0].name, 'project-test1')
2374 self.assertEqual(self.builds[1].name, 'mutex-one')
2375 self.assertEqual(self.builds[2].name, 'project-test1')
2376
James E. Blair08d19992016-08-10 15:25:31 -07002377 self.launch_server.release('mutex-one')
James E. Blairaf17a972016-02-03 15:07:18 -08002378 self.waitUntilSettled()
2379
2380 self.assertEqual(len(self.builds), 3)
2381 self.assertEqual(self.builds[0].name, 'project-test1')
2382 self.assertEqual(self.builds[1].name, 'project-test1')
2383 self.assertEqual(self.builds[2].name, 'mutex-two')
2384 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2385
James E. Blair08d19992016-08-10 15:25:31 -07002386 self.launch_server.release('mutex-two')
James E. Blairaf17a972016-02-03 15:07:18 -08002387 self.waitUntilSettled()
2388
2389 self.assertEqual(len(self.builds), 3)
2390 self.assertEqual(self.builds[0].name, 'project-test1')
2391 self.assertEqual(self.builds[1].name, 'project-test1')
2392 self.assertEqual(self.builds[2].name, 'mutex-one')
2393 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2394
James E. Blair08d19992016-08-10 15:25:31 -07002395 self.launch_server.release('mutex-one')
James E. Blairaf17a972016-02-03 15:07:18 -08002396 self.waitUntilSettled()
2397
2398 self.assertEqual(len(self.builds), 3)
2399 self.assertEqual(self.builds[0].name, 'project-test1')
2400 self.assertEqual(self.builds[1].name, 'project-test1')
2401 self.assertEqual(self.builds[2].name, 'mutex-two')
2402 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2403
James E. Blair08d19992016-08-10 15:25:31 -07002404 self.launch_server.release('mutex-two')
James E. Blairaf17a972016-02-03 15:07:18 -08002405 self.waitUntilSettled()
2406
2407 self.assertEqual(len(self.builds), 2)
2408 self.assertEqual(self.builds[0].name, 'project-test1')
2409 self.assertEqual(self.builds[1].name, 'project-test1')
2410 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2411
James E. Blair08d19992016-08-10 15:25:31 -07002412 self.launch_server.hold_jobs_in_build = False
2413 self.launch_server.release()
James E. Blairaf17a972016-02-03 15:07:18 -08002414
2415 self.waitUntilSettled()
2416 self.assertEqual(len(self.builds), 0)
2417
2418 self.assertEqual(A.reported, 1)
2419 self.assertEqual(B.reported, 1)
2420 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2421
James E. Blairec056492016-07-22 09:45:56 -07002422 @skip("Disabled for early v3 development")
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002423 def test_node_label(self):
2424 "Test that a job runs on a specific node label"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002425 self.worker.registerFunction('build:node-project-test1:debian')
2426
2427 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07002428 A.addApproval('code-review', 2)
2429 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002430 self.waitUntilSettled()
James E. Blair4ca985f2013-05-30 12:27:43 -07002431
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002432 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2433 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2434 'debian')
2435 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
James E. Blaircdccd972013-07-01 12:10:22 -07002436
2437 def test_live_reconfiguration(self):
2438 "Test that live reconfiguration works"
James E. Blair08d19992016-08-10 15:25:31 -07002439 self.launch_server.hold_jobs_in_build = True
James E. Blaircdccd972013-07-01 12:10:22 -07002440 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07002441 A.addApproval('code-review', 2)
2442 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blaircdccd972013-07-01 12:10:22 -07002443 self.waitUntilSettled()
2444
2445 self.sched.reconfigure(self.config)
2446
James E. Blair08d19992016-08-10 15:25:31 -07002447 self.launch_server.hold_jobs_in_build = False
2448 self.launch_server.release()
James E. Blaircdccd972013-07-01 12:10:22 -07002449 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002450 self.assertEqual(self.getJobFromHistory('project-merge').result,
2451 'SUCCESS')
2452 self.assertEqual(self.getJobFromHistory('project-test1').result,
2453 'SUCCESS')
2454 self.assertEqual(self.getJobFromHistory('project-test2').result,
2455 'SUCCESS')
2456 self.assertEqual(A.data['status'], 'MERGED')
2457 self.assertEqual(A.reported, 2)
James E. Blair287c06d2013-07-24 10:39:30 -07002458
James E. Blairec056492016-07-22 09:45:56 -07002459 @skip("Disabled for early v3 development")
James E. Blair6bc782d2015-07-17 16:20:21 -07002460 def test_live_reconfiguration_merge_conflict(self):
2461 # A real-world bug: a change in a gate queue has a merge
2462 # conflict and a job is added to its project while it's
2463 # sitting in the queue. The job gets added to the change and
2464 # enqueued and the change gets stuck.
2465 self.worker.registerFunction('build:project-test3')
James E. Blair08d19992016-08-10 15:25:31 -07002466 self.launch_server.hold_jobs_in_build = True
James E. Blair6bc782d2015-07-17 16:20:21 -07002467
2468 # This change is fine. It's here to stop the queue long
2469 # enough for the next change to be subject to the
2470 # reconfiguration, as well as to provide a conflict for the
2471 # next change. This change will succeed and merge.
2472 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2473 A.addPatchset(['conflict'])
James E. Blair8b5408c2016-08-08 15:37:46 -07002474 A.addApproval('code-review', 2)
James E. Blair6bc782d2015-07-17 16:20:21 -07002475
2476 # This change will be in merge conflict. During the
2477 # reconfiguration, we will add a job. We want to make sure
2478 # that doesn't cause it to get stuck.
2479 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2480 B.addPatchset(['conflict'])
James E. Blair8b5408c2016-08-08 15:37:46 -07002481 B.addApproval('code-review', 2)
James E. Blair4eb21fa2015-07-27 14:56:47 -07002482
James E. Blair8b5408c2016-08-08 15:37:46 -07002483 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
2484 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair6bc782d2015-07-17 16:20:21 -07002485
2486 self.waitUntilSettled()
2487
2488 # No jobs have run yet
2489 self.assertEqual(A.data['status'], 'NEW')
2490 self.assertEqual(A.reported, 1)
2491 self.assertEqual(B.data['status'], 'NEW')
2492 self.assertEqual(B.reported, 1)
2493 self.assertEqual(len(self.history), 0)
2494
2495 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002496 self.updateConfigLayout(
2497 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002498 self.sched.reconfigure(self.config)
2499 self.waitUntilSettled()
2500
James E. Blair08d19992016-08-10 15:25:31 -07002501 self.launch_server.hold_jobs_in_build = False
2502 self.launch_server.release()
James E. Blair6bc782d2015-07-17 16:20:21 -07002503 self.waitUntilSettled()
2504
2505 self.assertEqual(A.data['status'], 'MERGED')
2506 self.assertEqual(A.reported, 2)
2507 self.assertEqual(B.data['status'], 'NEW')
2508 self.assertEqual(B.reported, 2)
2509 self.assertEqual(self.getJobFromHistory('project-merge').result,
2510 'SUCCESS')
2511 self.assertEqual(self.getJobFromHistory('project-test1').result,
2512 'SUCCESS')
2513 self.assertEqual(self.getJobFromHistory('project-test2').result,
2514 'SUCCESS')
2515 self.assertEqual(self.getJobFromHistory('project-test3').result,
2516 'SUCCESS')
2517 self.assertEqual(len(self.history), 4)
2518
James E. Blairec056492016-07-22 09:45:56 -07002519 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002520 def test_live_reconfiguration_failed_root(self):
James E. Blair6bc782d2015-07-17 16:20:21 -07002521 # An extrapolation of test_live_reconfiguration_merge_conflict
2522 # that tests a job added to a job tree with a failed root does
2523 # not run.
2524 self.worker.registerFunction('build:project-test3')
James E. Blair08d19992016-08-10 15:25:31 -07002525 self.launch_server.hold_jobs_in_build = True
James E. Blair6bc782d2015-07-17 16:20:21 -07002526
2527 # This change is fine. It's here to stop the queue long
2528 # enough for the next change to be subject to the
2529 # reconfiguration. This change will succeed and merge.
2530 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2531 A.addPatchset(['conflict'])
James E. Blair8b5408c2016-08-08 15:37:46 -07002532 A.addApproval('code-review', 2)
2533 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair6bc782d2015-07-17 16:20:21 -07002534 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002535 self.launch_server.release('.*-merge')
James E. Blair6bc782d2015-07-17 16:20:21 -07002536 self.waitUntilSettled()
2537
2538 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair08d19992016-08-10 15:25:31 -07002539 self.launch_server.failJob('project-merge', B)
James E. Blair8b5408c2016-08-08 15:37:46 -07002540 B.addApproval('code-review', 2)
2541 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair6bc782d2015-07-17 16:20:21 -07002542 self.waitUntilSettled()
2543
James E. Blair08d19992016-08-10 15:25:31 -07002544 self.launch_server.release('.*-merge')
James E. Blair6bc782d2015-07-17 16:20:21 -07002545 self.waitUntilSettled()
2546
2547 # Both -merge jobs have run, but no others.
2548 self.assertEqual(A.data['status'], 'NEW')
2549 self.assertEqual(A.reported, 1)
2550 self.assertEqual(B.data['status'], 'NEW')
2551 self.assertEqual(B.reported, 1)
2552 self.assertEqual(self.history[0].result, 'SUCCESS')
2553 self.assertEqual(self.history[0].name, 'project-merge')
2554 self.assertEqual(self.history[1].result, 'FAILURE')
2555 self.assertEqual(self.history[1].name, 'project-merge')
2556 self.assertEqual(len(self.history), 2)
2557
2558 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002559 self.updateConfigLayout(
2560 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002561 self.sched.reconfigure(self.config)
2562 self.waitUntilSettled()
2563
James E. Blair08d19992016-08-10 15:25:31 -07002564 self.launch_server.hold_jobs_in_build = False
2565 self.launch_server.release()
James E. Blair6bc782d2015-07-17 16:20:21 -07002566 self.waitUntilSettled()
2567
2568 self.assertEqual(A.data['status'], 'MERGED')
2569 self.assertEqual(A.reported, 2)
2570 self.assertEqual(B.data['status'], 'NEW')
2571 self.assertEqual(B.reported, 2)
2572 self.assertEqual(self.history[0].result, 'SUCCESS')
2573 self.assertEqual(self.history[0].name, 'project-merge')
2574 self.assertEqual(self.history[1].result, 'FAILURE')
2575 self.assertEqual(self.history[1].name, 'project-merge')
2576 self.assertEqual(self.history[2].result, 'SUCCESS')
2577 self.assertEqual(self.history[3].result, 'SUCCESS')
2578 self.assertEqual(self.history[4].result, 'SUCCESS')
2579 self.assertEqual(len(self.history), 5)
2580
James E. Blairec056492016-07-22 09:45:56 -07002581 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002582 def test_live_reconfiguration_failed_job(self):
2583 # Test that a change with a removed failing job does not
2584 # disrupt reconfiguration. If a change has a failed job and
2585 # that job is removed during a reconfiguration, we observed a
2586 # bug where the code to re-set build statuses would run on
2587 # that build and raise an exception because the job no longer
2588 # existed.
James E. Blair08d19992016-08-10 15:25:31 -07002589 self.launch_server.hold_jobs_in_build = True
James E. Blair400e8fd2015-07-30 17:44:45 -07002590
2591 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2592
2593 # This change will fail and later be removed by the reconfiguration.
James E. Blair08d19992016-08-10 15:25:31 -07002594 self.launch_server.failJob('project-test1', A)
James E. Blair400e8fd2015-07-30 17:44:45 -07002595
2596 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2597 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002598 self.launch_server.release('.*-merge')
James E. Blair400e8fd2015-07-30 17:44:45 -07002599 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002600 self.launch_server.release('project-test1')
James E. Blair400e8fd2015-07-30 17:44:45 -07002601 self.waitUntilSettled()
2602
2603 self.assertEqual(A.data['status'], 'NEW')
2604 self.assertEqual(A.reported, 0)
2605
2606 self.assertEqual(self.getJobFromHistory('project-merge').result,
2607 'SUCCESS')
2608 self.assertEqual(self.getJobFromHistory('project-test1').result,
2609 'FAILURE')
2610 self.assertEqual(len(self.history), 2)
2611
2612 # Remove the test1 job.
James E. Blairf84026c2015-12-08 16:11:46 -08002613 self.updateConfigLayout(
2614 'tests/fixtures/layout-live-reconfiguration-failed-job.yaml')
James E. Blair400e8fd2015-07-30 17:44:45 -07002615 self.sched.reconfigure(self.config)
2616 self.waitUntilSettled()
2617
James E. Blair08d19992016-08-10 15:25:31 -07002618 self.launch_server.hold_jobs_in_build = False
2619 self.launch_server.release()
James E. Blair400e8fd2015-07-30 17:44:45 -07002620 self.waitUntilSettled()
2621
2622 self.assertEqual(self.getJobFromHistory('project-test2').result,
2623 'SUCCESS')
2624 self.assertEqual(self.getJobFromHistory('project-testfile').result,
2625 'SUCCESS')
2626 self.assertEqual(len(self.history), 4)
2627
2628 self.assertEqual(A.data['status'], 'NEW')
2629 self.assertEqual(A.reported, 1)
2630 self.assertIn('Build succeeded', A.messages[0])
2631 # Ensure the removed job was not included in the report.
2632 self.assertNotIn('project-test1', A.messages[0])
2633
James E. Blairec056492016-07-22 09:45:56 -07002634 @skip("Disabled for early v3 development")
James E. Blairfe707d12015-08-05 15:18:15 -07002635 def test_live_reconfiguration_shared_queue(self):
2636 # Test that a change with a failing job which was removed from
2637 # this project but otherwise still exists in the system does
2638 # not disrupt reconfiguration.
2639
James E. Blair08d19992016-08-10 15:25:31 -07002640 self.launch_server.hold_jobs_in_build = True
James E. Blairfe707d12015-08-05 15:18:15 -07002641
2642 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2643
James E. Blair08d19992016-08-10 15:25:31 -07002644 self.launch_server.failJob('project1-project2-integration', A)
James E. Blairfe707d12015-08-05 15:18:15 -07002645
2646 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2647 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002648 self.launch_server.release('.*-merge')
James E. Blairfe707d12015-08-05 15:18:15 -07002649 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002650 self.launch_server.release('project1-project2-integration')
James E. Blairfe707d12015-08-05 15:18:15 -07002651 self.waitUntilSettled()
2652
2653 self.assertEqual(A.data['status'], 'NEW')
2654 self.assertEqual(A.reported, 0)
2655
2656 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2657 'SUCCESS')
2658 self.assertEqual(self.getJobFromHistory(
2659 'project1-project2-integration').result, 'FAILURE')
2660 self.assertEqual(len(self.history), 2)
2661
2662 # Remove the integration job.
James E. Blairf84026c2015-12-08 16:11:46 -08002663 self.updateConfigLayout(
2664 'tests/fixtures/layout-live-reconfiguration-shared-queue.yaml')
James E. Blairfe707d12015-08-05 15:18:15 -07002665 self.sched.reconfigure(self.config)
2666 self.waitUntilSettled()
2667
James E. Blair08d19992016-08-10 15:25:31 -07002668 self.launch_server.hold_jobs_in_build = False
2669 self.launch_server.release()
James E. Blairfe707d12015-08-05 15:18:15 -07002670 self.waitUntilSettled()
2671
2672 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2673 'SUCCESS')
2674 self.assertEqual(self.getJobFromHistory('project1-test1').result,
2675 'SUCCESS')
2676 self.assertEqual(self.getJobFromHistory('project1-test2').result,
2677 'SUCCESS')
2678 self.assertEqual(self.getJobFromHistory(
2679 'project1-project2-integration').result, 'FAILURE')
2680 self.assertEqual(len(self.history), 4)
2681
2682 self.assertEqual(A.data['status'], 'NEW')
2683 self.assertEqual(A.reported, 1)
2684 self.assertIn('Build succeeded', A.messages[0])
2685 # Ensure the removed job was not included in the report.
2686 self.assertNotIn('project1-project2-integration', A.messages[0])
2687
James E. Blairec056492016-07-22 09:45:56 -07002688 @skip("Disabled for early v3 development")
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002689 def test_double_live_reconfiguration_shared_queue(self):
2690 # This was a real-world regression. A change is added to
2691 # gate; a reconfigure happens, a second change which depends
2692 # on the first is added, and a second reconfiguration happens.
2693 # Ensure that both changes merge.
2694
2695 # A failure may indicate incorrect caching or cleaning up of
2696 # references during a reconfiguration.
James E. Blair08d19992016-08-10 15:25:31 -07002697 self.launch_server.hold_jobs_in_build = True
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002698
2699 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2700 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2701 B.setDependsOn(A, 1)
James E. Blair8b5408c2016-08-08 15:37:46 -07002702 A.addApproval('code-review', 2)
2703 B.addApproval('code-review', 2)
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002704
2705 # Add the parent change.
James E. Blair8b5408c2016-08-08 15:37:46 -07002706 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002707 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002708 self.launch_server.release('.*-merge')
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002709 self.waitUntilSettled()
2710
2711 # Reconfigure (with only one change in the pipeline).
2712 self.sched.reconfigure(self.config)
2713 self.waitUntilSettled()
2714
2715 # Add the child change.
James E. Blair8b5408c2016-08-08 15:37:46 -07002716 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002717 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002718 self.launch_server.release('.*-merge')
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002719 self.waitUntilSettled()
2720
2721 # Reconfigure (with both in the pipeline).
2722 self.sched.reconfigure(self.config)
2723 self.waitUntilSettled()
2724
James E. Blair08d19992016-08-10 15:25:31 -07002725 self.launch_server.hold_jobs_in_build = False
2726 self.launch_server.release()
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002727 self.waitUntilSettled()
2728
2729 self.assertEqual(len(self.history), 8)
2730
2731 self.assertEqual(A.data['status'], 'MERGED')
2732 self.assertEqual(A.reported, 2)
2733 self.assertEqual(B.data['status'], 'MERGED')
2734 self.assertEqual(B.reported, 2)
2735
James E. Blairec056492016-07-22 09:45:56 -07002736 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002737 def test_live_reconfiguration_del_project(self):
2738 # Test project deletion from layout
2739 # while changes are enqueued
2740
James E. Blair08d19992016-08-10 15:25:31 -07002741 self.launch_server.hold_jobs_in_build = True
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002742 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2743 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2744 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
2745
2746 # A Depends-On: B
2747 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
2748 A.subject, B.data['id'])
James E. Blair8b5408c2016-08-08 15:37:46 -07002749 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002750
2751 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2752 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
2753 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07002754 self.launch_server.release('.*-merge')
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002755 self.waitUntilSettled()
2756 self.assertEqual(len(self.builds), 5)
2757
2758 # This layout defines only org/project, not org/project1
James E. Blairf84026c2015-12-08 16:11:46 -08002759 self.updateConfigLayout(
2760 'tests/fixtures/layout-live-reconfiguration-del-project.yaml')
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002761 self.sched.reconfigure(self.config)
2762 self.waitUntilSettled()
2763
2764 # Builds for C aborted, builds for A succeed,
2765 # and have change B applied ahead
2766 job_c = self.getJobFromHistory('project1-test1')
2767 self.assertEqual(job_c.changes, '3,1')
2768 self.assertEqual(job_c.result, 'ABORTED')
2769
James E. Blair08d19992016-08-10 15:25:31 -07002770 self.launch_server.hold_jobs_in_build = False
2771 self.launch_server.release()
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002772 self.waitUntilSettled()
2773
2774 self.assertEqual(self.getJobFromHistory('project-test1').changes,
2775 '2,1 1,1')
2776
2777 self.assertEqual(A.data['status'], 'NEW')
2778 self.assertEqual(B.data['status'], 'NEW')
2779 self.assertEqual(C.data['status'], 'NEW')
2780 self.assertEqual(A.reported, 1)
2781 self.assertEqual(B.reported, 0)
2782 self.assertEqual(C.reported, 0)
2783
2784 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
2785 self.assertIn('Build succeeded', A.messages[0])
2786
James E. Blairec056492016-07-22 09:45:56 -07002787 @skip("Disabled for early v3 development")
James E. Blaire712d9f2013-07-31 11:40:11 -07002788 def test_live_reconfiguration_functions(self):
2789 "Test live reconfiguration with a custom function"
2790 self.worker.registerFunction('build:node-project-test1:debian')
2791 self.worker.registerFunction('build:node-project-test1:wheezy')
2792 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07002793 A.addApproval('code-review', 2)
2794 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blaire712d9f2013-07-31 11:40:11 -07002795 self.waitUntilSettled()
2796
2797 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2798 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2799 'debian')
2800 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2801
James E. Blairf84026c2015-12-08 16:11:46 -08002802 self.updateConfigLayout(
2803 'tests/fixtures/layout-live-reconfiguration-functions.yaml')
James E. Blaire712d9f2013-07-31 11:40:11 -07002804 self.sched.reconfigure(self.config)
2805 self.worker.build_history = []
2806
2807 B = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07002808 B.addApproval('code-review', 2)
2809 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blaire712d9f2013-07-31 11:40:11 -07002810 self.waitUntilSettled()
2811
2812 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2813 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2814 'wheezy')
2815 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2816
James E. Blairec056492016-07-22 09:45:56 -07002817 @skip("Disabled for early v3 development")
James E. Blair287c06d2013-07-24 10:39:30 -07002818 def test_delayed_repo_init(self):
James E. Blairf84026c2015-12-08 16:11:46 -08002819 self.updateConfigLayout(
2820 'tests/fixtures/layout-delayed-repo-init.yaml')
James E. Blair287c06d2013-07-24 10:39:30 -07002821 self.sched.reconfigure(self.config)
2822
2823 self.init_repo("org/new-project")
2824 A = self.fake_gerrit.addFakeChange('org/new-project', 'master', 'A')
2825
James E. Blair8b5408c2016-08-08 15:37:46 -07002826 A.addApproval('code-review', 2)
2827 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair287c06d2013-07-24 10:39:30 -07002828 self.waitUntilSettled()
2829 self.assertEqual(self.getJobFromHistory('project-merge').result,
2830 'SUCCESS')
2831 self.assertEqual(self.getJobFromHistory('project-test1').result,
2832 'SUCCESS')
2833 self.assertEqual(self.getJobFromHistory('project-test2').result,
2834 'SUCCESS')
2835 self.assertEqual(A.data['status'], 'MERGED')
2836 self.assertEqual(A.reported, 2)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002837
Clark Boylan6dbbc482013-10-18 10:57:31 -07002838 def test_repo_deleted(self):
Paul Belanger66e95962016-11-11 12:11:06 -05002839 self.updateConfigLayout('layout-repo-deleted')
Clark Boylan6dbbc482013-10-18 10:57:31 -07002840 self.sched.reconfigure(self.config)
2841
2842 self.init_repo("org/delete-project")
2843 A = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'A')
2844
James E. Blair8b5408c2016-08-08 15:37:46 -07002845 A.addApproval('code-review', 2)
2846 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Clark Boylan6dbbc482013-10-18 10:57:31 -07002847 self.waitUntilSettled()
2848 self.assertEqual(self.getJobFromHistory('project-merge').result,
2849 'SUCCESS')
2850 self.assertEqual(self.getJobFromHistory('project-test1').result,
2851 'SUCCESS')
2852 self.assertEqual(self.getJobFromHistory('project-test2').result,
2853 'SUCCESS')
2854 self.assertEqual(A.data['status'], 'MERGED')
2855 self.assertEqual(A.reported, 2)
2856
2857 # Delete org/new-project zuul repo. Should be recloned.
2858 shutil.rmtree(os.path.join(self.git_root, "org/delete-project"))
2859
2860 B = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'B')
2861
James E. Blair8b5408c2016-08-08 15:37:46 -07002862 B.addApproval('code-review', 2)
2863 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
Clark Boylan6dbbc482013-10-18 10:57:31 -07002864 self.waitUntilSettled()
2865 self.assertEqual(self.getJobFromHistory('project-merge').result,
2866 'SUCCESS')
2867 self.assertEqual(self.getJobFromHistory('project-test1').result,
2868 'SUCCESS')
2869 self.assertEqual(self.getJobFromHistory('project-test2').result,
2870 'SUCCESS')
2871 self.assertEqual(B.data['status'], 'MERGED')
2872 self.assertEqual(B.reported, 2)
2873
James E. Blairec056492016-07-22 09:45:56 -07002874 @skip("Disabled for early v3 development")
James E. Blair456f2fb2016-02-09 09:29:33 -08002875 def test_tags(self):
2876 "Test job tags"
2877 self.config.set('zuul', 'layout_config',
2878 'tests/fixtures/layout-tags.yaml')
2879 self.sched.reconfigure(self.config)
2880
2881 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2882 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
2883 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2884 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2885 self.waitUntilSettled()
2886
2887 results = {'project1-merge': 'extratag merge project1',
2888 'project2-merge': 'merge'}
2889
2890 for build in self.history:
2891 self.assertEqual(results.get(build.name, ''),
2892 build.parameters.get('BUILD_TAGS'))
2893
James E. Blairec056492016-07-22 09:45:56 -07002894 @skip("Disabled for early v3 development")
James E. Blair63bb0ef2013-07-29 17:14:51 -07002895 def test_timer(self):
2896 "Test that a periodic job is triggered"
James E. Blair08d19992016-08-10 15:25:31 -07002897 self.launch_server.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08002898 self.updateConfigLayout(
2899 'tests/fixtures/layout-timer.yaml')
James E. Blair63bb0ef2013-07-29 17:14:51 -07002900 self.sched.reconfigure(self.config)
2901 self.registerJobs()
2902
Clark Boylan3ee090a2014-04-03 20:55:09 -07002903 # The pipeline triggers every second, so we should have seen
2904 # several by now.
2905 time.sleep(5)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002906 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002907
2908 self.assertEqual(len(self.builds), 2)
2909
James E. Blair63bb0ef2013-07-29 17:14:51 -07002910 port = self.webapp.server.socket.getsockname()[1]
2911
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002912 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2913 f = urllib.request.urlopen(req)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002914 data = f.read()
2915
James E. Blair08d19992016-08-10 15:25:31 -07002916 self.launch_server.hold_jobs_in_build = False
Clark Boylan3ee090a2014-04-03 20:55:09 -07002917 # Stop queuing timer triggered jobs so that the assertions
2918 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08002919 self.updateConfigLayout(
2920 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002921 self.sched.reconfigure(self.config)
2922 self.registerJobs()
James E. Blair08d19992016-08-10 15:25:31 -07002923 self.launch_server.release()
James E. Blair63bb0ef2013-07-29 17:14:51 -07002924 self.waitUntilSettled()
2925
2926 self.assertEqual(self.getJobFromHistory(
2927 'project-bitrot-stable-old').result, 'SUCCESS')
2928 self.assertEqual(self.getJobFromHistory(
2929 'project-bitrot-stable-older').result, 'SUCCESS')
2930
2931 data = json.loads(data)
2932 status_jobs = set()
2933 for p in data['pipelines']:
2934 for q in p['change_queues']:
2935 for head in q['heads']:
2936 for change in head:
Alex Gaynorddb9ef32013-09-16 21:04:58 -07002937 self.assertEqual(change['id'], None)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002938 for job in change['jobs']:
2939 status_jobs.add(job['name'])
2940 self.assertIn('project-bitrot-stable-old', status_jobs)
2941 self.assertIn('project-bitrot-stable-older', status_jobs)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002942
James E. Blairec056492016-07-22 09:45:56 -07002943 @skip("Disabled for early v3 development")
James E. Blair4f6033c2014-03-27 15:49:09 -07002944 def test_idle(self):
2945 "Test that frequent periodic jobs work"
James E. Blair08d19992016-08-10 15:25:31 -07002946 self.launch_server.hold_jobs_in_build = True
James E. Blair4f6033c2014-03-27 15:49:09 -07002947
Clark Boylan3ee090a2014-04-03 20:55:09 -07002948 for x in range(1, 3):
2949 # Test that timer triggers periodic jobs even across
2950 # layout config reloads.
2951 # Start timer trigger
James E. Blairf84026c2015-12-08 16:11:46 -08002952 self.updateConfigLayout(
2953 'tests/fixtures/layout-idle.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002954 self.sched.reconfigure(self.config)
2955 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08002956 self.waitUntilSettled()
James E. Blair4f6033c2014-03-27 15:49:09 -07002957
Clark Boylan3ee090a2014-04-03 20:55:09 -07002958 # The pipeline triggers every second, so we should have seen
2959 # several by now.
2960 time.sleep(5)
Clark Boylan3ee090a2014-04-03 20:55:09 -07002961
2962 # Stop queuing timer triggered jobs so that the assertions
2963 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08002964 self.updateConfigLayout(
2965 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002966 self.sched.reconfigure(self.config)
2967 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08002968 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002969
2970 self.assertEqual(len(self.builds), 2)
James E. Blair08d19992016-08-10 15:25:31 -07002971 self.launch_server.release('.*')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002972 self.waitUntilSettled()
2973 self.assertEqual(len(self.builds), 0)
2974 self.assertEqual(len(self.history), x * 2)
James E. Blair4f6033c2014-03-27 15:49:09 -07002975
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002976 def test_check_smtp_pool(self):
Paul Belanger01be8ca2016-11-11 12:21:06 -05002977 self.updateConfigLayout('layout-smtp')
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002978 self.sched.reconfigure(self.config)
2979
2980 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2981 self.waitUntilSettled()
2982
2983 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2984 self.waitUntilSettled()
2985
James E. Blairff80a2f2013-12-27 13:24:06 -08002986 self.assertEqual(len(self.smtp_messages), 2)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002987
2988 # A.messages only holds what FakeGerrit places in it. Thus we
2989 # work on the knowledge of what the first message should be as
2990 # it is only configured to go to SMTP.
2991
2992 self.assertEqual('zuul@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08002993 self.smtp_messages[0]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002994 self.assertEqual(['you@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08002995 self.smtp_messages[0]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002996 self.assertEqual('Starting check jobs.',
James E. Blairff80a2f2013-12-27 13:24:06 -08002997 self.smtp_messages[0]['body'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002998
2999 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003000 self.smtp_messages[1]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003001 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003002 self.smtp_messages[1]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003003 self.assertEqual(A.messages[0],
James E. Blairff80a2f2013-12-27 13:24:06 -08003004 self.smtp_messages[1]['body'])
James E. Blairad28e912013-11-27 10:43:22 -08003005
James E. Blairec056492016-07-22 09:45:56 -07003006 @skip("Disabled for early v3 development")
James E. Blaire5910202013-12-27 09:50:31 -08003007 def test_timer_smtp(self):
3008 "Test that a periodic job is triggered"
James E. Blair08d19992016-08-10 15:25:31 -07003009 self.launch_server.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08003010 self.updateConfigLayout(
3011 'tests/fixtures/layout-timer-smtp.yaml')
James E. Blaire5910202013-12-27 09:50:31 -08003012 self.sched.reconfigure(self.config)
3013 self.registerJobs()
3014
Clark Boylan3ee090a2014-04-03 20:55:09 -07003015 # The pipeline triggers every second, so we should have seen
3016 # several by now.
3017 time.sleep(5)
James E. Blaire5910202013-12-27 09:50:31 -08003018 self.waitUntilSettled()
3019
Clark Boylan3ee090a2014-04-03 20:55:09 -07003020 self.assertEqual(len(self.builds), 2)
James E. Blair08d19992016-08-10 15:25:31 -07003021 self.launch_server.release('.*')
Clark Boylan3ee090a2014-04-03 20:55:09 -07003022 self.waitUntilSettled()
3023 self.assertEqual(len(self.history), 2)
3024
James E. Blaire5910202013-12-27 09:50:31 -08003025 self.assertEqual(self.getJobFromHistory(
3026 'project-bitrot-stable-old').result, 'SUCCESS')
3027 self.assertEqual(self.getJobFromHistory(
3028 'project-bitrot-stable-older').result, 'SUCCESS')
3029
James E. Blairff80a2f2013-12-27 13:24:06 -08003030 self.assertEqual(len(self.smtp_messages), 1)
James E. Blaire5910202013-12-27 09:50:31 -08003031
3032 # A.messages only holds what FakeGerrit places in it. Thus we
3033 # work on the knowledge of what the first message should be as
3034 # it is only configured to go to SMTP.
3035
3036 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003037 self.smtp_messages[0]['from_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003038 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003039 self.smtp_messages[0]['to_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003040 self.assertIn('Subject: Periodic check for org/project succeeded',
James E. Blairff80a2f2013-12-27 13:24:06 -08003041 self.smtp_messages[0]['headers'])
James E. Blaire5910202013-12-27 09:50:31 -08003042
Clark Boylan3ee090a2014-04-03 20:55:09 -07003043 # Stop queuing timer triggered jobs and let any that may have
3044 # queued through so that end of test assertions pass.
James E. Blairf84026c2015-12-08 16:11:46 -08003045 self.updateConfigLayout(
3046 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07003047 self.sched.reconfigure(self.config)
3048 self.registerJobs()
James E. Blairf8058972014-08-15 16:09:16 -07003049 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003050 self.launch_server.release('.*')
Clark Boylan3ee090a2014-04-03 20:55:09 -07003051 self.waitUntilSettled()
3052
James E. Blairec056492016-07-22 09:45:56 -07003053 @skip("Disabled for early v3 development")
James E. Blair91e34592015-07-31 16:45:59 -07003054 def test_client_enqueue_change(self):
James E. Blairad28e912013-11-27 10:43:22 -08003055 "Test that the RPC client can enqueue a change"
3056 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07003057 A.addApproval('code-review', 2)
3058 A.addApproval('approved', 1)
James E. Blairad28e912013-11-27 10:43:22 -08003059
3060 client = zuul.rpcclient.RPCClient('127.0.0.1',
3061 self.gearman_server.port)
3062 r = client.enqueue(pipeline='gate',
3063 project='org/project',
3064 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003065 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003066 self.waitUntilSettled()
3067 self.assertEqual(self.getJobFromHistory('project-merge').result,
3068 'SUCCESS')
3069 self.assertEqual(self.getJobFromHistory('project-test1').result,
3070 'SUCCESS')
3071 self.assertEqual(self.getJobFromHistory('project-test2').result,
3072 'SUCCESS')
3073 self.assertEqual(A.data['status'], 'MERGED')
3074 self.assertEqual(A.reported, 2)
3075 self.assertEqual(r, True)
3076
James E. Blairec056492016-07-22 09:45:56 -07003077 @skip("Disabled for early v3 development")
James E. Blair91e34592015-07-31 16:45:59 -07003078 def test_client_enqueue_ref(self):
3079 "Test that the RPC client can enqueue a ref"
3080
3081 client = zuul.rpcclient.RPCClient('127.0.0.1',
3082 self.gearman_server.port)
3083 r = client.enqueue_ref(
3084 pipeline='post',
3085 project='org/project',
3086 trigger='gerrit',
3087 ref='master',
3088 oldrev='90f173846e3af9154517b88543ffbd1691f31366',
3089 newrev='d479a0bfcb34da57a31adb2a595c0cf687812543')
3090 self.waitUntilSettled()
3091 job_names = [x.name for x in self.history]
3092 self.assertEqual(len(self.history), 1)
3093 self.assertIn('project-post', job_names)
3094 self.assertEqual(r, True)
3095
James E. Blairec056492016-07-22 09:45:56 -07003096 @skip("Disabled for early v3 development")
James E. Blairad28e912013-11-27 10:43:22 -08003097 def test_client_enqueue_negative(self):
3098 "Test that the RPC client returns errors"
3099 client = zuul.rpcclient.RPCClient('127.0.0.1',
3100 self.gearman_server.port)
3101 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3102 "Invalid project"):
3103 r = client.enqueue(pipeline='gate',
3104 project='project-does-not-exist',
3105 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003106 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003107 client.shutdown()
3108 self.assertEqual(r, False)
3109
3110 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3111 "Invalid pipeline"):
3112 r = client.enqueue(pipeline='pipeline-does-not-exist',
3113 project='org/project',
3114 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003115 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003116 client.shutdown()
3117 self.assertEqual(r, False)
3118
3119 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3120 "Invalid trigger"):
3121 r = client.enqueue(pipeline='gate',
3122 project='org/project',
3123 trigger='trigger-does-not-exist',
James E. Blair36658cf2013-12-06 17:53:48 -08003124 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003125 client.shutdown()
3126 self.assertEqual(r, False)
3127
3128 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3129 "Invalid change"):
3130 r = client.enqueue(pipeline='gate',
3131 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
James E. Blairec056492016-07-22 09:45:56 -07003141 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003142 def test_client_promote(self):
3143 "Test that the RPC client can promote a change"
James E. Blair08d19992016-08-10 15:25:31 -07003144 self.launch_server.hold_jobs_in_build = True
James E. Blair36658cf2013-12-06 17:53:48 -08003145 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3146 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3147 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07003148 A.addApproval('code-review', 2)
3149 B.addApproval('code-review', 2)
3150 C.addApproval('code-review', 2)
James E. Blair36658cf2013-12-06 17:53:48 -08003151
James E. Blair8b5408c2016-08-08 15:37:46 -07003152 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
3153 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
3154 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
James E. Blair36658cf2013-12-06 17:53:48 -08003155
3156 self.waitUntilSettled()
3157
Sean Daguef39b9ca2014-01-10 21:34:35 -05003158 items = self.sched.layout.pipelines['gate'].getAllItems()
3159 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)
3165 r = client.promote(pipeline='gate',
3166 change_ids=['2,1', '3,1'])
3167
Sean Daguef39b9ca2014-01-10 21:34:35 -05003168 # ensure that enqueue times are durable
3169 items = self.sched.layout.pipelines['gate'].getAllItems()
3170 for item in items:
3171 self.assertEqual(
3172 enqueue_times[str(item.change)], item.enqueue_time)
3173
James E. Blair78acec92014-02-06 07:11:32 -08003174 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003175 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003176 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003177 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003178 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003179 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003180 self.waitUntilSettled()
3181
3182 self.assertEqual(len(self.builds), 6)
3183 self.assertEqual(self.builds[0].name, 'project-test1')
3184 self.assertEqual(self.builds[1].name, 'project-test2')
3185 self.assertEqual(self.builds[2].name, 'project-test1')
3186 self.assertEqual(self.builds[3].name, 'project-test2')
3187 self.assertEqual(self.builds[4].name, 'project-test1')
3188 self.assertEqual(self.builds[5].name, 'project-test2')
3189
3190 self.assertTrue(self.job_has_changes(self.builds[0], B))
3191 self.assertFalse(self.job_has_changes(self.builds[0], A))
3192 self.assertFalse(self.job_has_changes(self.builds[0], C))
3193
3194 self.assertTrue(self.job_has_changes(self.builds[2], B))
3195 self.assertTrue(self.job_has_changes(self.builds[2], C))
3196 self.assertFalse(self.job_has_changes(self.builds[2], A))
3197
3198 self.assertTrue(self.job_has_changes(self.builds[4], B))
3199 self.assertTrue(self.job_has_changes(self.builds[4], C))
3200 self.assertTrue(self.job_has_changes(self.builds[4], A))
3201
James E. Blair08d19992016-08-10 15:25:31 -07003202 self.launch_server.release()
James E. Blair36658cf2013-12-06 17:53:48 -08003203 self.waitUntilSettled()
3204
3205 self.assertEqual(A.data['status'], 'MERGED')
3206 self.assertEqual(A.reported, 2)
3207 self.assertEqual(B.data['status'], 'MERGED')
3208 self.assertEqual(B.reported, 2)
3209 self.assertEqual(C.data['status'], 'MERGED')
3210 self.assertEqual(C.reported, 2)
3211
3212 client.shutdown()
3213 self.assertEqual(r, True)
3214
James E. Blairec056492016-07-22 09:45:56 -07003215 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003216 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)
3239 r = client.promote(pipeline='gate',
3240 change_ids=['3,1'])
3241
James E. Blair78acec92014-02-06 07:11:32 -08003242 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003243 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003244 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003245 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003246 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003247 self.launch_server.release('.*-merge')
James E. Blair36658cf2013-12-06 17:53:48 -08003248 self.waitUntilSettled()
3249
3250 self.assertEqual(len(self.builds), 6)
3251 self.assertEqual(self.builds[0].name, 'project-test1')
3252 self.assertEqual(self.builds[1].name, 'project-test2')
3253 self.assertEqual(self.builds[2].name, 'project-test1')
3254 self.assertEqual(self.builds[3].name, 'project-test2')
3255 self.assertEqual(self.builds[4].name, 'project-test1')
3256 self.assertEqual(self.builds[5].name, 'project-test2')
3257
3258 self.assertTrue(self.job_has_changes(self.builds[0], B))
3259 self.assertFalse(self.job_has_changes(self.builds[0], A))
3260 self.assertFalse(self.job_has_changes(self.builds[0], C))
3261
3262 self.assertTrue(self.job_has_changes(self.builds[2], B))
3263 self.assertTrue(self.job_has_changes(self.builds[2], C))
3264 self.assertFalse(self.job_has_changes(self.builds[2], A))
3265
3266 self.assertTrue(self.job_has_changes(self.builds[4], B))
3267 self.assertTrue(self.job_has_changes(self.builds[4], C))
3268 self.assertTrue(self.job_has_changes(self.builds[4], A))
3269
James E. Blair08d19992016-08-10 15:25:31 -07003270 self.launch_server.release()
James E. Blair36658cf2013-12-06 17:53:48 -08003271 self.waitUntilSettled()
3272
3273 self.assertEqual(A.data['status'], 'MERGED')
3274 self.assertEqual(A.reported, 2)
3275 self.assertEqual(B.data['status'], 'MERGED')
3276 self.assertEqual(B.reported, 2)
3277 self.assertEqual(C.data['status'], 'MERGED')
3278 self.assertEqual(C.reported, 2)
3279
3280 client.shutdown()
3281 self.assertEqual(r, True)
3282
James E. Blairec056492016-07-22 09:45:56 -07003283 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003284 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):
3296 r = client.promote(pipeline='nonexistent',
3297 change_ids=['2,1', '3,1'])
3298 client.shutdown()
3299 self.assertEqual(r, False)
3300
3301 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
3302 r = client.promote(pipeline='gate',
3303 change_ids=['4,1'])
3304 client.shutdown()
3305 self.assertEqual(r, False)
3306
James E. Blair08d19992016-08-10 15:25:31 -07003307 self.launch_server.hold_jobs_in_build = False
3308 self.launch_server.release()
James E. Blair36658cf2013-12-06 17:53:48 -08003309 self.waitUntilSettled()
Clark Boylan7603a372014-01-21 11:43:20 -08003310
James E. Blairec056492016-07-22 09:45:56 -07003311 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003312 def test_queue_rate_limiting(self):
3313 "Test that DependentPipelines are rate limited with dep across window"
James E. Blairf84026c2015-12-08 16:11:46 -08003314 self.updateConfigLayout(
3315 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003316 self.sched.reconfigure(self.config)
James E. Blair08d19992016-08-10 15:25:31 -07003317 self.launch_server.hold_jobs_in_build = True
Clark Boylan7603a372014-01-21 11:43:20 -08003318 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3319 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3320 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3321
3322 C.setDependsOn(B, 1)
James E. Blair08d19992016-08-10 15:25:31 -07003323 self.launch_server.failJob('project-test1', A)
Clark Boylan7603a372014-01-21 11:43:20 -08003324
James E. Blair8b5408c2016-08-08 15:37:46 -07003325 A.addApproval('code-review', 2)
3326 B.addApproval('code-review', 2)
3327 C.addApproval('code-review', 2)
Clark Boylan7603a372014-01-21 11:43:20 -08003328
James E. Blair8b5408c2016-08-08 15:37:46 -07003329 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
3330 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
3331 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
Clark Boylan7603a372014-01-21 11:43:20 -08003332 self.waitUntilSettled()
3333
3334 # Only A and B will have their merge jobs queued because
3335 # window is 2.
3336 self.assertEqual(len(self.builds), 2)
3337 self.assertEqual(self.builds[0].name, 'project-merge')
3338 self.assertEqual(self.builds[1].name, 'project-merge')
3339
James E. Blair08d19992016-08-10 15:25:31 -07003340 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003341 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003342 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003343 self.waitUntilSettled()
3344
3345 # Only A and B will have their test jobs queued because
3346 # window is 2.
3347 self.assertEqual(len(self.builds), 4)
3348 self.assertEqual(self.builds[0].name, 'project-test1')
3349 self.assertEqual(self.builds[1].name, 'project-test2')
3350 self.assertEqual(self.builds[2].name, 'project-test1')
3351 self.assertEqual(self.builds[3].name, 'project-test2')
3352
James E. Blair08d19992016-08-10 15:25:31 -07003353 self.launch_server.release('project-.*')
Clark Boylan7603a372014-01-21 11:43:20 -08003354 self.waitUntilSettled()
3355
3356 queue = self.sched.layout.pipelines['gate'].queues[0]
3357 # A failed so window is reduced by 1 to 1.
3358 self.assertEqual(queue.window, 1)
3359 self.assertEqual(queue.window_floor, 1)
3360 self.assertEqual(A.data['status'], 'NEW')
3361
3362 # Gate is reset and only B's merge job is queued because
3363 # window shrunk to 1.
3364 self.assertEqual(len(self.builds), 1)
3365 self.assertEqual(self.builds[0].name, 'project-merge')
3366
James E. Blair08d19992016-08-10 15:25:31 -07003367 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003368 self.waitUntilSettled()
3369
3370 # Only B's test jobs are queued because window is still 1.
3371 self.assertEqual(len(self.builds), 2)
3372 self.assertEqual(self.builds[0].name, 'project-test1')
3373 self.assertEqual(self.builds[1].name, 'project-test2')
3374
James E. Blair08d19992016-08-10 15:25:31 -07003375 self.launch_server.release('project-.*')
Clark Boylan7603a372014-01-21 11:43:20 -08003376 self.waitUntilSettled()
3377
3378 # B was successfully merged so window is increased to 2.
3379 self.assertEqual(queue.window, 2)
3380 self.assertEqual(queue.window_floor, 1)
3381 self.assertEqual(B.data['status'], 'MERGED')
3382
3383 # Only C is left and its merge job is queued.
3384 self.assertEqual(len(self.builds), 1)
3385 self.assertEqual(self.builds[0].name, 'project-merge')
3386
James E. Blair08d19992016-08-10 15:25:31 -07003387 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003388 self.waitUntilSettled()
3389
3390 # After successful merge job the test jobs for C are queued.
3391 self.assertEqual(len(self.builds), 2)
3392 self.assertEqual(self.builds[0].name, 'project-test1')
3393 self.assertEqual(self.builds[1].name, 'project-test2')
3394
James E. Blair08d19992016-08-10 15:25:31 -07003395 self.launch_server.release('project-.*')
Clark Boylan7603a372014-01-21 11:43:20 -08003396 self.waitUntilSettled()
3397
3398 # C successfully merged so window is bumped to 3.
3399 self.assertEqual(queue.window, 3)
3400 self.assertEqual(queue.window_floor, 1)
3401 self.assertEqual(C.data['status'], 'MERGED')
3402
James E. Blairec056492016-07-22 09:45:56 -07003403 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003404 def test_queue_rate_limiting_dependent(self):
3405 "Test that DependentPipelines are rate limited with dep in window"
James E. Blairf84026c2015-12-08 16:11:46 -08003406 self.updateConfigLayout(
3407 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003408 self.sched.reconfigure(self.config)
James E. Blair08d19992016-08-10 15:25:31 -07003409 self.launch_server.hold_jobs_in_build = True
Clark Boylan7603a372014-01-21 11:43:20 -08003410 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3411 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3412 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3413
3414 B.setDependsOn(A, 1)
3415
James E. Blair08d19992016-08-10 15:25:31 -07003416 self.launch_server.failJob('project-test1', A)
Clark Boylan7603a372014-01-21 11:43:20 -08003417
James E. Blair8b5408c2016-08-08 15:37:46 -07003418 A.addApproval('code-review', 2)
3419 B.addApproval('code-review', 2)
3420 C.addApproval('code-review', 2)
Clark Boylan7603a372014-01-21 11:43:20 -08003421
James E. Blair8b5408c2016-08-08 15:37:46 -07003422 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
3423 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
3424 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
Clark Boylan7603a372014-01-21 11:43:20 -08003425 self.waitUntilSettled()
3426
3427 # Only A and B will have their merge jobs queued because
3428 # window is 2.
3429 self.assertEqual(len(self.builds), 2)
3430 self.assertEqual(self.builds[0].name, 'project-merge')
3431 self.assertEqual(self.builds[1].name, 'project-merge')
3432
James E. Blair08d19992016-08-10 15:25:31 -07003433 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003434 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003435 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003436 self.waitUntilSettled()
3437
3438 # Only A and B will have their test jobs queued because
3439 # window is 2.
3440 self.assertEqual(len(self.builds), 4)
3441 self.assertEqual(self.builds[0].name, 'project-test1')
3442 self.assertEqual(self.builds[1].name, 'project-test2')
3443 self.assertEqual(self.builds[2].name, 'project-test1')
3444 self.assertEqual(self.builds[3].name, 'project-test2')
3445
James E. Blair08d19992016-08-10 15:25:31 -07003446 self.launch_server.release('project-.*')
Clark Boylan7603a372014-01-21 11:43:20 -08003447 self.waitUntilSettled()
3448
3449 queue = self.sched.layout.pipelines['gate'].queues[0]
3450 # A failed so window is reduced by 1 to 1.
3451 self.assertEqual(queue.window, 1)
3452 self.assertEqual(queue.window_floor, 1)
3453 self.assertEqual(A.data['status'], 'NEW')
3454 self.assertEqual(B.data['status'], 'NEW')
3455
3456 # Gate is reset and only C's merge job is queued because
3457 # window shrunk to 1 and A and B were dequeued.
3458 self.assertEqual(len(self.builds), 1)
3459 self.assertEqual(self.builds[0].name, 'project-merge')
3460
James E. Blair08d19992016-08-10 15:25:31 -07003461 self.launch_server.release('.*-merge')
Clark Boylan7603a372014-01-21 11:43:20 -08003462 self.waitUntilSettled()
3463
3464 # Only C's test jobs are queued because window is still 1.
3465 self.assertEqual(len(self.builds), 2)
3466 self.assertEqual(self.builds[0].name, 'project-test1')
3467 self.assertEqual(self.builds[1].name, 'project-test2')
3468
James E. Blair08d19992016-08-10 15:25:31 -07003469 self.launch_server.release('project-.*')
Clark Boylan7603a372014-01-21 11:43:20 -08003470 self.waitUntilSettled()
3471
3472 # C was successfully merged so window is increased to 2.
3473 self.assertEqual(queue.window, 2)
3474 self.assertEqual(queue.window_floor, 1)
3475 self.assertEqual(C.data['status'], 'MERGED')
Joshua Heskethba8776a2014-01-12 14:35:40 +08003476
James E. Blairec056492016-07-22 09:45:56 -07003477 @skip("Disabled for early v3 development")
Joshua Heskethba8776a2014-01-12 14:35:40 +08003478 def test_worker_update_metadata(self):
3479 "Test if a worker can send back metadata about itself"
James E. Blair08d19992016-08-10 15:25:31 -07003480 self.launch_server.hold_jobs_in_build = True
Joshua Heskethba8776a2014-01-12 14:35:40 +08003481
3482 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07003483 A.addApproval('code-review', 2)
3484 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Heskethba8776a2014-01-12 14:35:40 +08003485 self.waitUntilSettled()
3486
3487 self.assertEqual(len(self.launcher.builds), 1)
3488
3489 self.log.debug('Current builds:')
3490 self.log.debug(self.launcher.builds)
3491
3492 start = time.time()
3493 while True:
3494 if time.time() - start > 10:
3495 raise Exception("Timeout waiting for gearman server to report "
3496 + "back to the client")
3497 build = self.launcher.builds.values()[0]
3498 if build.worker.name == "My Worker":
3499 break
3500 else:
3501 time.sleep(0)
3502
3503 self.log.debug(build)
3504 self.assertEqual("My Worker", build.worker.name)
3505 self.assertEqual("localhost", build.worker.hostname)
3506 self.assertEqual(['127.0.0.1', '192.168.1.1'], build.worker.ips)
3507 self.assertEqual("zuul.example.org", build.worker.fqdn)
3508 self.assertEqual("FakeBuilder", build.worker.program)
3509 self.assertEqual("v1.1", build.worker.version)
3510 self.assertEqual({'something': 'else'}, build.worker.extra)
3511
James E. Blair08d19992016-08-10 15:25:31 -07003512 self.launch_server.hold_jobs_in_build = False
3513 self.launch_server.release()
Joshua Heskethba8776a2014-01-12 14:35:40 +08003514 self.waitUntilSettled()
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003515
James E. Blairec056492016-07-22 09:45:56 -07003516 @skip("Disabled for early v3 development")
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003517 def test_footer_message(self):
3518 "Test a pipeline's footer message is correctly added to the report."
James E. Blairf84026c2015-12-08 16:11:46 -08003519 self.updateConfigLayout(
3520 'tests/fixtures/layout-footer-message.yaml')
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003521 self.sched.reconfigure(self.config)
3522 self.registerJobs()
3523
3524 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07003525 A.addApproval('code-review', 2)
James E. Blair08d19992016-08-10 15:25:31 -07003526 self.launch_server.failJob('test1', A)
James E. Blair8b5408c2016-08-08 15:37:46 -07003527 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003528 self.waitUntilSettled()
3529
3530 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07003531 B.addApproval('code-review', 2)
3532 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003533 self.waitUntilSettled()
3534
3535 self.assertEqual(2, len(self.smtp_messages))
3536
3537 failure_body = """\
3538Build failed. For information on how to proceed, see \
3539http://wiki.example.org/Test_Failures
3540
3541- test1 http://logs.example.com/1/1/gate/test1/0 : FAILURE in 0s
3542- test2 http://logs.example.com/1/1/gate/test2/1 : SUCCESS in 0s
3543
3544For CI problems and help debugging, contact ci@example.org"""
3545
3546 success_body = """\
3547Build succeeded.
3548
3549- test1 http://logs.example.com/2/1/gate/test1/2 : SUCCESS in 0s
3550- test2 http://logs.example.com/2/1/gate/test2/3 : SUCCESS in 0s
3551
3552For CI problems and help debugging, contact ci@example.org"""
3553
3554 self.assertEqual(failure_body, self.smtp_messages[0]['body'])
3555 self.assertEqual(success_body, self.smtp_messages[1]['body'])
Joshua Heskethb7179772014-01-30 23:30:46 +11003556
James E. Blairec056492016-07-22 09:45:56 -07003557 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003558 def test_merge_failure_reporters(self):
3559 """Check that the config is set up correctly"""
3560
James E. Blairf84026c2015-12-08 16:11:46 -08003561 self.updateConfigLayout(
3562 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003563 self.sched.reconfigure(self.config)
3564 self.registerJobs()
3565
3566 self.assertEqual(
Jeremy Stanley1c2c3c22015-06-15 21:23:19 +00003567 "Merge Failed.\n\nThis change or one of its cross-repo "
3568 "dependencies was unable to be automatically merged with the "
3569 "current state of its repository. Please rebase the change and "
3570 "upload a new patchset.",
Joshua Heskethb7179772014-01-30 23:30:46 +11003571 self.sched.layout.pipelines['check'].merge_failure_message)
3572 self.assertEqual(
3573 "The merge failed! For more information...",
3574 self.sched.layout.pipelines['gate'].merge_failure_message)
3575
3576 self.assertEqual(
3577 len(self.sched.layout.pipelines['check'].merge_failure_actions), 1)
3578 self.assertEqual(
3579 len(self.sched.layout.pipelines['gate'].merge_failure_actions), 2)
3580
3581 self.assertTrue(isinstance(
Joshua Heskethde958652015-11-10 19:19:50 +11003582 self.sched.layout.pipelines['check'].merge_failure_actions[0],
3583 zuul.reporter.gerrit.GerritReporter))
Joshua Heskethb7179772014-01-30 23:30:46 +11003584
3585 self.assertTrue(
3586 (
3587 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003588 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003589 zuul.reporter.smtp.SMTPReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003590 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003591 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003592 zuul.reporter.gerrit.GerritReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003593 ) or (
3594 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003595 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003596 zuul.reporter.gerrit.GerritReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003597 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003598 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003599 zuul.reporter.smtp.SMTPReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003600 )
3601 )
3602
James E. Blairec056492016-07-22 09:45:56 -07003603 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003604 def test_merge_failure_reports(self):
3605 """Check that when a change fails to merge the correct message is sent
3606 to the correct reporter"""
James E. Blairf84026c2015-12-08 16:11:46 -08003607 self.updateConfigLayout(
3608 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003609 self.sched.reconfigure(self.config)
3610 self.registerJobs()
3611
3612 # Check a test failure isn't reported to SMTP
3613 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07003614 A.addApproval('code-review', 2)
James E. Blair08d19992016-08-10 15:25:31 -07003615 self.launch_server.failJob('project-test1', A)
James E. Blair8b5408c2016-08-08 15:37:46 -07003616 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Heskethb7179772014-01-30 23:30:46 +11003617 self.waitUntilSettled()
3618
3619 self.assertEqual(3, len(self.history)) # 3 jobs
3620 self.assertEqual(0, len(self.smtp_messages))
3621
3622 # Check a merge failure is reported to SMTP
3623 # B should be merged, but C will conflict with B
3624 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3625 B.addPatchset(['conflict'])
3626 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3627 C.addPatchset(['conflict'])
James E. Blair8b5408c2016-08-08 15:37:46 -07003628 B.addApproval('code-review', 2)
3629 C.addApproval('code-review', 2)
3630 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
3631 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
Joshua Heskethb7179772014-01-30 23:30:46 +11003632 self.waitUntilSettled()
3633
3634 self.assertEqual(6, len(self.history)) # A and B jobs
3635 self.assertEqual(1, len(self.smtp_messages))
3636 self.assertEqual('The merge failed! For more information...',
3637 self.smtp_messages[0]['body'])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003638
James E. Blairec056492016-07-22 09:45:56 -07003639 @skip("Disabled for early v3 development")
James E. Blairf760f0e2016-02-09 08:44:52 -08003640 def test_default_merge_failure_reports(self):
3641 """Check that the default merge failure reports are correct."""
3642
3643 # A should report success, B should report merge failure.
3644 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3645 A.addPatchset(['conflict'])
3646 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3647 B.addPatchset(['conflict'])
James E. Blair8b5408c2016-08-08 15:37:46 -07003648 A.addApproval('code-review', 2)
3649 B.addApproval('code-review', 2)
3650 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
3651 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blairf760f0e2016-02-09 08:44:52 -08003652 self.waitUntilSettled()
3653
3654 self.assertEqual(3, len(self.history)) # A jobs
3655 self.assertEqual(A.reported, 2)
3656 self.assertEqual(B.reported, 2)
3657 self.assertEqual(A.data['status'], 'MERGED')
3658 self.assertEqual(B.data['status'], 'NEW')
3659 self.assertIn('Build succeeded', A.messages[1])
3660 self.assertIn('Merge Failed', B.messages[1])
3661 self.assertIn('automatically merged', B.messages[1])
3662 self.assertNotIn('logs.example.com', B.messages[1])
3663 self.assertNotIn('SKIPPED', B.messages[1])
3664
James E. Blairec056492016-07-22 09:45:56 -07003665 @skip("Disabled for early v3 development")
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003666 def test_swift_instructions(self):
3667 "Test that the correct swift instructions are sent to the workers"
James E. Blairf84026c2015-12-08 16:11:46 -08003668 self.updateConfigLayout(
3669 'tests/fixtures/layout-swift.yaml')
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003670 self.sched.reconfigure(self.config)
3671 self.registerJobs()
3672
James E. Blair08d19992016-08-10 15:25:31 -07003673 self.launch_server.hold_jobs_in_build = True
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003674 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3675
James E. Blair8b5408c2016-08-08 15:37:46 -07003676 A.addApproval('code-review', 2)
3677 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003678 self.waitUntilSettled()
3679
3680 self.assertEqual(
3681 "https://storage.example.org/V1/AUTH_account/merge_logs/1/1/1/"
3682 "gate/test-merge/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003683 self.builds[0].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003684 self.assertEqual(5,
3685 len(self.builds[0].parameters['SWIFT_logs_HMAC_BODY'].
3686 split('\n')))
3687 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[0].parameters)
3688
3689 self.assertEqual(
3690 "https://storage.example.org/V1/AUTH_account/logs/1/1/1/"
3691 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003692 self.builds[1].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003693 self.assertEqual(5,
3694 len(self.builds[1].parameters['SWIFT_logs_HMAC_BODY'].
3695 split('\n')))
3696 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[1].parameters)
3697
3698 self.assertEqual(
3699 "https://storage.example.org/V1/AUTH_account/stash/1/1/1/"
3700 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003701 self.builds[1].parameters['SWIFT_MOSTLY_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003702 self.assertEqual(5,
3703 len(self.builds[1].
3704 parameters['SWIFT_MOSTLY_HMAC_BODY'].split('\n')))
3705 self.assertIn('SWIFT_MOSTLY_SIGNATURE', self.builds[1].parameters)
3706
James E. Blair08d19992016-08-10 15:25:31 -07003707 self.launch_server.hold_jobs_in_build = False
3708 self.launch_server.release()
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003709 self.waitUntilSettled()
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003710
James E. Blairec056492016-07-22 09:45:56 -07003711 @skip("Disabled for early v3 development")
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003712 def test_client_get_running_jobs(self):
3713 "Test that the RPC client can get a list of running jobs"
James E. Blair08d19992016-08-10 15:25:31 -07003714 self.launch_server.hold_jobs_in_build = True
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003715 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -07003716 A.addApproval('code-review', 2)
3717 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003718 self.waitUntilSettled()
3719
3720 client = zuul.rpcclient.RPCClient('127.0.0.1',
3721 self.gearman_server.port)
3722
3723 # Wait for gearman server to send the initial workData back to zuul
3724 start = time.time()
3725 while True:
3726 if time.time() - start > 10:
3727 raise Exception("Timeout waiting for gearman server to report "
3728 + "back to the client")
3729 build = self.launcher.builds.values()[0]
3730 if build.worker.name == "My Worker":
3731 break
3732 else:
3733 time.sleep(0)
3734
3735 running_items = client.get_running_jobs()
3736
3737 self.assertEqual(1, len(running_items))
3738 running_item = running_items[0]
3739 self.assertEqual([], running_item['failing_reasons'])
3740 self.assertEqual([], running_item['items_behind'])
3741 self.assertEqual('https://hostname/1', running_item['url'])
3742 self.assertEqual(None, running_item['item_ahead'])
3743 self.assertEqual('org/project', running_item['project'])
3744 self.assertEqual(None, running_item['remaining_time'])
3745 self.assertEqual(True, running_item['active'])
3746 self.assertEqual('1,1', running_item['id'])
3747
3748 self.assertEqual(3, len(running_item['jobs']))
3749 for job in running_item['jobs']:
3750 if job['name'] == 'project-merge':
3751 self.assertEqual('project-merge', job['name'])
3752 self.assertEqual('gate', job['pipeline'])
3753 self.assertEqual(False, job['retry'])
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003754 self.assertEqual('https://server/job/project-merge/0/',
3755 job['url'])
3756 self.assertEqual(7, len(job['worker']))
3757 self.assertEqual(False, job['canceled'])
3758 self.assertEqual(True, job['voting'])
3759 self.assertEqual(None, job['result'])
3760 self.assertEqual('gate', job['pipeline'])
3761 break
3762
James E. Blair08d19992016-08-10 15:25:31 -07003763 self.launch_server.hold_jobs_in_build = False
3764 self.launch_server.release()
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003765 self.waitUntilSettled()
3766
3767 running_items = client.get_running_jobs()
3768 self.assertEqual(0, len(running_items))
James E. Blairbadc1ad2014-04-28 13:55:14 -07003769
3770 def test_nonvoting_pipeline(self):
3771 "Test that a nonvoting pipeline (experimental) can still report"
3772
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003773 A = self.fake_gerrit.addFakeChange('org/experimental-project',
3774 'master', 'A')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003775 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
3776 self.waitUntilSettled()
Paul Belanger15e3e202016-10-14 16:27:34 -04003777
3778 self.assertEqual(self.getJobFromHistory('project-merge').result,
3779 'SUCCESS')
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003780 self.assertEqual(
3781 self.getJobFromHistory('experimental-project-test').result,
3782 'SUCCESS')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003783 self.assertEqual(A.reported, 1)
James E. Blair5ee24252014-12-30 10:12:29 -08003784
3785 def test_crd_gate(self):
3786 "Test cross-repo dependencies"
3787 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3788 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07003789 A.addApproval('code-review', 2)
3790 B.addApproval('code-review', 2)
James E. Blair5ee24252014-12-30 10:12:29 -08003791
3792 AM2 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM2')
3793 AM1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM1')
3794 AM2.setMerged()
3795 AM1.setMerged()
3796
3797 BM2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM2')
3798 BM1 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM1')
3799 BM2.setMerged()
3800 BM1.setMerged()
3801
3802 # A -> AM1 -> AM2
3803 # B -> BM1 -> BM2
3804 # A Depends-On: B
3805 # M2 is here to make sure it is never queried. If it is, it
3806 # means zuul is walking down the entire history of merged
3807 # changes.
3808
3809 B.setDependsOn(BM1, 1)
3810 BM1.setDependsOn(BM2, 1)
3811
3812 A.setDependsOn(AM1, 1)
3813 AM1.setDependsOn(AM2, 1)
3814
3815 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3816 A.subject, B.data['id'])
3817
James E. Blair8b5408c2016-08-08 15:37:46 -07003818 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08003819 self.waitUntilSettled()
3820
3821 self.assertEqual(A.data['status'], 'NEW')
3822 self.assertEqual(B.data['status'], 'NEW')
3823
Paul Belanger5dccbe72016-11-14 11:17:37 -05003824 for connection in self.connections.connections.values():
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11003825 connection.maintainCache([])
James E. Blair5ee24252014-12-30 10:12:29 -08003826
James E. Blair08d19992016-08-10 15:25:31 -07003827 self.launch_server.hold_jobs_in_build = True
James E. Blair8b5408c2016-08-08 15:37:46 -07003828 B.addApproval('approved', 1)
3829 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08003830 self.waitUntilSettled()
3831
James E. Blair08d19992016-08-10 15:25:31 -07003832 self.launch_server.release('.*-merge')
James E. Blair5ee24252014-12-30 10:12:29 -08003833 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003834 self.launch_server.release('.*-merge')
James E. Blair5ee24252014-12-30 10:12:29 -08003835 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003836 self.launch_server.hold_jobs_in_build = False
3837 self.launch_server.release()
James E. Blair5ee24252014-12-30 10:12:29 -08003838 self.waitUntilSettled()
3839
3840 self.assertEqual(AM2.queried, 0)
3841 self.assertEqual(BM2.queried, 0)
3842 self.assertEqual(A.data['status'], 'MERGED')
3843 self.assertEqual(B.data['status'], 'MERGED')
3844 self.assertEqual(A.reported, 2)
3845 self.assertEqual(B.reported, 2)
3846
Paul Belanger5dccbe72016-11-14 11:17:37 -05003847 changes = self.getJobFromHistory(
3848 'project-merge', 'org/project1').changes
3849 self.assertEqual(changes, '2,1 1,1')
James E. Blair8f78d882015-02-05 08:51:37 -08003850
3851 def test_crd_branch(self):
3852 "Test cross-repo dependencies in multiple branches"
Paul Belanger6379db12016-11-14 13:57:54 -05003853
3854 self.create_branch('org/project2', 'mp')
James E. Blair8f78d882015-02-05 08:51:37 -08003855 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3856 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3857 C = self.fake_gerrit.addFakeChange('org/project2', 'mp', 'C')
3858 C.data['id'] = B.data['id']
James E. Blair8b5408c2016-08-08 15:37:46 -07003859 A.addApproval('code-review', 2)
3860 B.addApproval('code-review', 2)
3861 C.addApproval('code-review', 2)
James E. Blair8f78d882015-02-05 08:51:37 -08003862
3863 # A Depends-On: B+C
3864 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3865 A.subject, B.data['id'])
3866
James E. Blair08d19992016-08-10 15:25:31 -07003867 self.launch_server.hold_jobs_in_build = True
James E. Blair8b5408c2016-08-08 15:37:46 -07003868 B.addApproval('approved', 1)
3869 C.addApproval('approved', 1)
3870 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair8f78d882015-02-05 08:51:37 -08003871 self.waitUntilSettled()
3872
James E. Blair08d19992016-08-10 15:25:31 -07003873 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003874 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003875 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003876 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003877 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003878 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003879 self.launch_server.hold_jobs_in_build = False
3880 self.launch_server.release()
James E. Blair8f78d882015-02-05 08:51:37 -08003881 self.waitUntilSettled()
3882
3883 self.assertEqual(A.data['status'], 'MERGED')
3884 self.assertEqual(B.data['status'], 'MERGED')
3885 self.assertEqual(C.data['status'], 'MERGED')
3886 self.assertEqual(A.reported, 2)
3887 self.assertEqual(B.reported, 2)
3888 self.assertEqual(C.reported, 2)
3889
Paul Belanger6379db12016-11-14 13:57:54 -05003890 changes = self.getJobFromHistory(
3891 'project-merge', 'org/project1').changes
3892 self.assertEqual(changes, '2,1 3,1 1,1')
James E. Blair8f78d882015-02-05 08:51:37 -08003893
3894 def test_crd_multiline(self):
3895 "Test multiple depends-on lines in commit"
3896 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3897 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3898 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
James E. Blair8b5408c2016-08-08 15:37:46 -07003899 A.addApproval('code-review', 2)
3900 B.addApproval('code-review', 2)
3901 C.addApproval('code-review', 2)
James E. Blair8f78d882015-02-05 08:51:37 -08003902
3903 # A Depends-On: B+C
3904 A.data['commitMessage'] = '%s\n\nDepends-On: %s\nDepends-On: %s\n' % (
3905 A.subject, B.data['id'], C.data['id'])
3906
James E. Blair08d19992016-08-10 15:25:31 -07003907 self.launch_server.hold_jobs_in_build = True
James E. Blair8b5408c2016-08-08 15:37:46 -07003908 B.addApproval('approved', 1)
3909 C.addApproval('approved', 1)
3910 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair8f78d882015-02-05 08:51:37 -08003911 self.waitUntilSettled()
3912
James E. Blair08d19992016-08-10 15:25:31 -07003913 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003914 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003915 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003916 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003917 self.launch_server.release('.*-merge')
James E. Blair8f78d882015-02-05 08:51:37 -08003918 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003919 self.launch_server.hold_jobs_in_build = False
3920 self.launch_server.release()
James E. Blair8f78d882015-02-05 08:51:37 -08003921 self.waitUntilSettled()
3922
3923 self.assertEqual(A.data['status'], 'MERGED')
3924 self.assertEqual(B.data['status'], 'MERGED')
3925 self.assertEqual(C.data['status'], 'MERGED')
3926 self.assertEqual(A.reported, 2)
3927 self.assertEqual(B.reported, 2)
3928 self.assertEqual(C.reported, 2)
3929
Paul Belanger5dccbe72016-11-14 11:17:37 -05003930 changes = self.getJobFromHistory(
3931 'project-merge', 'org/project1').changes
3932 self.assertEqual(changes, '2,1 3,1 1,1')
James E. Blair5ee24252014-12-30 10:12:29 -08003933
3934 def test_crd_unshared_gate(self):
3935 "Test cross-repo dependencies in unshared gate queues"
3936 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3937 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07003938 A.addApproval('code-review', 2)
3939 B.addApproval('code-review', 2)
James E. Blair5ee24252014-12-30 10:12:29 -08003940
3941 # A Depends-On: B
3942 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3943 A.subject, B.data['id'])
3944
3945 # A and B do not share a queue, make sure that A is unable to
3946 # enqueue B (and therefore, A is unable to be enqueued).
James E. Blair8b5408c2016-08-08 15:37:46 -07003947 B.addApproval('approved', 1)
3948 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08003949 self.waitUntilSettled()
3950
3951 self.assertEqual(A.data['status'], 'NEW')
3952 self.assertEqual(B.data['status'], 'NEW')
3953 self.assertEqual(A.reported, 0)
3954 self.assertEqual(B.reported, 0)
3955 self.assertEqual(len(self.history), 0)
3956
3957 # Enqueue and merge B alone.
James E. Blair8b5408c2016-08-08 15:37:46 -07003958 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08003959 self.waitUntilSettled()
3960
3961 self.assertEqual(B.data['status'], 'MERGED')
3962 self.assertEqual(B.reported, 2)
3963
3964 # Now that B is merged, A should be able to be enqueued and
3965 # merged.
James E. Blair8b5408c2016-08-08 15:37:46 -07003966 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08003967 self.waitUntilSettled()
3968
3969 self.assertEqual(A.data['status'], 'MERGED')
3970 self.assertEqual(A.reported, 2)
3971
James E. Blair96698e22015-04-02 07:48:21 -07003972 def test_crd_gate_reverse(self):
3973 "Test reverse cross-repo dependencies"
3974 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3975 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07003976 A.addApproval('code-review', 2)
3977 B.addApproval('code-review', 2)
James E. Blair96698e22015-04-02 07:48:21 -07003978
3979 # A Depends-On: B
3980
3981 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3982 A.subject, B.data['id'])
3983
James E. Blair8b5408c2016-08-08 15:37:46 -07003984 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair96698e22015-04-02 07:48:21 -07003985 self.waitUntilSettled()
3986
3987 self.assertEqual(A.data['status'], 'NEW')
3988 self.assertEqual(B.data['status'], 'NEW')
3989
James E. Blair08d19992016-08-10 15:25:31 -07003990 self.launch_server.hold_jobs_in_build = True
James E. Blair8b5408c2016-08-08 15:37:46 -07003991 A.addApproval('approved', 1)
3992 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair96698e22015-04-02 07:48:21 -07003993 self.waitUntilSettled()
3994
James E. Blair08d19992016-08-10 15:25:31 -07003995 self.launch_server.release('.*-merge')
James E. Blair96698e22015-04-02 07:48:21 -07003996 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003997 self.launch_server.release('.*-merge')
James E. Blair96698e22015-04-02 07:48:21 -07003998 self.waitUntilSettled()
James E. Blair08d19992016-08-10 15:25:31 -07003999 self.launch_server.hold_jobs_in_build = False
4000 self.launch_server.release()
James E. Blair96698e22015-04-02 07:48:21 -07004001 self.waitUntilSettled()
4002
4003 self.assertEqual(A.data['status'], 'MERGED')
4004 self.assertEqual(B.data['status'], 'MERGED')
4005 self.assertEqual(A.reported, 2)
4006 self.assertEqual(B.reported, 2)
4007
Paul Belanger5dccbe72016-11-14 11:17:37 -05004008 changes = self.getJobFromHistory(
4009 'project-merge', 'org/project1').changes
4010 self.assertEqual(changes, '2,1 1,1')
James E. Blair96698e22015-04-02 07:48:21 -07004011
James E. Blair5ee24252014-12-30 10:12:29 -08004012 def test_crd_cycle(self):
4013 "Test cross-repo dependency cycles"
4014 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4015 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07004016 A.addApproval('code-review', 2)
4017 B.addApproval('code-review', 2)
James E. Blair5ee24252014-12-30 10:12:29 -08004018
4019 # A -> B -> A (via commit-depends)
4020
4021 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4022 A.subject, B.data['id'])
4023 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4024 B.subject, A.data['id'])
4025
James E. Blair8b5408c2016-08-08 15:37:46 -07004026 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair5ee24252014-12-30 10:12:29 -08004027 self.waitUntilSettled()
4028
4029 self.assertEqual(A.reported, 0)
4030 self.assertEqual(B.reported, 0)
4031 self.assertEqual(A.data['status'], 'NEW')
4032 self.assertEqual(B.data['status'], 'NEW')
James E. Blairbfb8e042014-12-30 17:01:44 -08004033
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004034 def test_crd_gate_unknown(self):
4035 "Test unknown projects in dependent pipeline"
4036 self.init_repo("org/unknown")
4037 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4038 B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -07004039 A.addApproval('code-review', 2)
4040 B.addApproval('code-review', 2)
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004041
4042 # A Depends-On: B
4043 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4044 A.subject, B.data['id'])
4045
James E. Blair8b5408c2016-08-08 15:37:46 -07004046 B.addApproval('approved', 1)
4047 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004048 self.waitUntilSettled()
4049
4050 # Unknown projects cannot share a queue with any other
4051 # since they don't have common jobs with any other (they have no jobs).
4052 # Changes which depend on unknown project changes
4053 # should not be processed in dependent pipeline
4054 self.assertEqual(A.data['status'], 'NEW')
4055 self.assertEqual(B.data['status'], 'NEW')
4056 self.assertEqual(A.reported, 0)
4057 self.assertEqual(B.reported, 0)
4058 self.assertEqual(len(self.history), 0)
4059
4060 # Simulate change B being gated outside this layout
James E. Blair8b5408c2016-08-08 15:37:46 -07004061 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004062 B.setMerged()
4063 self.waitUntilSettled()
4064 self.assertEqual(len(self.history), 0)
4065
4066 # Now that B is merged, A should be able to be enqueued and
4067 # merged.
James E. Blair8b5408c2016-08-08 15:37:46 -07004068 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004069 self.waitUntilSettled()
4070
4071 self.assertEqual(A.data['status'], 'MERGED')
4072 self.assertEqual(A.reported, 2)
4073 self.assertEqual(B.data['status'], 'MERGED')
4074 self.assertEqual(B.reported, 0)
4075
James E. Blairbfb8e042014-12-30 17:01:44 -08004076 def test_crd_check(self):
4077 "Test cross-repo dependencies in independent pipelines"
4078
Paul Belangerb30342b2016-11-14 12:30:43 -05004079 self.launch_server.hold_jobs_in_build = True
James E. Blairbfb8e042014-12-30 17:01:44 -08004080 self.gearman_server.hold_jobs_in_queue = True
4081 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4082 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4083
4084 # A Depends-On: B
4085 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4086 A.subject, B.data['id'])
4087
4088 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4089 self.waitUntilSettled()
4090
4091 queue = self.gearman_server.getQueue()
4092 ref = self.getParameter(queue[-1], 'ZUUL_REF')
4093 self.gearman_server.hold_jobs_in_queue = False
4094 self.gearman_server.release()
4095 self.waitUntilSettled()
4096
Paul Belangerb30342b2016-11-14 12:30:43 -05004097 self.launch_server.release('.*-merge')
4098 self.waitUntilSettled()
4099
4100 path = os.path.join(self.builds[0].jobdir.git_root, "org/project1")
James E. Blairbfb8e042014-12-30 17:01:44 -08004101 repo = git.Repo(path)
4102 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4103 repo_messages.reverse()
Paul Belangerb30342b2016-11-14 12:30:43 -05004104 correct_messages = [
4105 'initial commit', 'add content from fixture', 'A-1']
James E. Blairbfb8e042014-12-30 17:01:44 -08004106 self.assertEqual(repo_messages, correct_messages)
4107
Paul Belangerb30342b2016-11-14 12:30:43 -05004108 path = os.path.join(self.builds[0].jobdir.git_root, "org/project2")
James E. Blairbfb8e042014-12-30 17:01:44 -08004109 repo = git.Repo(path)
4110 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4111 repo_messages.reverse()
Paul Belangerb30342b2016-11-14 12:30:43 -05004112 correct_messages = [
4113 'initial commit', 'add content from fixture', 'B-1']
James E. Blairbfb8e042014-12-30 17:01:44 -08004114 self.assertEqual(repo_messages, correct_messages)
4115
Paul Belangerb30342b2016-11-14 12:30:43 -05004116 self.launch_server.hold_jobs_in_build = False
4117 self.launch_server.release()
4118 self.waitUntilSettled()
4119
James E. Blairbfb8e042014-12-30 17:01:44 -08004120 self.assertEqual(A.data['status'], 'NEW')
4121 self.assertEqual(B.data['status'], 'NEW')
4122 self.assertEqual(A.reported, 1)
4123 self.assertEqual(B.reported, 0)
4124
4125 self.assertEqual(self.history[0].changes, '2,1 1,1')
Paul Belangerb30342b2016-11-14 12:30:43 -05004126 tenant = self.sched.abide.tenants.get('tenant-one')
4127 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
James E. Blair8f78d882015-02-05 08:51:37 -08004128
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004129 def test_crd_check_git_depends(self):
4130 "Test single-repo dependencies in independent pipelines"
James E. Blairb8c16472015-05-05 14:55:26 -07004131 self.gearman_server.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004132 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4133 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4134
4135 # Add two git-dependent changes and make sure they both report
4136 # success.
4137 B.setDependsOn(A, 1)
4138 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4139 self.waitUntilSettled()
4140 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4141 self.waitUntilSettled()
4142
James E. Blairb8c16472015-05-05 14:55:26 -07004143 self.orderedRelease()
4144 self.gearman_server.hold_jobs_in_build = False
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004145 self.waitUntilSettled()
4146
4147 self.assertEqual(A.data['status'], 'NEW')
4148 self.assertEqual(B.data['status'], 'NEW')
4149 self.assertEqual(A.reported, 1)
4150 self.assertEqual(B.reported, 1)
4151
4152 self.assertEqual(self.history[0].changes, '1,1')
4153 self.assertEqual(self.history[-1].changes, '1,1 2,1')
Paul Belanger08136962016-11-03 17:57:38 -04004154 tenant = self.sched.abide.tenants.get('tenant-one')
4155 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004156
4157 self.assertIn('Build succeeded', A.messages[0])
4158 self.assertIn('Build succeeded', B.messages[0])
4159
4160 def test_crd_check_duplicate(self):
4161 "Test duplicate check in independent pipelines"
James E. Blair08d19992016-08-10 15:25:31 -07004162 self.launch_server.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004163 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4164 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
Paul Belanger08136962016-11-03 17:57:38 -04004165 tenant = self.sched.abide.tenants.get('tenant-one')
4166 check_pipeline = tenant.layout.pipelines['check']
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004167
4168 # Add two git-dependent changes...
4169 B.setDependsOn(A, 1)
4170 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4171 self.waitUntilSettled()
4172 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4173
4174 # ...make sure the live one is not duplicated...
4175 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4176 self.waitUntilSettled()
4177 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4178
4179 # ...but the non-live one is able to be.
4180 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4181 self.waitUntilSettled()
4182 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4183
Clark Boylandd849822015-03-02 12:38:14 -08004184 # Release jobs in order to avoid races with change A jobs
4185 # finishing before change B jobs.
James E. Blaird7650852015-05-07 15:47:37 -07004186 self.orderedRelease()
James E. Blair08d19992016-08-10 15:25:31 -07004187 self.launch_server.hold_jobs_in_build = False
4188 self.launch_server.release()
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004189 self.waitUntilSettled()
4190
4191 self.assertEqual(A.data['status'], 'NEW')
4192 self.assertEqual(B.data['status'], 'NEW')
4193 self.assertEqual(A.reported, 1)
4194 self.assertEqual(B.reported, 1)
4195
4196 self.assertEqual(self.history[0].changes, '1,1 2,1')
4197 self.assertEqual(self.history[1].changes, '1,1')
Paul Belanger08136962016-11-03 17:57:38 -04004198 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004199
4200 self.assertIn('Build succeeded', A.messages[0])
4201 self.assertIn('Build succeeded', B.messages[0])
4202
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004203 def _test_crd_check_reconfiguration(self, project1, project2):
James E. Blair8f78d882015-02-05 08:51:37 -08004204 "Test cross-repo dependencies re-enqueued in independent pipelines"
4205
4206 self.gearman_server.hold_jobs_in_queue = True
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004207 A = self.fake_gerrit.addFakeChange(project1, 'master', 'A')
4208 B = self.fake_gerrit.addFakeChange(project2, 'master', 'B')
James E. Blair8f78d882015-02-05 08:51:37 -08004209
4210 # A Depends-On: B
4211 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4212 A.subject, B.data['id'])
4213
4214 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4215 self.waitUntilSettled()
4216
4217 self.sched.reconfigure(self.config)
4218
4219 # Make sure the items still share a change queue, and the
4220 # first one is not live.
Paul Belangerce4485f2016-11-11 17:01:56 -05004221 tenant = self.sched.abide.tenants.get('tenant-one')
4222 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 1)
4223 queue = tenant.layout.pipelines['check'].queues[0]
James E. Blair8f78d882015-02-05 08:51:37 -08004224 first_item = queue.queue[0]
4225 for item in queue.queue:
4226 self.assertEqual(item.queue, first_item.queue)
4227 self.assertFalse(first_item.live)
4228 self.assertTrue(queue.queue[1].live)
4229
4230 self.gearman_server.hold_jobs_in_queue = False
4231 self.gearman_server.release()
4232 self.waitUntilSettled()
4233
4234 self.assertEqual(A.data['status'], 'NEW')
4235 self.assertEqual(B.data['status'], 'NEW')
4236 self.assertEqual(A.reported, 1)
4237 self.assertEqual(B.reported, 0)
4238
4239 self.assertEqual(self.history[0].changes, '2,1 1,1')
Paul Belangerce4485f2016-11-11 17:01:56 -05004240 self.assertEqual(len(tenant.layout.pipelines['check'].queues), 0)
James E. Blair17dd6772015-02-09 14:45:18 -08004241
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004242 def test_crd_check_reconfiguration(self):
4243 self._test_crd_check_reconfiguration('org/project1', 'org/project2')
4244
4245 def test_crd_undefined_project(self):
4246 """Test that undefined projects in dependencies are handled for
4247 independent pipelines"""
4248 # It's a hack for fake gerrit,
4249 # as it implies repo creation upon the creation of any change
4250 self.init_repo("org/unknown")
4251 self._test_crd_check_reconfiguration('org/project1', 'org/unknown')
4252
James E. Blairec056492016-07-22 09:45:56 -07004253 @skip("Disabled for early v3 development")
James E. Blair17dd6772015-02-09 14:45:18 -08004254 def test_crd_check_ignore_dependencies(self):
4255 "Test cross-repo dependencies can be ignored"
James E. Blairf84026c2015-12-08 16:11:46 -08004256 self.updateConfigLayout(
4257 'tests/fixtures/layout-ignore-dependencies.yaml')
James E. Blair17dd6772015-02-09 14:45:18 -08004258 self.sched.reconfigure(self.config)
4259 self.registerJobs()
4260
4261 self.gearman_server.hold_jobs_in_queue = True
4262 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4263 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4264 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
4265
4266 # A Depends-On: B
4267 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4268 A.subject, B.data['id'])
4269 # C git-depends on B
4270 C.setDependsOn(B, 1)
4271 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4272 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4273 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4274 self.waitUntilSettled()
4275
4276 # Make sure none of the items share a change queue, and all
4277 # are live.
4278 check_pipeline = self.sched.layout.pipelines['check']
4279 self.assertEqual(len(check_pipeline.queues), 3)
4280 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4281 for item in check_pipeline.getAllItems():
4282 self.assertTrue(item.live)
4283
4284 self.gearman_server.hold_jobs_in_queue = False
4285 self.gearman_server.release()
4286 self.waitUntilSettled()
4287
4288 self.assertEqual(A.data['status'], 'NEW')
4289 self.assertEqual(B.data['status'], 'NEW')
4290 self.assertEqual(C.data['status'], 'NEW')
4291 self.assertEqual(A.reported, 1)
4292 self.assertEqual(B.reported, 1)
4293 self.assertEqual(C.reported, 1)
4294
4295 # Each job should have tested exactly one change
4296 for job in self.history:
4297 self.assertEqual(len(job.changes.split()), 1)
James E. Blair96698e22015-04-02 07:48:21 -07004298
James E. Blairec056492016-07-22 09:45:56 -07004299 @skip("Disabled for early v3 development")
James E. Blair96698e22015-04-02 07:48:21 -07004300 def test_crd_check_transitive(self):
4301 "Test transitive cross-repo dependencies"
4302 # Specifically, if A -> B -> C, and C gets a new patchset and
4303 # A gets a new patchset, ensure the test of A,2 includes B,1
4304 # and C,2 (not C,1 which would indicate stale data in the
4305 # cache for B).
4306 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4307 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4308 C = self.fake_gerrit.addFakeChange('org/project3', 'master', 'C')
4309
4310 # A Depends-On: B
4311 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4312 A.subject, B.data['id'])
4313
4314 # B Depends-On: C
4315 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4316 B.subject, C.data['id'])
4317
4318 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4319 self.waitUntilSettled()
4320 self.assertEqual(self.history[-1].changes, '3,1 2,1 1,1')
4321
4322 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4323 self.waitUntilSettled()
4324 self.assertEqual(self.history[-1].changes, '3,1 2,1')
4325
4326 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4327 self.waitUntilSettled()
4328 self.assertEqual(self.history[-1].changes, '3,1')
4329
4330 C.addPatchset()
4331 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(2))
4332 self.waitUntilSettled()
4333 self.assertEqual(self.history[-1].changes, '3,2')
4334
4335 A.addPatchset()
4336 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
4337 self.waitUntilSettled()
4338 self.assertEqual(self.history[-1].changes, '3,2 2,1 1,2')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004339
James E. Blaira8b90b32016-08-24 15:18:50 -07004340 def test_crd_check_unknown(self):
4341 "Test unknown projects in independent pipeline"
4342 self.init_repo("org/unknown")
4343 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4344 B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'D')
4345 # A Depends-On: B
4346 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4347 A.subject, B.data['id'])
4348
4349 # Make sure zuul has seen an event on B.
4350 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4351 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4352 self.waitUntilSettled()
4353
4354 self.assertEqual(A.data['status'], 'NEW')
4355 self.assertEqual(A.reported, 1)
4356 self.assertEqual(B.data['status'], 'NEW')
4357 self.assertEqual(B.reported, 0)
4358
James E. Blair92464a22016-04-05 10:21:26 -07004359 def test_crd_cycle_join(self):
4360 "Test an updated change creates a cycle"
4361 A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A')
4362
4363 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4364 self.waitUntilSettled()
4365
4366 # Create B->A
4367 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4368 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4369 B.subject, A.data['id'])
4370 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4371 self.waitUntilSettled()
4372
4373 # Update A to add A->B (a cycle).
4374 A.addPatchset()
4375 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4376 A.subject, B.data['id'])
4377 # Normally we would submit the patchset-created event for
4378 # processing here, however, we have no way of noting whether
4379 # the dependency cycle detection correctly raised an
4380 # exception, so instead, we reach into the source driver and
4381 # call the method that would ultimately be called by the event
4382 # processing.
4383
Paul Belanger0e155e22016-11-14 14:12:23 -05004384 tenant = self.sched.abide.tenants.get('tenant-one')
4385 source = tenant.layout.pipelines['gate'].source
4386
4387 # TODO(pabelanger): As we add more source / trigger APIs we should make
4388 # it easier for users to create events for testing.
4389 event = zuul.model.TriggerEvent()
4390 event.trigger_name = 'gerrit'
4391 event.change_number = '1'
4392 event.patch_number = '2'
James E. Blair92464a22016-04-05 10:21:26 -07004393 with testtools.ExpectedException(
4394 Exception, "Dependency cycle detected"):
Paul Belanger0e155e22016-11-14 14:12:23 -05004395 source.getChange(event, True)
James E. Blair92464a22016-04-05 10:21:26 -07004396 self.log.debug("Got expected dependency cycle exception")
4397
4398 # Now if we update B to remove the depends-on, everything
4399 # should be okay. B; A->B
4400
4401 B.addPatchset()
4402 B.data['commitMessage'] = '%s\n' % (B.subject,)
Paul Belanger0e155e22016-11-14 14:12:23 -05004403
4404 source.getChange(event, True)
4405 event.change_number = '2'
4406 source.getChange(event, True)
James E. Blair92464a22016-04-05 10:21:26 -07004407
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004408 def test_disable_at(self):
4409 "Test a pipeline will only report to the disabled trigger when failing"
4410
Paul Belanger7dc76e82016-11-11 16:51:08 -05004411 self.updateConfigLayout('layout-disabled-at')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004412 self.sched.reconfigure(self.config)
4413
Paul Belanger7dc76e82016-11-11 16:51:08 -05004414 tenant = self.sched.abide.tenants.get('openstack')
4415 self.assertEqual(3, tenant.layout.pipelines['check'].disable_at)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004416 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004417 0, tenant.layout.pipelines['check']._consecutive_failures)
4418 self.assertFalse(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004419
4420 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4421 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
4422 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
4423 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
4424 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
4425 F = self.fake_gerrit.addFakeChange('org/project', 'master', 'F')
4426 G = self.fake_gerrit.addFakeChange('org/project', 'master', 'G')
4427 H = self.fake_gerrit.addFakeChange('org/project', 'master', 'H')
4428 I = self.fake_gerrit.addFakeChange('org/project', 'master', 'I')
4429 J = self.fake_gerrit.addFakeChange('org/project', 'master', 'J')
4430 K = self.fake_gerrit.addFakeChange('org/project', 'master', 'K')
4431
James E. Blair08d19992016-08-10 15:25:31 -07004432 self.launch_server.failJob('project-test1', A)
4433 self.launch_server.failJob('project-test1', B)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004434 # Let C pass, resetting the counter
James E. Blair08d19992016-08-10 15:25:31 -07004435 self.launch_server.failJob('project-test1', D)
4436 self.launch_server.failJob('project-test1', E)
4437 self.launch_server.failJob('project-test1', F)
4438 self.launch_server.failJob('project-test1', G)
4439 self.launch_server.failJob('project-test1', H)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004440 # I also passes but should only report to the disabled reporters
James E. Blair08d19992016-08-10 15:25:31 -07004441 self.launch_server.failJob('project-test1', J)
4442 self.launch_server.failJob('project-test1', K)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004443
4444 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4445 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4446 self.waitUntilSettled()
4447
4448 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004449 2, tenant.layout.pipelines['check']._consecutive_failures)
4450 self.assertFalse(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004451
4452 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4453 self.waitUntilSettled()
4454
4455 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004456 0, tenant.layout.pipelines['check']._consecutive_failures)
4457 self.assertFalse(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004458
4459 self.fake_gerrit.addEvent(D.getPatchsetCreatedEvent(1))
4460 self.fake_gerrit.addEvent(E.getPatchsetCreatedEvent(1))
4461 self.fake_gerrit.addEvent(F.getPatchsetCreatedEvent(1))
4462 self.waitUntilSettled()
4463
4464 # We should be disabled now
4465 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004466 3, tenant.layout.pipelines['check']._consecutive_failures)
4467 self.assertTrue(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004468
4469 # We need to wait between each of these patches to make sure the
4470 # smtp messages come back in an expected order
4471 self.fake_gerrit.addEvent(G.getPatchsetCreatedEvent(1))
4472 self.waitUntilSettled()
4473 self.fake_gerrit.addEvent(H.getPatchsetCreatedEvent(1))
4474 self.waitUntilSettled()
4475 self.fake_gerrit.addEvent(I.getPatchsetCreatedEvent(1))
4476 self.waitUntilSettled()
4477
4478 # The first 6 (ABCDEF) jobs should have reported back to gerrt thus
4479 # leaving a message on each change
4480 self.assertEqual(1, len(A.messages))
4481 self.assertIn('Build failed.', A.messages[0])
4482 self.assertEqual(1, len(B.messages))
4483 self.assertIn('Build failed.', B.messages[0])
4484 self.assertEqual(1, len(C.messages))
4485 self.assertIn('Build succeeded.', C.messages[0])
4486 self.assertEqual(1, len(D.messages))
4487 self.assertIn('Build failed.', D.messages[0])
4488 self.assertEqual(1, len(E.messages))
4489 self.assertIn('Build failed.', E.messages[0])
4490 self.assertEqual(1, len(F.messages))
4491 self.assertIn('Build failed.', F.messages[0])
4492
4493 # The last 3 (GHI) would have only reported via smtp.
4494 self.assertEqual(3, len(self.smtp_messages))
4495 self.assertEqual(0, len(G.messages))
4496 self.assertIn('Build failed.', self.smtp_messages[0]['body'])
Paul Belanger7dc76e82016-11-11 16:51:08 -05004497 self.assertIn(
4498 'project-test1 https://server/job', self.smtp_messages[0]['body'])
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004499 self.assertEqual(0, len(H.messages))
4500 self.assertIn('Build failed.', self.smtp_messages[1]['body'])
Paul Belanger7dc76e82016-11-11 16:51:08 -05004501 self.assertIn(
4502 'project-test1 https://server/job', self.smtp_messages[1]['body'])
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004503 self.assertEqual(0, len(I.messages))
4504 self.assertIn('Build succeeded.', self.smtp_messages[2]['body'])
Paul Belanger7dc76e82016-11-11 16:51:08 -05004505 self.assertIn(
4506 'project-test1 https://server/job', self.smtp_messages[2]['body'])
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004507
4508 # Now reload the configuration (simulate a HUP) to check the pipeline
4509 # comes out of disabled
4510 self.sched.reconfigure(self.config)
4511
Paul Belanger7dc76e82016-11-11 16:51:08 -05004512 tenant = self.sched.abide.tenants.get('openstack')
4513
4514 self.assertEqual(3, tenant.layout.pipelines['check'].disable_at)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004515 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004516 0, tenant.layout.pipelines['check']._consecutive_failures)
4517 self.assertFalse(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004518
4519 self.fake_gerrit.addEvent(J.getPatchsetCreatedEvent(1))
4520 self.fake_gerrit.addEvent(K.getPatchsetCreatedEvent(1))
4521 self.waitUntilSettled()
4522
4523 self.assertEqual(
Paul Belanger7dc76e82016-11-11 16:51:08 -05004524 2, tenant.layout.pipelines['check']._consecutive_failures)
4525 self.assertFalse(tenant.layout.pipelines['check']._disabled)
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004526
4527 # J and K went back to gerrit
4528 self.assertEqual(1, len(J.messages))
4529 self.assertIn('Build failed.', J.messages[0])
4530 self.assertEqual(1, len(K.messages))
4531 self.assertIn('Build failed.', K.messages[0])
4532 # No more messages reported via smtp
4533 self.assertEqual(3, len(self.smtp_messages))
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004534
James E. Blairec056492016-07-22 09:45:56 -07004535 @skip("Disabled for early v3 development")
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004536 def test_success_pattern(self):
4537 "Ensure bad build params are ignored"
4538
4539 # Use SMTP reporter to grab the result message easier
4540 self.init_repo("org/docs")
4541 self.config.set('zuul', 'layout_config',
4542 'tests/fixtures/layout-success-pattern.yaml')
4543 self.sched.reconfigure(self.config)
James E. Blair08d19992016-08-10 15:25:31 -07004544 self.launch_server.hold_jobs_in_build = True
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004545 self.registerJobs()
4546
4547 A = self.fake_gerrit.addFakeChange('org/docs', 'master', 'A')
4548 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4549 self.waitUntilSettled()
4550
4551 # Grab build id
4552 self.assertEqual(len(self.builds), 1)
4553 uuid = self.builds[0].unique[:7]
4554
James E. Blair08d19992016-08-10 15:25:31 -07004555 self.launch_server.hold_jobs_in_build = False
4556 self.launch_server.release()
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004557 self.waitUntilSettled()
4558
4559 self.assertEqual(len(self.smtp_messages), 1)
4560 body = self.smtp_messages[0]['body'].splitlines()
4561 self.assertEqual('Build succeeded.', body[0])
4562
4563 self.assertIn(
4564 '- docs-draft-test http://docs-draft.example.org/1/1/1/check/'
4565 'docs-draft-test/%s/publish-docs/' % uuid,
4566 body[2])
4567 self.assertIn(
4568 '- docs-draft-test2 https://server/job/docs-draft-test2/1/',
4569 body[3])
Arieb6f068c2016-10-09 13:11:06 +03004570
4571
4572class TestDuplicatePipeline(ZuulTestCase):
4573 tenant_config_file = 'config/duplicate-pipeline/main.yaml'
4574
4575 def test_duplicate_pipelines(self):
4576 "Test that a change matching multiple pipelines works"
4577
4578 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4579 self.fake_gerrit.addEvent(A.getChangeRestoredEvent())
4580 self.waitUntilSettled()
4581
4582 self.assertHistory([
4583 dict(name='project-test1', result='SUCCESS', changes='1,1',
4584 pipeline='dup1'),
4585 dict(name='project-test1', result='SUCCESS', changes='1,1',
4586 pipeline='dup2'),
Paul Belanger73a7d8e2016-11-09 11:12:42 -05004587 ], ordered=False)
Arieb6f068c2016-10-09 13:11:06 +03004588
4589 self.assertEqual(len(A.messages), 2)
4590
Paul Belangera46a3742016-11-09 14:23:03 -05004591 if 'dup1' in A.messages[0]:
4592 self.assertIn('dup1', A.messages[0])
4593 self.assertNotIn('dup2', A.messages[0])
4594 self.assertIn('project-test1', A.messages[0])
4595 self.assertIn('dup2', A.messages[1])
4596 self.assertNotIn('dup1', A.messages[1])
4597 self.assertIn('project-test1', A.messages[1])
4598 else:
4599 self.assertIn('dup1', A.messages[1])
4600 self.assertNotIn('dup2', A.messages[1])
4601 self.assertIn('project-test1', A.messages[1])
4602 self.assertIn('dup2', A.messages[0])
4603 self.assertNotIn('dup1', A.messages[0])
4604 self.assertIn('project-test1', A.messages[0])
Paul Belangerfac69ba2016-11-03 09:03:13 -04004605
4606
4607class TestSchedulerOneJobProject(ZuulTestCase):
4608 tenant_config_file = 'config/one-job-project/main.yaml'
4609
4610 def test_one_job_project(self):
4611 "Test that queueing works with one job"
4612 A = self.fake_gerrit.addFakeChange('org/one-job-project',
4613 'master', 'A')
4614 B = self.fake_gerrit.addFakeChange('org/one-job-project',
4615 'master', 'B')
4616 A.addApproval('code-review', 2)
4617 B.addApproval('code-review', 2)
4618 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
4619 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
4620 self.waitUntilSettled()
4621
4622 self.assertEqual(A.data['status'], 'MERGED')
4623 self.assertEqual(A.reported, 2)
4624 self.assertEqual(B.data['status'], 'MERGED')
4625 self.assertEqual(B.reported, 2)
Paul Belanger86085b32016-11-03 12:48:57 -04004626
4627
4628class TestSchedulerTemplatedProject(ZuulTestCase):
4629 tenant_config_file = 'config/templated-project/main.yaml'
4630
4631 def test_job_from_templates_launched(self):
4632 "Test whether a job generated via a template can be launched"
4633
4634 A = self.fake_gerrit.addFakeChange(
4635 'org/templated-project', 'master', 'A')
4636 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4637 self.waitUntilSettled()
4638
4639 self.assertEqual(self.getJobFromHistory('project-test1').result,
4640 'SUCCESS')
4641 self.assertEqual(self.getJobFromHistory('project-test2').result,
4642 'SUCCESS')
Paul Belanger3adf72f2016-11-03 14:57:31 -04004643
4644 def test_layered_templates(self):
4645 "Test whether a job generated via a template can be launched"
4646
4647 A = self.fake_gerrit.addFakeChange(
4648 'org/layered-project', 'master', 'A')
4649 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4650 self.waitUntilSettled()
4651
4652 self.assertEqual(self.getJobFromHistory('project-test1').result,
4653 'SUCCESS')
4654 self.assertEqual(self.getJobFromHistory('project-test2').result,
4655 'SUCCESS')
4656 self.assertEqual(self.getJobFromHistory('layered-project-test3'
4657 ).result, 'SUCCESS')
4658 self.assertEqual(self.getJobFromHistory('layered-project-test4'
4659 ).result, 'SUCCESS')
4660 self.assertEqual(self.getJobFromHistory('layered-project-foo-test5'
4661 ).result, 'SUCCESS')
4662 self.assertEqual(self.getJobFromHistory('project-test6').result,
4663 'SUCCESS')