blob: a953ffb0083126913ab15f64498c80e2ddf9ca9c [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
Monty Taylorbc758832013-06-17 17:22:42 -040017from cStringIO import StringIO
Yuriy Taradaya6d452f2014-04-16 12:36:20 +040018import gzip
James E. Blairb0fcae42012-07-17 11:12:10 -070019import json
Monty Taylorbc758832013-06-17 17:22:42 -040020import logging
21import os
James E. Blairb0fcae42012-07-17 11:12:10 -070022import re
James E. Blair4886cc12012-07-18 15:39:41 -070023import shutil
Monty Taylorbc758832013-06-17 17:22:42 -040024import time
James E. Blair1843a552013-07-03 14:19:52 -070025import urllib
Monty Taylorbc758832013-06-17 17:22:42 -040026import urllib2
Monty Taylorbc758832013-06-17 17:22:42 -040027
James E. Blair4886cc12012-07-18 15:39:41 -070028import git
Monty Taylorbc758832013-06-17 17:22:42 -040029import testtools
James E. Blairb0fcae42012-07-17 11:12:10 -070030
James E. Blairb0fcae42012-07-17 11:12:10 -070031import zuul.scheduler
James E. Blairad28e912013-11-27 10:43:22 -080032import zuul.rpcclient
Joshua Hesketh1879cf72013-08-19 14:13:15 +100033import zuul.reporter.gerrit
Joshua Hesketh5fea8672013-08-19 17:32:01 +100034import zuul.reporter.smtp
James E. Blairb0fcae42012-07-17 11:12:10 -070035
Clark Boylanb640e052014-04-03 16:41:46 -070036from tests.base import ZuulTestCase, repack_repo
James E. Blairb0fcae42012-07-17 11:12:10 -070037
James E. Blair1f4c2bb2013-04-26 08:40:46 -070038logging.basicConfig(level=logging.DEBUG,
39 format='%(asctime)s %(name)-32s '
40 '%(levelname)-8s %(message)s')
James E. Blairb0fcae42012-07-17 11:12:10 -070041
42
Clark Boylanb640e052014-04-03 16:41:46 -070043class TestScheduler(ZuulTestCase):
James E. Blairb0fcae42012-07-17 11:12:10 -070044 def test_jobs_launched(self):
45 "Test that jobs are launched and a change is merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -070046
James E. Blairb0fcae42012-07-17 11:12:10 -070047 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8c803f82012-07-31 16:25:42 -070048 A.addApproval('CRVW', 2)
James E. Blairb0fcae42012-07-17 11:12:10 -070049 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
50 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -040051 self.assertEqual(self.getJobFromHistory('project-merge').result,
52 'SUCCESS')
53 self.assertEqual(self.getJobFromHistory('project-test1').result,
54 'SUCCESS')
55 self.assertEqual(self.getJobFromHistory('project-test2').result,
56 'SUCCESS')
57 self.assertEqual(A.data['status'], 'MERGED')
58 self.assertEqual(A.reported, 2)
James E. Blairb0fcae42012-07-17 11:12:10 -070059
James E. Blair66eeebf2013-07-27 17:44:32 -070060 self.assertReportedStat('gerrit.event.comment-added', value='1|c')
61 self.assertReportedStat('zuul.pipeline.gate.current_changes',
62 value='1|g')
63 self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
64 kind='ms')
65 self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
66 value='1|c')
67 self.assertReportedStat('zuul.pipeline.gate.resident_time', kind='ms')
68 self.assertReportedStat('zuul.pipeline.gate.total_changes',
69 value='1|c')
James E. Blair412e5582013-04-22 15:50:12 -070070 self.assertReportedStat(
James E. Blair66eeebf2013-07-27 17:44:32 -070071 'zuul.pipeline.gate.org.project.resident_time', kind='ms')
James E. Blair412e5582013-04-22 15:50:12 -070072 self.assertReportedStat(
James E. Blair66eeebf2013-07-27 17:44:32 -070073 'zuul.pipeline.gate.org.project.total_changes', value='1|c')
James E. Blair412e5582013-04-22 15:50:12 -070074
James E. Blair3cb10702013-08-24 08:56:03 -070075 def test_initial_pipeline_gauges(self):
76 "Test that each pipeline reported its length on start"
77 pipeline_names = self.sched.layout.pipelines.keys()
78 self.assertNotEqual(len(pipeline_names), 0)
79 for name in pipeline_names:
80 self.assertReportedStat('zuul.pipeline.%s.current_changes' % name,
81 value='0|g')
82
James E. Blair42f74822013-05-14 15:18:03 -070083 def test_duplicate_pipelines(self):
84 "Test that a change matching multiple pipelines works"
James E. Blair1b4d9722013-05-21 10:32:04 -070085
James E. Blair42f74822013-05-14 15:18:03 -070086 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
87 self.fake_gerrit.addEvent(A.getChangeRestoredEvent())
88 self.waitUntilSettled()
James E. Blair42f74822013-05-14 15:18:03 -070089
Monty Taylor98f0f3e2013-07-06 16:02:31 -040090 self.assertEqual(len(self.history), 2)
Monty Taylor6bef8ef2013-06-02 08:17:12 -040091 self.history[0].name == 'project-test1'
92 self.history[1].name == 'project-test1'
James E. Blair42f74822013-05-14 15:18:03 -070093
Monty Taylor98f0f3e2013-07-06 16:02:31 -040094 self.assertEqual(len(A.messages), 2)
James E. Blair42f74822013-05-14 15:18:03 -070095 if 'dup1/project-test1' in A.messages[0]:
Monty Taylor98f0f3e2013-07-06 16:02:31 -040096 self.assertIn('dup1/project-test1', A.messages[0])
97 self.assertNotIn('dup2/project-test1', A.messages[0])
98 self.assertNotIn('dup1/project-test1', A.messages[1])
99 self.assertIn('dup2/project-test1', A.messages[1])
James E. Blair42f74822013-05-14 15:18:03 -0700100 else:
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400101 self.assertIn('dup1/project-test1', A.messages[1])
102 self.assertNotIn('dup2/project-test1', A.messages[1])
103 self.assertNotIn('dup1/project-test1', A.messages[0])
104 self.assertIn('dup2/project-test1', A.messages[0])
James E. Blair42f74822013-05-14 15:18:03 -0700105
James E. Blairb0fcae42012-07-17 11:12:10 -0700106 def test_parallel_changes(self):
107 "Test that changes are tested in parallel and merged in series"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700108
109 self.worker.hold_jobs_in_build = True
James E. Blairb0fcae42012-07-17 11:12:10 -0700110 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
111 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
112 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700113 A.addApproval('CRVW', 2)
114 B.addApproval('CRVW', 2)
115 C.addApproval('CRVW', 2)
James E. Blairb0fcae42012-07-17 11:12:10 -0700116
117 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
118 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
119 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
120
121 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400122 self.assertEqual(len(self.builds), 1)
123 self.assertEqual(self.builds[0].name, 'project-merge')
124 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700125
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700126 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700127 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400128 self.assertEqual(len(self.builds), 3)
129 self.assertEqual(self.builds[0].name, 'project-test1')
130 self.assertTrue(self.job_has_changes(self.builds[0], A))
131 self.assertEqual(self.builds[1].name, 'project-test2')
132 self.assertTrue(self.job_has_changes(self.builds[1], A))
133 self.assertEqual(self.builds[2].name, 'project-merge')
134 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700135
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700136 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700137 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400138 self.assertEqual(len(self.builds), 5)
139 self.assertEqual(self.builds[0].name, 'project-test1')
140 self.assertTrue(self.job_has_changes(self.builds[0], A))
141 self.assertEqual(self.builds[1].name, 'project-test2')
142 self.assertTrue(self.job_has_changes(self.builds[1], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700143
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400144 self.assertEqual(self.builds[2].name, 'project-test1')
145 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
146 self.assertEqual(self.builds[3].name, 'project-test2')
147 self.assertTrue(self.job_has_changes(self.builds[3], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700148
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400149 self.assertEqual(self.builds[4].name, 'project-merge')
150 self.assertTrue(self.job_has_changes(self.builds[4], A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700151
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700152 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700153 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400154 self.assertEqual(len(self.builds), 6)
155 self.assertEqual(self.builds[0].name, 'project-test1')
156 self.assertTrue(self.job_has_changes(self.builds[0], A))
157 self.assertEqual(self.builds[1].name, 'project-test2')
158 self.assertTrue(self.job_has_changes(self.builds[1], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700159
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400160 self.assertEqual(self.builds[2].name, 'project-test1')
161 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
162 self.assertEqual(self.builds[3].name, 'project-test2')
163 self.assertTrue(self.job_has_changes(self.builds[3], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700164
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400165 self.assertEqual(self.builds[4].name, 'project-test1')
166 self.assertTrue(self.job_has_changes(self.builds[4], A, B, C))
167 self.assertEqual(self.builds[5].name, 'project-test2')
168 self.assertTrue(self.job_has_changes(self.builds[5], A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700169
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700170 self.worker.hold_jobs_in_build = False
171 self.worker.release()
James E. Blairb0fcae42012-07-17 11:12:10 -0700172 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400173 self.assertEqual(len(self.builds), 0)
James E. Blairb0fcae42012-07-17 11:12:10 -0700174
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400175 self.assertEqual(len(self.history), 9)
176 self.assertEqual(A.data['status'], 'MERGED')
177 self.assertEqual(B.data['status'], 'MERGED')
178 self.assertEqual(C.data['status'], 'MERGED')
179 self.assertEqual(A.reported, 2)
180 self.assertEqual(B.reported, 2)
181 self.assertEqual(C.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700182
183 def test_failed_changes(self):
184 "Test that a change behind a failed change is retested"
James E. Blaire2819012013-06-28 17:17:26 -0400185 self.worker.hold_jobs_in_build = True
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700186
James E. Blairb02a3bb2012-07-30 17:49:55 -0700187 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
188 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8c803f82012-07-31 16:25:42 -0700189 A.addApproval('CRVW', 2)
190 B.addApproval('CRVW', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700191
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700192 self.worker.addFailTest('project-test1', A)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700193
James E. Blaire2819012013-06-28 17:17:26 -0400194 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
195 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700196 self.waitUntilSettled()
James E. Blaire2819012013-06-28 17:17:26 -0400197
198 self.worker.release('.*-merge')
199 self.waitUntilSettled()
200
201 self.worker.hold_jobs_in_build = False
202 self.worker.release()
203
204 self.waitUntilSettled()
205 # It's certain that the merge job for change 2 will run, but
206 # the test1 and test2 jobs may or may not run.
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400207 self.assertTrue(len(self.history) > 6)
208 self.assertEqual(A.data['status'], 'NEW')
209 self.assertEqual(B.data['status'], 'MERGED')
210 self.assertEqual(A.reported, 2)
211 self.assertEqual(B.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700212
213 def test_independent_queues(self):
214 "Test that changes end up in the right queues"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700215
216 self.worker.hold_jobs_in_build = True
Zhongyue Luo5d556072012-09-21 02:00:47 +0900217 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700218 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
219 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700220 A.addApproval('CRVW', 2)
221 B.addApproval('CRVW', 2)
222 C.addApproval('CRVW', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700223
224 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
225 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
226 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
227
James E. Blairb02a3bb2012-07-30 17:49:55 -0700228 self.waitUntilSettled()
229
230 # There should be one merge job at the head of each queue running
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400231 self.assertEqual(len(self.builds), 2)
232 self.assertEqual(self.builds[0].name, 'project-merge')
233 self.assertTrue(self.job_has_changes(self.builds[0], A))
234 self.assertEqual(self.builds[1].name, 'project1-merge')
235 self.assertTrue(self.job_has_changes(self.builds[1], B))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700236
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700237 # Release the current merge builds
238 self.worker.release('.*-merge')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700239 self.waitUntilSettled()
240 # Release the merge job for project2 which is behind project1
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700241 self.worker.release('.*-merge')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700242 self.waitUntilSettled()
243
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700244 # All the test builds should be running:
James E. Blairb02a3bb2012-07-30 17:49:55 -0700245 # project1 (3) + project2 (3) + project (2) = 8
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400246 self.assertEqual(len(self.builds), 8)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700247
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700248 self.worker.release()
James E. Blairb02a3bb2012-07-30 17:49:55 -0700249 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400250 self.assertEqual(len(self.builds), 0)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700251
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400252 self.assertEqual(len(self.history), 11)
253 self.assertEqual(A.data['status'], 'MERGED')
254 self.assertEqual(B.data['status'], 'MERGED')
255 self.assertEqual(C.data['status'], 'MERGED')
256 self.assertEqual(A.reported, 2)
257 self.assertEqual(B.reported, 2)
258 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700259
260 def test_failed_change_at_head(self):
261 "Test that if a change at the head fails, jobs behind it are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700262
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700263 self.worker.hold_jobs_in_build = True
James E. Blaird466dc42012-07-31 10:42:56 -0700264 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
265 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
266 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700267 A.addApproval('CRVW', 2)
268 B.addApproval('CRVW', 2)
269 C.addApproval('CRVW', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700270
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700271 self.worker.addFailTest('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700272
273 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
274 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
275 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
276
277 self.waitUntilSettled()
James E. Blaird466dc42012-07-31 10:42:56 -0700278
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400279 self.assertEqual(len(self.builds), 1)
280 self.assertEqual(self.builds[0].name, 'project-merge')
281 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blaird466dc42012-07-31 10:42:56 -0700282
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700283 self.worker.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700284 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700285 self.worker.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700286 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700287 self.worker.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700288 self.waitUntilSettled()
289
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400290 self.assertEqual(len(self.builds), 6)
291 self.assertEqual(self.builds[0].name, 'project-test1')
292 self.assertEqual(self.builds[1].name, 'project-test2')
293 self.assertEqual(self.builds[2].name, 'project-test1')
294 self.assertEqual(self.builds[3].name, 'project-test2')
295 self.assertEqual(self.builds[4].name, 'project-test1')
296 self.assertEqual(self.builds[5].name, 'project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700297
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400298 self.release(self.builds[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700299 self.waitUntilSettled()
300
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400301 # project-test2, project-merge for B
302 self.assertEqual(len(self.builds), 2)
303 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 4)
James E. Blaird466dc42012-07-31 10:42:56 -0700304
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700305 self.worker.hold_jobs_in_build = False
306 self.worker.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700307 self.waitUntilSettled()
308
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400309 self.assertEqual(len(self.builds), 0)
310 self.assertEqual(len(self.history), 15)
311 self.assertEqual(A.data['status'], 'NEW')
312 self.assertEqual(B.data['status'], 'MERGED')
313 self.assertEqual(C.data['status'], 'MERGED')
314 self.assertEqual(A.reported, 2)
315 self.assertEqual(B.reported, 2)
316 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700317
James E. Blair0aac4872013-08-23 14:02:38 -0700318 def test_failed_change_in_middle(self):
319 "Test a failed change in the middle of the queue"
320
321 self.worker.hold_jobs_in_build = True
322 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
323 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
324 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
325 A.addApproval('CRVW', 2)
326 B.addApproval('CRVW', 2)
327 C.addApproval('CRVW', 2)
328
329 self.worker.addFailTest('project-test1', B)
330
331 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
332 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
333 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
334
335 self.waitUntilSettled()
336
337 self.worker.release('.*-merge')
338 self.waitUntilSettled()
339 self.worker.release('.*-merge')
340 self.waitUntilSettled()
341 self.worker.release('.*-merge')
342 self.waitUntilSettled()
343
344 self.assertEqual(len(self.builds), 6)
345 self.assertEqual(self.builds[0].name, 'project-test1')
346 self.assertEqual(self.builds[1].name, 'project-test2')
347 self.assertEqual(self.builds[2].name, 'project-test1')
348 self.assertEqual(self.builds[3].name, 'project-test2')
349 self.assertEqual(self.builds[4].name, 'project-test1')
350 self.assertEqual(self.builds[5].name, 'project-test2')
351
352 self.release(self.builds[2])
353 self.waitUntilSettled()
354
James E. Blair972e3c72013-08-29 12:04:55 -0700355 # project-test1 and project-test2 for A
356 # project-test2 for B
357 # project-merge for C (without B)
358 self.assertEqual(len(self.builds), 4)
James E. Blair0aac4872013-08-23 14:02:38 -0700359 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 2)
360
James E. Blair972e3c72013-08-29 12:04:55 -0700361 self.worker.release('.*-merge')
362 self.waitUntilSettled()
363
364 # project-test1 and project-test2 for A
365 # project-test2 for B
366 # project-test1 and project-test2 for C
367 self.assertEqual(len(self.builds), 5)
368
James E. Blair0aac4872013-08-23 14:02:38 -0700369 items = self.sched.layout.pipelines['gate'].getAllItems()
370 builds = items[0].current_build_set.getBuilds()
371 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
372 self.assertEqual(self.countJobResults(builds, None), 2)
373 builds = items[1].current_build_set.getBuilds()
374 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
375 self.assertEqual(self.countJobResults(builds, 'FAILURE'), 1)
376 self.assertEqual(self.countJobResults(builds, None), 1)
377 builds = items[2].current_build_set.getBuilds()
378 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
James E. Blair972e3c72013-08-29 12:04:55 -0700379 self.assertEqual(self.countJobResults(builds, None), 2)
James E. Blair0aac4872013-08-23 14:02:38 -0700380
381 self.worker.hold_jobs_in_build = False
382 self.worker.release()
383 self.waitUntilSettled()
384
385 self.assertEqual(len(self.builds), 0)
386 self.assertEqual(len(self.history), 12)
387 self.assertEqual(A.data['status'], 'MERGED')
388 self.assertEqual(B.data['status'], 'NEW')
389 self.assertEqual(C.data['status'], 'MERGED')
390 self.assertEqual(A.reported, 2)
391 self.assertEqual(B.reported, 2)
392 self.assertEqual(C.reported, 2)
393
James E. Blaird466dc42012-07-31 10:42:56 -0700394 def test_failed_change_at_head_with_queue(self):
395 "Test that if a change at the head fails, queued jobs are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700396
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700397 self.gearman_server.hold_jobs_in_queue = True
James E. Blaird466dc42012-07-31 10:42:56 -0700398 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
399 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
400 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700401 A.addApproval('CRVW', 2)
402 B.addApproval('CRVW', 2)
403 C.addApproval('CRVW', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700404
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700405 self.worker.addFailTest('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700406
407 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
408 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
409 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
410
411 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700412 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400413 self.assertEqual(len(self.builds), 0)
414 self.assertEqual(len(queue), 1)
415 self.assertEqual(queue[0].name, 'build:project-merge')
416 self.assertTrue(self.job_has_changes(queue[0], A))
James E. Blaird466dc42012-07-31 10:42:56 -0700417
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700418 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700419 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700420 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700421 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700422 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700423 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700424 queue = self.gearman_server.getQueue()
James E. Blaird466dc42012-07-31 10:42:56 -0700425
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400426 self.assertEqual(len(self.builds), 0)
427 self.assertEqual(len(queue), 6)
428 self.assertEqual(queue[0].name, 'build:project-test1')
429 self.assertEqual(queue[1].name, 'build:project-test2')
430 self.assertEqual(queue[2].name, 'build:project-test1')
431 self.assertEqual(queue[3].name, 'build:project-test2')
432 self.assertEqual(queue[4].name, 'build:project-test1')
433 self.assertEqual(queue[5].name, 'build:project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700434
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700435 self.release(queue[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700436 self.waitUntilSettled()
437
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400438 self.assertEqual(len(self.builds), 0)
James E. Blair701c5b42013-06-06 09:34:59 -0700439 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400440 self.assertEqual(len(queue), 2) # project-test2, project-merge for B
441 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 0)
James E. Blaird466dc42012-07-31 10:42:56 -0700442
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700443 self.gearman_server.hold_jobs_in_queue = False
444 self.gearman_server.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700445 self.waitUntilSettled()
446
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400447 self.assertEqual(len(self.builds), 0)
448 self.assertEqual(len(self.history), 11)
449 self.assertEqual(A.data['status'], 'NEW')
450 self.assertEqual(B.data['status'], 'MERGED')
451 self.assertEqual(C.data['status'], 'MERGED')
452 self.assertEqual(A.reported, 2)
453 self.assertEqual(B.reported, 2)
454 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700455
James E. Blairfef71632013-09-23 11:15:47 -0700456 def test_two_failed_changes_at_head(self):
457 "Test that changes are reparented correctly if 2 fail at head"
458
459 self.worker.hold_jobs_in_build = True
460 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
461 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
462 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
463 A.addApproval('CRVW', 2)
464 B.addApproval('CRVW', 2)
465 C.addApproval('CRVW', 2)
466
467 self.worker.addFailTest('project-test1', A)
468 self.worker.addFailTest('project-test1', B)
469
470 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
471 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
472 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
473 self.waitUntilSettled()
474
475 self.worker.release('.*-merge')
476 self.waitUntilSettled()
477 self.worker.release('.*-merge')
478 self.waitUntilSettled()
479 self.worker.release('.*-merge')
480 self.waitUntilSettled()
481
482 self.assertEqual(len(self.builds), 6)
483 self.assertEqual(self.builds[0].name, 'project-test1')
484 self.assertEqual(self.builds[1].name, 'project-test2')
485 self.assertEqual(self.builds[2].name, 'project-test1')
486 self.assertEqual(self.builds[3].name, 'project-test2')
487 self.assertEqual(self.builds[4].name, 'project-test1')
488 self.assertEqual(self.builds[5].name, 'project-test2')
489
490 self.assertTrue(self.job_has_changes(self.builds[0], A))
491 self.assertTrue(self.job_has_changes(self.builds[2], A))
492 self.assertTrue(self.job_has_changes(self.builds[2], B))
493 self.assertTrue(self.job_has_changes(self.builds[4], A))
494 self.assertTrue(self.job_has_changes(self.builds[4], B))
495 self.assertTrue(self.job_has_changes(self.builds[4], C))
496
497 # Fail change B first
498 self.release(self.builds[2])
499 self.waitUntilSettled()
500
501 # restart of C after B failure
502 self.worker.release('.*-merge')
503 self.waitUntilSettled()
504
505 self.assertEqual(len(self.builds), 5)
506 self.assertEqual(self.builds[0].name, 'project-test1')
507 self.assertEqual(self.builds[1].name, 'project-test2')
508 self.assertEqual(self.builds[2].name, 'project-test2')
509 self.assertEqual(self.builds[3].name, 'project-test1')
510 self.assertEqual(self.builds[4].name, 'project-test2')
511
512 self.assertTrue(self.job_has_changes(self.builds[1], A))
513 self.assertTrue(self.job_has_changes(self.builds[2], A))
514 self.assertTrue(self.job_has_changes(self.builds[2], B))
515 self.assertTrue(self.job_has_changes(self.builds[4], A))
516 self.assertFalse(self.job_has_changes(self.builds[4], B))
517 self.assertTrue(self.job_has_changes(self.builds[4], C))
518
519 # Finish running all passing jobs for change A
520 self.release(self.builds[1])
521 self.waitUntilSettled()
522 # Fail and report change A
523 self.release(self.builds[0])
524 self.waitUntilSettled()
525
526 # restart of B,C after A failure
527 self.worker.release('.*-merge')
528 self.waitUntilSettled()
529 self.worker.release('.*-merge')
530 self.waitUntilSettled()
531
532 self.assertEqual(len(self.builds), 4)
533 self.assertEqual(self.builds[0].name, 'project-test1') # B
534 self.assertEqual(self.builds[1].name, 'project-test2') # B
535 self.assertEqual(self.builds[2].name, 'project-test1') # C
536 self.assertEqual(self.builds[3].name, 'project-test2') # C
537
538 self.assertFalse(self.job_has_changes(self.builds[1], A))
539 self.assertTrue(self.job_has_changes(self.builds[1], B))
540 self.assertFalse(self.job_has_changes(self.builds[1], C))
541
542 self.assertFalse(self.job_has_changes(self.builds[2], A))
543 # After A failed and B and C restarted, B should be back in
544 # C's tests because it has not failed yet.
545 self.assertTrue(self.job_has_changes(self.builds[2], B))
546 self.assertTrue(self.job_has_changes(self.builds[2], C))
547
548 self.worker.hold_jobs_in_build = False
549 self.worker.release()
550 self.waitUntilSettled()
551
552 self.assertEqual(len(self.builds), 0)
553 self.assertEqual(len(self.history), 21)
554 self.assertEqual(A.data['status'], 'NEW')
555 self.assertEqual(B.data['status'], 'NEW')
556 self.assertEqual(C.data['status'], 'MERGED')
557 self.assertEqual(A.reported, 2)
558 self.assertEqual(B.reported, 2)
559 self.assertEqual(C.reported, 2)
560
James E. Blair8c803f82012-07-31 16:25:42 -0700561 def test_patch_order(self):
562 "Test that dependent patches are tested in the right order"
563 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
564 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
565 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
566 A.addApproval('CRVW', 2)
567 B.addApproval('CRVW', 2)
568 C.addApproval('CRVW', 2)
569
570 M2 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M2')
571 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
572 M2.setMerged()
573 M1.setMerged()
574
575 # C -> B -> A -> M1 -> M2
576 # M2 is here to make sure it is never queried. If it is, it
577 # means zuul is walking down the entire history of merged
578 # changes.
579
580 C.setDependsOn(B, 1)
581 B.setDependsOn(A, 1)
582 A.setDependsOn(M1, 1)
583 M1.setDependsOn(M2, 1)
584
585 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
586
587 self.waitUntilSettled()
588
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400589 self.assertEqual(A.data['status'], 'NEW')
590 self.assertEqual(B.data['status'], 'NEW')
591 self.assertEqual(C.data['status'], 'NEW')
James E. Blair8c803f82012-07-31 16:25:42 -0700592
593 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
594 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
595
596 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400597 self.assertEqual(M2.queried, 0)
598 self.assertEqual(A.data['status'], 'MERGED')
599 self.assertEqual(B.data['status'], 'MERGED')
600 self.assertEqual(C.data['status'], 'MERGED')
601 self.assertEqual(A.reported, 2)
602 self.assertEqual(B.reported, 2)
603 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700604
James E. Blair0e933c52013-07-11 10:18:52 -0700605 def test_trigger_cache(self):
606 "Test that the trigger cache operates correctly"
607 self.worker.hold_jobs_in_build = True
608
609 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
610 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
611 X = self.fake_gerrit.addFakeChange('org/project', 'master', 'X')
612 A.addApproval('CRVW', 2)
613 B.addApproval('CRVW', 2)
614
615 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
616 M1.setMerged()
617
618 B.setDependsOn(A, 1)
619 A.setDependsOn(M1, 1)
620
621 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
622 self.fake_gerrit.addEvent(X.getPatchsetCreatedEvent(1))
623
624 self.waitUntilSettled()
625
626 for build in self.builds:
627 if build.parameters['ZUUL_PIPELINE'] == 'check':
628 build.release()
629 self.waitUntilSettled()
630 for build in self.builds:
631 if build.parameters['ZUUL_PIPELINE'] == 'check':
632 build.release()
633 self.waitUntilSettled()
634
635 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
636 self.waitUntilSettled()
637
Antoine Mussof0506fa2014-06-03 15:03:38 +0200638 self.log.debug("len %s" % self.gerrit._change_cache.keys())
James E. Blair0e933c52013-07-11 10:18:52 -0700639 # there should still be changes in the cache
James E. Blair6c358e72013-07-29 17:06:47 -0700640 self.assertNotEqual(len(self.gerrit._change_cache.keys()), 0)
James E. Blair0e933c52013-07-11 10:18:52 -0700641
642 self.worker.hold_jobs_in_build = False
643 self.worker.release()
644 self.waitUntilSettled()
645
646 self.assertEqual(A.data['status'], 'MERGED')
647 self.assertEqual(B.data['status'], 'MERGED')
648 self.assertEqual(A.queried, 2) # Initial and isMerged
649 self.assertEqual(B.queried, 3) # Initial A, refresh from B, isMerged
650
James E. Blair8c803f82012-07-31 16:25:42 -0700651 def test_can_merge(self):
James E. Blair4886cc12012-07-18 15:39:41 -0700652 "Test whether a change is ready to merge"
James E. Blair8c803f82012-07-31 16:25:42 -0700653 # TODO: move to test_gerrit (this is a unit test!)
654 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair6c358e72013-07-29 17:06:47 -0700655 trigger = self.sched.layout.pipelines['gate'].trigger
656 a = self.sched.triggers['gerrit'].getChange(1, 2)
James E. Blaireff88162013-07-01 12:44:14 -0400657 mgr = self.sched.layout.pipelines['gate'].manager
James E. Blair6c358e72013-07-29 17:06:47 -0700658 self.assertFalse(trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700659
660 A.addApproval('CRVW', 2)
James E. Blair6c358e72013-07-29 17:06:47 -0700661 a = trigger.getChange(1, 2, refresh=True)
662 self.assertFalse(trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700663
664 A.addApproval('APRV', 1)
James E. Blair6c358e72013-07-29 17:06:47 -0700665 a = trigger.getChange(1, 2, refresh=True)
666 self.assertTrue(trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
667 trigger.maintainCache([])
James E. Blair4886cc12012-07-18 15:39:41 -0700668
James E. Blair11041d22014-05-02 14:49:53 -0700669 def test_pipeline_requirements_closed_change(self):
670 "Test that pipeline requirements for closed changes are effective"
671 self.config.set('zuul', 'layout_config',
672 'tests/fixtures/layout-pipeline-requirements.yaml')
673 self.sched.reconfigure(self.config)
674
675 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
676 status='MERGED')
677 self.fake_gerrit.addEvent(A.addApproval('CRVW', 2))
678 self.waitUntilSettled()
679 self.assertEqual(len(self.history), 0)
680 self.assertEqual(len(self.builds), 0)
681
682 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B',
683 status='MERGED')
684 B.addApproval('CRVW', 2)
685 B.addApproval('VRFY', 1)
686 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
687 self.waitUntilSettled()
688 self.assertEqual(len(self.history), 0)
689 self.assertEqual(len(self.builds), 0)
690
691 for pipeline in self.sched.layout.pipelines.values():
692 pipeline.trigger.maintainCache([])
693
James E. Blair4886cc12012-07-18 15:39:41 -0700694 def test_build_configuration(self):
695 "Test that zuul merges the right commits for testing"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700696
697 self.gearman_server.hold_jobs_in_queue = True
James E. Blair4886cc12012-07-18 15:39:41 -0700698 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
699 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
700 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
701 A.addApproval('CRVW', 2)
702 B.addApproval('CRVW', 2)
703 C.addApproval('CRVW', 2)
704 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
705 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
706 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
707 self.waitUntilSettled()
708
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700709 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700710 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700711 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700712 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700713 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700714 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700715 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700716 ref = self.getParameter(queue[-1], 'ZUUL_REF')
717 self.gearman_server.hold_jobs_in_queue = False
718 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700719 self.waitUntilSettled()
James E. Blair4886cc12012-07-18 15:39:41 -0700720
Monty Taylorbc758832013-06-17 17:22:42 -0400721 path = os.path.join(self.git_root, "org/project")
James E. Blair4886cc12012-07-18 15:39:41 -0700722 repo = git.Repo(path)
723 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
724 repo_messages.reverse()
James E. Blair4886cc12012-07-18 15:39:41 -0700725 correct_messages = ['initial commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400726 self.assertEqual(repo_messages, correct_messages)
James E. Blair973721f2012-08-15 10:19:43 -0700727
728 def test_build_configuration_conflict(self):
729 "Test that merge conflicts are handled"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700730
731 self.gearman_server.hold_jobs_in_queue = True
James E. Blair6736beb2013-07-11 15:18:15 -0700732 A = self.fake_gerrit.addFakeChange('org/conflict-project',
733 'master', 'A')
James E. Blair973721f2012-08-15 10:19:43 -0700734 A.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700735 B = self.fake_gerrit.addFakeChange('org/conflict-project',
736 'master', 'B')
James E. Blair973721f2012-08-15 10:19:43 -0700737 B.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700738 C = self.fake_gerrit.addFakeChange('org/conflict-project',
739 'master', 'C')
James E. Blair973721f2012-08-15 10:19:43 -0700740 A.addApproval('CRVW', 2)
741 B.addApproval('CRVW', 2)
742 C.addApproval('CRVW', 2)
743 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
744 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
745 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
746 self.waitUntilSettled()
747
James E. Blair6736beb2013-07-11 15:18:15 -0700748 self.assertEqual(A.reported, 1)
749 self.assertEqual(B.reported, 1)
750 self.assertEqual(C.reported, 1)
751
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700752 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700753 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700754 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700755 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700756 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700757 self.waitUntilSettled()
James E. Blair972e3c72013-08-29 12:04:55 -0700758
759 self.assertEqual(len(self.history), 2) # A and C merge jobs
760
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700761 self.gearman_server.hold_jobs_in_queue = False
762 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700763 self.waitUntilSettled()
764
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400765 self.assertEqual(A.data['status'], 'MERGED')
766 self.assertEqual(B.data['status'], 'NEW')
767 self.assertEqual(C.data['status'], 'MERGED')
768 self.assertEqual(A.reported, 2)
769 self.assertEqual(B.reported, 2)
770 self.assertEqual(C.reported, 2)
James E. Blair972e3c72013-08-29 12:04:55 -0700771 self.assertEqual(len(self.history), 6)
James E. Blair6736beb2013-07-11 15:18:15 -0700772
James E. Blairdaabed22012-08-15 15:38:57 -0700773 def test_post(self):
774 "Test that post jobs run"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700775
Zhongyue Luo5d556072012-09-21 02:00:47 +0900776 e = {
777 "type": "ref-updated",
778 "submitter": {
779 "name": "User Name",
780 },
781 "refUpdate": {
782 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
783 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
784 "refName": "master",
785 "project": "org/project",
786 }
787 }
James E. Blairdaabed22012-08-15 15:38:57 -0700788 self.fake_gerrit.addEvent(e)
789 self.waitUntilSettled()
790
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400791 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400792 self.assertEqual(len(self.history), 1)
793 self.assertIn('project-post', job_names)
James E. Blairc6294a52012-08-17 10:19:48 -0700794
795 def test_build_configuration_branch(self):
796 "Test that the right commits are on alternate branches"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700797
798 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -0700799 A = self.fake_gerrit.addFakeChange('org/project', 'mp', 'A')
800 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
801 C = self.fake_gerrit.addFakeChange('org/project', 'mp', 'C')
802 A.addApproval('CRVW', 2)
803 B.addApproval('CRVW', 2)
804 C.addApproval('CRVW', 2)
805 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
806 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
807 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
808 self.waitUntilSettled()
809
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700810 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -0700811 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700812 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -0700813 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700814 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -0700815 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700816 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700817 ref = self.getParameter(queue[-1], 'ZUUL_REF')
818 self.gearman_server.hold_jobs_in_queue = False
819 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -0700820 self.waitUntilSettled()
821
Monty Taylorbc758832013-06-17 17:22:42 -0400822 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -0700823 repo = git.Repo(path)
824 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
825 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -0700826 correct_messages = ['initial commit', 'mp commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400827 self.assertEqual(repo_messages, correct_messages)
James E. Blairc6294a52012-08-17 10:19:48 -0700828
829 def test_build_configuration_branch_interaction(self):
830 "Test that switching between branches works"
831 self.test_build_configuration()
832 self.test_build_configuration_branch()
833 # C has been merged, undo that
Monty Taylorbc758832013-06-17 17:22:42 -0400834 path = os.path.join(self.upstream_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -0700835 repo = git.Repo(path)
836 repo.heads.master.commit = repo.commit('init')
837 self.test_build_configuration()
838
839 def test_build_configuration_multi_branch(self):
840 "Test that dependent changes on multiple branches are merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700841
842 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -0700843 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
844 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
845 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
846 A.addApproval('CRVW', 2)
847 B.addApproval('CRVW', 2)
848 C.addApproval('CRVW', 2)
849 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
850 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
851 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
852 self.waitUntilSettled()
James E. Blairbb1fe502014-03-04 10:15:06 -0800853 queue = self.gearman_server.getQueue()
854 job_A = None
855 for job in queue:
856 if 'project-merge' in job.name:
857 job_A = job
858 ref_A = self.getParameter(job_A, 'ZUUL_REF')
859 commit_A = self.getParameter(job_A, 'ZUUL_COMMIT')
860 self.log.debug("Got Zuul ref for change A: %s" % ref_A)
861 self.log.debug("Got Zuul commit for change A: %s" % commit_A)
James E. Blairc6294a52012-08-17 10:19:48 -0700862
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700863 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -0700864 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700865 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -0700866 job_B = None
867 for job in queue:
868 if 'project-merge' in job.name:
869 job_B = job
870 ref_B = self.getParameter(job_B, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -0800871 commit_B = self.getParameter(job_B, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -0700872 self.log.debug("Got Zuul ref for change B: %s" % ref_B)
James E. Blairbb1fe502014-03-04 10:15:06 -0800873 self.log.debug("Got Zuul commit for change B: %s" % commit_B)
874
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700875 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -0700876 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700877 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -0700878 for job in queue:
879 if 'project-merge' in job.name:
880 job_C = job
881 ref_C = self.getParameter(job_C, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -0800882 commit_C = self.getParameter(job_C, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -0700883 self.log.debug("Got Zuul ref for change C: %s" % ref_C)
James E. Blairbb1fe502014-03-04 10:15:06 -0800884 self.log.debug("Got Zuul commit for change C: %s" % commit_C)
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700885 self.gearman_server.hold_jobs_in_queue = False
886 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -0700887 self.waitUntilSettled()
888
Monty Taylorbc758832013-06-17 17:22:42 -0400889 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -0700890 repo = git.Repo(path)
891
892 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -0700893 for c in repo.iter_commits(ref_C)]
James E. Blairbb1fe502014-03-04 10:15:06 -0800894 repo_shas = [c.hexsha for c in repo.iter_commits(ref_C)]
James E. Blairc6294a52012-08-17 10:19:48 -0700895 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -0700896 correct_messages = ['initial commit', 'A-1', 'C-1']
James E. Blairbb1fe502014-03-04 10:15:06 -0800897 # Ensure the right commits are in the history for this ref
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400898 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -0800899 # Ensure ZUUL_REF -> ZUUL_COMMIT
900 self.assertEqual(repo_shas[0], commit_C)
James E. Blairc6294a52012-08-17 10:19:48 -0700901
902 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -0700903 for c in repo.iter_commits(ref_B)]
James E. Blairbb1fe502014-03-04 10:15:06 -0800904 repo_shas = [c.hexsha for c in repo.iter_commits(ref_B)]
James E. Blairc6294a52012-08-17 10:19:48 -0700905 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -0700906 correct_messages = ['initial commit', 'mp commit', 'B-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400907 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -0800908 self.assertEqual(repo_shas[0], commit_B)
909
910 repo_messages = [c.message.strip()
911 for c in repo.iter_commits(ref_A)]
912 repo_shas = [c.hexsha for c in repo.iter_commits(ref_A)]
913 repo_messages.reverse()
914 correct_messages = ['initial commit', 'A-1']
915 self.assertEqual(repo_messages, correct_messages)
916 self.assertEqual(repo_shas[0], commit_A)
917
918 self.assertNotEqual(ref_A, ref_B, ref_C)
919 self.assertNotEqual(commit_A, commit_B, commit_C)
James E. Blair7f71c802012-08-22 13:04:32 -0700920
921 def test_one_job_project(self):
922 "Test that queueing works with one job"
923 A = self.fake_gerrit.addFakeChange('org/one-job-project',
924 'master', 'A')
925 B = self.fake_gerrit.addFakeChange('org/one-job-project',
926 'master', 'B')
927 A.addApproval('CRVW', 2)
928 B.addApproval('CRVW', 2)
929 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
930 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
931 self.waitUntilSettled()
932
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400933 self.assertEqual(A.data['status'], 'MERGED')
934 self.assertEqual(A.reported, 2)
935 self.assertEqual(B.data['status'], 'MERGED')
936 self.assertEqual(B.reported, 2)
James E. Blaircaec0c52012-08-22 14:52:22 -0700937
Antoine Musso80edd5a2013-02-13 15:37:53 +0100938 def test_job_from_templates_launched(self):
939 "Test whether a job generated via a template can be launched"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700940
Antoine Musso80edd5a2013-02-13 15:37:53 +0100941 A = self.fake_gerrit.addFakeChange(
942 'org/templated-project', 'master', 'A')
943 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
944 self.waitUntilSettled()
Antoine Musso80edd5a2013-02-13 15:37:53 +0100945
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400946 self.assertEqual(self.getJobFromHistory('project-test1').result,
947 'SUCCESS')
948 self.assertEqual(self.getJobFromHistory('project-test2').result,
949 'SUCCESS')
Antoine Musso80edd5a2013-02-13 15:37:53 +0100950
James E. Blair3e98c022013-12-16 15:25:38 -0800951 def test_layered_templates(self):
952 "Test whether a job generated via a template can be launched"
953
954 A = self.fake_gerrit.addFakeChange(
955 'org/layered-project', 'master', 'A')
956 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
957 self.waitUntilSettled()
958
959 self.assertEqual(self.getJobFromHistory('project-test1').result,
960 'SUCCESS')
961 self.assertEqual(self.getJobFromHistory('project-test2').result,
962 'SUCCESS')
James E. Blairaea6cf62013-12-16 15:38:12 -0800963 self.assertEqual(self.getJobFromHistory('layered-project-test3'
964 ).result, 'SUCCESS')
965 self.assertEqual(self.getJobFromHistory('layered-project-test4'
966 ).result, 'SUCCESS')
James E. Blair12a92b12014-03-26 11:54:53 -0700967 self.assertEqual(self.getJobFromHistory('layered-project-foo-test5'
968 ).result, 'SUCCESS')
James E. Blair3e98c022013-12-16 15:25:38 -0800969 self.assertEqual(self.getJobFromHistory('project-test6').result,
970 'SUCCESS')
971
James E. Blaircaec0c52012-08-22 14:52:22 -0700972 def test_dependent_changes_dequeue(self):
973 "Test that dependent patches are not needlessly tested"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700974
James E. Blaircaec0c52012-08-22 14:52:22 -0700975 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
976 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
977 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
978 A.addApproval('CRVW', 2)
979 B.addApproval('CRVW', 2)
980 C.addApproval('CRVW', 2)
981
982 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
983 M1.setMerged()
984
985 # C -> B -> A -> M1
986
987 C.setDependsOn(B, 1)
988 B.setDependsOn(A, 1)
989 A.setDependsOn(M1, 1)
990
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700991 self.worker.addFailTest('project-merge', A)
James E. Blaircaec0c52012-08-22 14:52:22 -0700992
993 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
994 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
995 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
996
997 self.waitUntilSettled()
998
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400999 self.assertEqual(A.data['status'], 'NEW')
1000 self.assertEqual(A.reported, 2)
1001 self.assertEqual(B.data['status'], 'NEW')
1002 self.assertEqual(B.reported, 2)
1003 self.assertEqual(C.data['status'], 'NEW')
1004 self.assertEqual(C.reported, 2)
1005 self.assertEqual(len(self.history), 1)
James E. Blairec590122012-08-22 15:19:31 -07001006
James E. Blair972e3c72013-08-29 12:04:55 -07001007 def test_failing_dependent_changes(self):
1008 "Test that failing dependent patches are taken out of stream"
1009 self.worker.hold_jobs_in_build = True
1010 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1011 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1012 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1013 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1014 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
1015 A.addApproval('CRVW', 2)
1016 B.addApproval('CRVW', 2)
1017 C.addApproval('CRVW', 2)
1018 D.addApproval('CRVW', 2)
1019 E.addApproval('CRVW', 2)
1020
1021 # E, D -> C -> B, A
1022
1023 D.setDependsOn(C, 1)
1024 C.setDependsOn(B, 1)
1025
1026 self.worker.addFailTest('project-test1', B)
1027
1028 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1029 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1030 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1031 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1032 self.fake_gerrit.addEvent(E.addApproval('APRV', 1))
1033
1034 self.waitUntilSettled()
1035 self.worker.release('.*-merge')
1036 self.waitUntilSettled()
1037 self.worker.release('.*-merge')
1038 self.waitUntilSettled()
1039 self.worker.release('.*-merge')
1040 self.waitUntilSettled()
1041 self.worker.release('.*-merge')
1042 self.waitUntilSettled()
1043 self.worker.release('.*-merge')
1044 self.waitUntilSettled()
1045
1046 self.worker.hold_jobs_in_build = False
1047 for build in self.builds:
1048 if build.parameters['ZUUL_CHANGE'] != '1':
1049 build.release()
1050 self.waitUntilSettled()
1051
1052 self.worker.release()
1053 self.waitUntilSettled()
1054
1055 self.assertEqual(A.data['status'], 'MERGED')
1056 self.assertEqual(A.reported, 2)
1057 self.assertEqual(B.data['status'], 'NEW')
1058 self.assertEqual(B.reported, 2)
1059 self.assertEqual(C.data['status'], 'NEW')
1060 self.assertEqual(C.reported, 2)
1061 self.assertEqual(D.data['status'], 'NEW')
1062 self.assertEqual(D.reported, 2)
1063 self.assertEqual(E.data['status'], 'MERGED')
1064 self.assertEqual(E.reported, 2)
1065 self.assertEqual(len(self.history), 18)
1066
James E. Blairec590122012-08-22 15:19:31 -07001067 def test_head_is_dequeued_once(self):
James E. Blair2fa50962013-01-30 21:50:41 -08001068 "Test that if a change at the head fails it is dequeued only once"
James E. Blairec590122012-08-22 15:19:31 -07001069 # If it's dequeued more than once, we should see extra
1070 # aborted jobs.
James E. Blairec590122012-08-22 15:19:31 -07001071
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001072 self.worker.hold_jobs_in_build = True
James E. Blairec590122012-08-22 15:19:31 -07001073 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1074 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1075 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
1076 A.addApproval('CRVW', 2)
1077 B.addApproval('CRVW', 2)
1078 C.addApproval('CRVW', 2)
1079
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001080 self.worker.addFailTest('project1-test1', A)
1081 self.worker.addFailTest('project1-test2', A)
1082 self.worker.addFailTest('project1-project2-integration', A)
James E. Blairec590122012-08-22 15:19:31 -07001083
1084 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1085 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1086 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1087
1088 self.waitUntilSettled()
James E. Blairec590122012-08-22 15:19:31 -07001089
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001090 self.assertEqual(len(self.builds), 1)
1091 self.assertEqual(self.builds[0].name, 'project1-merge')
1092 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blairec590122012-08-22 15:19:31 -07001093
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001094 self.worker.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001095 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001096 self.worker.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001097 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001098 self.worker.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001099 self.waitUntilSettled()
1100
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001101 self.assertEqual(len(self.builds), 9)
1102 self.assertEqual(self.builds[0].name, 'project1-test1')
1103 self.assertEqual(self.builds[1].name, 'project1-test2')
1104 self.assertEqual(self.builds[2].name, 'project1-project2-integration')
1105 self.assertEqual(self.builds[3].name, 'project1-test1')
1106 self.assertEqual(self.builds[4].name, 'project1-test2')
1107 self.assertEqual(self.builds[5].name, 'project1-project2-integration')
1108 self.assertEqual(self.builds[6].name, 'project1-test1')
1109 self.assertEqual(self.builds[7].name, 'project1-test2')
1110 self.assertEqual(self.builds[8].name, 'project1-project2-integration')
James E. Blairec590122012-08-22 15:19:31 -07001111
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001112 self.release(self.builds[0])
James E. Blairec590122012-08-22 15:19:31 -07001113 self.waitUntilSettled()
1114
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001115 self.assertEqual(len(self.builds), 3) # test2,integration, merge for B
1116 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 6)
James E. Blairec590122012-08-22 15:19:31 -07001117
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001118 self.worker.hold_jobs_in_build = False
1119 self.worker.release()
James E. Blairec590122012-08-22 15:19:31 -07001120 self.waitUntilSettled()
1121
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001122 self.assertEqual(len(self.builds), 0)
1123 self.assertEqual(len(self.history), 20)
James E. Blaircaec0c52012-08-22 14:52:22 -07001124
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001125 self.assertEqual(A.data['status'], 'NEW')
1126 self.assertEqual(B.data['status'], 'MERGED')
1127 self.assertEqual(C.data['status'], 'MERGED')
1128 self.assertEqual(A.reported, 2)
1129 self.assertEqual(B.reported, 2)
1130 self.assertEqual(C.reported, 2)
James E. Blair4ec821f2012-08-23 15:28:28 -07001131
1132 def test_nonvoting_job(self):
1133 "Test that non-voting jobs don't vote."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001134
James E. Blair4ec821f2012-08-23 15:28:28 -07001135 A = self.fake_gerrit.addFakeChange('org/nonvoting-project',
1136 'master', 'A')
1137 A.addApproval('CRVW', 2)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001138 self.worker.addFailTest('nonvoting-project-test2', A)
James E. Blair4ec821f2012-08-23 15:28:28 -07001139 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1140
1141 self.waitUntilSettled()
James E. Blair4ec821f2012-08-23 15:28:28 -07001142
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001143 self.assertEqual(A.data['status'], 'MERGED')
1144 self.assertEqual(A.reported, 2)
1145 self.assertEqual(
1146 self.getJobFromHistory('nonvoting-project-merge').result,
1147 'SUCCESS')
1148 self.assertEqual(
1149 self.getJobFromHistory('nonvoting-project-test1').result,
1150 'SUCCESS')
1151 self.assertEqual(
1152 self.getJobFromHistory('nonvoting-project-test2').result,
1153 'FAILURE')
James E. Blaire0487072012-08-29 17:38:31 -07001154
1155 def test_check_queue_success(self):
1156 "Test successful check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001157
James E. Blaire0487072012-08-29 17:38:31 -07001158 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1159 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1160
1161 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001162
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001163 self.assertEqual(A.data['status'], 'NEW')
1164 self.assertEqual(A.reported, 1)
1165 self.assertEqual(self.getJobFromHistory('project-merge').result,
1166 'SUCCESS')
1167 self.assertEqual(self.getJobFromHistory('project-test1').result,
1168 'SUCCESS')
1169 self.assertEqual(self.getJobFromHistory('project-test2').result,
1170 'SUCCESS')
James E. Blaire0487072012-08-29 17:38:31 -07001171
1172 def test_check_queue_failure(self):
1173 "Test failed check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001174
James E. Blaire0487072012-08-29 17:38:31 -07001175 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001176 self.worker.addFailTest('project-test2', A)
James E. Blaire0487072012-08-29 17:38:31 -07001177 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1178
1179 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001180
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001181 self.assertEqual(A.data['status'], 'NEW')
1182 self.assertEqual(A.reported, 1)
1183 self.assertEqual(self.getJobFromHistory('project-merge').result,
James E. Blair78e31b32013-07-09 09:11:34 -07001184 'SUCCESS')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001185 self.assertEqual(self.getJobFromHistory('project-test1').result,
1186 'SUCCESS')
1187 self.assertEqual(self.getJobFromHistory('project-test2').result,
1188 'FAILURE')
James E. Blair127bc182012-08-28 15:55:15 -07001189
1190 def test_dependent_behind_dequeue(self):
1191 "test that dependent changes behind dequeued changes work"
1192 # This complicated test is a reproduction of a real life bug
1193 self.sched.reconfigure(self.config)
James E. Blair127bc182012-08-28 15:55:15 -07001194
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001195 self.worker.hold_jobs_in_build = True
James E. Blair127bc182012-08-28 15:55:15 -07001196 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1197 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1198 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
1199 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
1200 E = self.fake_gerrit.addFakeChange('org/project2', 'master', 'E')
1201 F = self.fake_gerrit.addFakeChange('org/project3', 'master', 'F')
1202 D.setDependsOn(C, 1)
1203 E.setDependsOn(D, 1)
1204 A.addApproval('CRVW', 2)
1205 B.addApproval('CRVW', 2)
1206 C.addApproval('CRVW', 2)
1207 D.addApproval('CRVW', 2)
1208 E.addApproval('CRVW', 2)
1209 F.addApproval('CRVW', 2)
1210
1211 A.fail_merge = True
James E. Blair127bc182012-08-28 15:55:15 -07001212
1213 # Change object re-use in the gerrit trigger is hidden if
1214 # changes are added in quick succession; waiting makes it more
1215 # like real life.
1216 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1217 self.waitUntilSettled()
1218 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1219 self.waitUntilSettled()
1220
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001221 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001222 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001223 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001224 self.waitUntilSettled()
1225
1226 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1227 self.waitUntilSettled()
1228 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1229 self.waitUntilSettled()
1230 self.fake_gerrit.addEvent(E.addApproval('APRV', 1))
1231 self.waitUntilSettled()
1232 self.fake_gerrit.addEvent(F.addApproval('APRV', 1))
1233 self.waitUntilSettled()
1234
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001235 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001236 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001237 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001238 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001239 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001240 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001241 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001242 self.waitUntilSettled()
1243
1244 # all jobs running
James E. Blaire955e062012-10-08 09:49:03 -07001245
1246 # Grab pointers to the jobs we want to release before
1247 # releasing any, because list indexes may change as
1248 # the jobs complete.
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001249 a, b, c = self.builds[:3]
James E. Blaire955e062012-10-08 09:49:03 -07001250 a.release()
1251 b.release()
1252 c.release()
James E. Blair127bc182012-08-28 15:55:15 -07001253 self.waitUntilSettled()
1254
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001255 self.worker.hold_jobs_in_build = False
1256 self.worker.release()
James E. Blair127bc182012-08-28 15:55:15 -07001257 self.waitUntilSettled()
1258
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001259 self.assertEqual(A.data['status'], 'NEW')
1260 self.assertEqual(B.data['status'], 'MERGED')
1261 self.assertEqual(C.data['status'], 'MERGED')
1262 self.assertEqual(D.data['status'], 'MERGED')
1263 self.assertEqual(E.data['status'], 'MERGED')
1264 self.assertEqual(F.data['status'], 'MERGED')
James E. Blair127bc182012-08-28 15:55:15 -07001265
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001266 self.assertEqual(A.reported, 2)
1267 self.assertEqual(B.reported, 2)
1268 self.assertEqual(C.reported, 2)
1269 self.assertEqual(D.reported, 2)
1270 self.assertEqual(E.reported, 2)
1271 self.assertEqual(F.reported, 2)
James E. Blair127bc182012-08-28 15:55:15 -07001272
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001273 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 15)
1274 self.assertEqual(len(self.history), 44)
James E. Blair05fed602012-09-07 12:45:24 -07001275
1276 def test_merger_repack(self):
1277 "Test that the merger works after a repack"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001278
James E. Blair05fed602012-09-07 12:45:24 -07001279 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1280 A.addApproval('CRVW', 2)
1281 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1282 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001283 self.assertEqual(self.getJobFromHistory('project-merge').result,
1284 'SUCCESS')
1285 self.assertEqual(self.getJobFromHistory('project-test1').result,
1286 'SUCCESS')
1287 self.assertEqual(self.getJobFromHistory('project-test2').result,
1288 'SUCCESS')
1289 self.assertEqual(A.data['status'], 'MERGED')
1290 self.assertEqual(A.reported, 2)
James E. Blair05fed602012-09-07 12:45:24 -07001291 self.assertEmptyQueues()
James E. Blair4ca985f2013-05-30 12:27:43 -07001292 self.worker.build_history = []
James E. Blair05fed602012-09-07 12:45:24 -07001293
Monty Taylorbc758832013-06-17 17:22:42 -04001294 path = os.path.join(self.git_root, "org/project")
1295 print repack_repo(path)
James E. Blair05fed602012-09-07 12:45:24 -07001296
1297 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1298 A.addApproval('CRVW', 2)
1299 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1300 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001301 self.assertEqual(self.getJobFromHistory('project-merge').result,
1302 'SUCCESS')
1303 self.assertEqual(self.getJobFromHistory('project-test1').result,
1304 'SUCCESS')
1305 self.assertEqual(self.getJobFromHistory('project-test2').result,
1306 'SUCCESS')
1307 self.assertEqual(A.data['status'], 'MERGED')
1308 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001309
James E. Blair4886f282012-11-15 09:27:33 -08001310 def test_merger_repack_large_change(self):
1311 "Test that the merger works with large changes after a repack"
1312 # https://bugs.launchpad.net/zuul/+bug/1078946
James E. Blairac2c3242014-01-24 13:38:51 -08001313 # This test assumes the repo is already cloned; make sure it is
1314 url = self.sched.triggers['gerrit'].getGitUrl(
1315 self.sched.layout.projects['org/project1'])
James E. Blair4076e2b2014-01-28 12:42:20 -08001316 self.merge_server.merger.addProject('org/project1', url)
James E. Blair4886f282012-11-15 09:27:33 -08001317 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1318 A.addPatchset(large=True)
Monty Taylorbc758832013-06-17 17:22:42 -04001319 path = os.path.join(self.upstream_root, "org/project1")
1320 print repack_repo(path)
1321 path = os.path.join(self.git_root, "org/project1")
1322 print repack_repo(path)
James E. Blair4886f282012-11-15 09:27:33 -08001323
1324 A.addApproval('CRVW', 2)
1325 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1326 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001327 self.assertEqual(self.getJobFromHistory('project1-merge').result,
1328 'SUCCESS')
1329 self.assertEqual(self.getJobFromHistory('project1-test1').result,
1330 'SUCCESS')
1331 self.assertEqual(self.getJobFromHistory('project1-test2').result,
1332 'SUCCESS')
1333 self.assertEqual(A.data['status'], 'MERGED')
1334 self.assertEqual(A.reported, 2)
James E. Blair4886f282012-11-15 09:27:33 -08001335
James E. Blair7ee88a22012-09-12 18:59:31 +02001336 def test_nonexistent_job(self):
1337 "Test launching a job that doesn't exist"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001338 # Set to the state immediately after a restart
1339 self.resetGearmanServer()
1340 self.launcher.negative_function_cache_ttl = 0
James E. Blair7ee88a22012-09-12 18:59:31 +02001341
1342 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1343 A.addApproval('CRVW', 2)
1344 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1345 # There may be a thread about to report a lost change
1346 while A.reported < 2:
1347 self.waitUntilSettled()
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001348 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001349 self.assertFalse(job_names)
1350 self.assertEqual(A.data['status'], 'NEW')
1351 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001352 self.assertEmptyQueues()
1353
1354 # Make sure things still work:
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001355 self.registerJobs()
James E. Blair7ee88a22012-09-12 18:59:31 +02001356 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1357 A.addApproval('CRVW', 2)
1358 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1359 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001360 self.assertEqual(self.getJobFromHistory('project-merge').result,
1361 'SUCCESS')
1362 self.assertEqual(self.getJobFromHistory('project-test1').result,
1363 'SUCCESS')
1364 self.assertEqual(self.getJobFromHistory('project-test2').result,
1365 'SUCCESS')
1366 self.assertEqual(A.data['status'], 'MERGED')
1367 self.assertEqual(A.reported, 2)
James E. Blairf62d4282012-12-31 17:01:50 -08001368
1369 def test_single_nonexistent_post_job(self):
1370 "Test launching a single post job that doesn't exist"
James E. Blairf62d4282012-12-31 17:01:50 -08001371 e = {
1372 "type": "ref-updated",
1373 "submitter": {
1374 "name": "User Name",
1375 },
1376 "refUpdate": {
1377 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
1378 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
1379 "refName": "master",
1380 "project": "org/project",
1381 }
1382 }
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001383 # Set to the state immediately after a restart
1384 self.resetGearmanServer()
1385 self.launcher.negative_function_cache_ttl = 0
1386
James E. Blairf62d4282012-12-31 17:01:50 -08001387 self.fake_gerrit.addEvent(e)
1388 self.waitUntilSettled()
1389
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001390 self.assertEqual(len(self.history), 0)
James E. Blair2fa50962013-01-30 21:50:41 -08001391
1392 def test_new_patchset_dequeues_old(self):
1393 "Test that a new patchset causes the old to be dequeued"
1394 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001395 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001396 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1397 M.setMerged()
1398
1399 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1400 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1401 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1402 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1403 A.addApproval('CRVW', 2)
1404 B.addApproval('CRVW', 2)
1405 C.addApproval('CRVW', 2)
1406 D.addApproval('CRVW', 2)
1407
1408 C.setDependsOn(B, 1)
1409 B.setDependsOn(A, 1)
1410 A.setDependsOn(M, 1)
1411
1412 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1413 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1414 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1415 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1416 self.waitUntilSettled()
1417
1418 B.addPatchset()
1419 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1420 self.waitUntilSettled()
1421
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001422 self.worker.hold_jobs_in_build = False
1423 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001424 self.waitUntilSettled()
1425
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001426 self.assertEqual(A.data['status'], 'MERGED')
1427 self.assertEqual(A.reported, 2)
1428 self.assertEqual(B.data['status'], 'NEW')
1429 self.assertEqual(B.reported, 2)
1430 self.assertEqual(C.data['status'], 'NEW')
1431 self.assertEqual(C.reported, 2)
1432 self.assertEqual(D.data['status'], 'MERGED')
1433 self.assertEqual(D.reported, 2)
1434 self.assertEqual(len(self.history), 9) # 3 each for A, B, D.
James E. Blair2fa50962013-01-30 21:50:41 -08001435
Arx Cruzb1b010d2013-10-28 19:49:59 -02001436 def test_zuul_url_return(self):
1437 "Test if ZUUL_URL is returning when zuul_url is set in zuul.conf"
James E. Blair4076e2b2014-01-28 12:42:20 -08001438 self.assertTrue(self.sched.config.has_option('merger', 'zuul_url'))
Arx Cruzb1b010d2013-10-28 19:49:59 -02001439 self.worker.hold_jobs_in_build = True
1440
1441 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1442 A.addApproval('CRVW', 2)
1443 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1444 self.waitUntilSettled()
1445
1446 self.assertEqual(len(self.builds), 1)
1447 for build in self.builds:
1448 self.assertTrue('ZUUL_URL' in build.parameters)
1449
1450 self.worker.hold_jobs_in_build = False
1451 self.worker.release()
1452 self.waitUntilSettled()
1453
James E. Blair2fa50962013-01-30 21:50:41 -08001454 def test_new_patchset_dequeues_old_on_head(self):
1455 "Test that a new patchset causes the old to be dequeued (at head)"
1456 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001457 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001458 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1459 M.setMerged()
1460 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1461 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1462 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1463 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1464 A.addApproval('CRVW', 2)
1465 B.addApproval('CRVW', 2)
1466 C.addApproval('CRVW', 2)
1467 D.addApproval('CRVW', 2)
1468
1469 C.setDependsOn(B, 1)
1470 B.setDependsOn(A, 1)
1471 A.setDependsOn(M, 1)
1472
1473 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1474 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1475 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1476 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1477 self.waitUntilSettled()
1478
1479 A.addPatchset()
1480 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1481 self.waitUntilSettled()
1482
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001483 self.worker.hold_jobs_in_build = False
1484 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001485 self.waitUntilSettled()
1486
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001487 self.assertEqual(A.data['status'], 'NEW')
1488 self.assertEqual(A.reported, 2)
1489 self.assertEqual(B.data['status'], 'NEW')
1490 self.assertEqual(B.reported, 2)
1491 self.assertEqual(C.data['status'], 'NEW')
1492 self.assertEqual(C.reported, 2)
1493 self.assertEqual(D.data['status'], 'MERGED')
1494 self.assertEqual(D.reported, 2)
1495 self.assertEqual(len(self.history), 7)
James E. Blair2fa50962013-01-30 21:50:41 -08001496
1497 def test_new_patchset_dequeues_old_without_dependents(self):
1498 "Test that a new patchset causes only the old to be dequeued"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001499 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001500 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1501 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1502 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1503 A.addApproval('CRVW', 2)
1504 B.addApproval('CRVW', 2)
1505 C.addApproval('CRVW', 2)
1506
1507 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1508 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1509 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1510 self.waitUntilSettled()
1511
1512 B.addPatchset()
1513 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1514 self.waitUntilSettled()
1515
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001516 self.worker.hold_jobs_in_build = False
1517 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001518 self.waitUntilSettled()
1519
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001520 self.assertEqual(A.data['status'], 'MERGED')
1521 self.assertEqual(A.reported, 2)
1522 self.assertEqual(B.data['status'], 'NEW')
1523 self.assertEqual(B.reported, 2)
1524 self.assertEqual(C.data['status'], 'MERGED')
1525 self.assertEqual(C.reported, 2)
1526 self.assertEqual(len(self.history), 9)
James E. Blair2fa50962013-01-30 21:50:41 -08001527
1528 def test_new_patchset_dequeues_old_independent_queue(self):
1529 "Test that a new patchset causes the old to be dequeued (independent)"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001530 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001531 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1532 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1533 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1534 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1535 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1536 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
1537 self.waitUntilSettled()
1538
1539 B.addPatchset()
1540 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1541 self.waitUntilSettled()
1542
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001543 self.worker.hold_jobs_in_build = False
1544 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001545 self.waitUntilSettled()
1546
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001547 self.assertEqual(A.data['status'], 'NEW')
1548 self.assertEqual(A.reported, 1)
1549 self.assertEqual(B.data['status'], 'NEW')
1550 self.assertEqual(B.reported, 1)
1551 self.assertEqual(C.data['status'], 'NEW')
1552 self.assertEqual(C.reported, 1)
1553 self.assertEqual(len(self.history), 10)
1554 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 1)
James E. Blair7d0dedc2013-02-21 17:26:09 -08001555
James E. Blair18c64442014-03-18 10:14:45 -07001556 def test_noop_job(self):
1557 "Test that the internal noop job works"
1558 A = self.fake_gerrit.addFakeChange('org/noop-project', 'master', 'A')
1559 A.addApproval('CRVW', 2)
1560 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1561 self.waitUntilSettled()
1562
1563 self.assertEqual(len(self.gearman_server.getQueue()), 0)
1564 self.assertTrue(self.sched._areAllBuildsComplete())
1565 self.assertEqual(len(self.history), 0)
1566 self.assertEqual(A.data['status'], 'MERGED')
1567 self.assertEqual(A.reported, 2)
1568
James E. Blair7d0dedc2013-02-21 17:26:09 -08001569 def test_zuul_refs(self):
1570 "Test that zuul refs exist and have the right changes"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001571 self.worker.hold_jobs_in_build = True
James E. Blair7d0dedc2013-02-21 17:26:09 -08001572 M1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'M1')
1573 M1.setMerged()
1574 M2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'M2')
1575 M2.setMerged()
1576
1577 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1578 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1579 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
1580 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
1581 A.addApproval('CRVW', 2)
1582 B.addApproval('CRVW', 2)
1583 C.addApproval('CRVW', 2)
1584 D.addApproval('CRVW', 2)
1585 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1586 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1587 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1588 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1589
1590 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001591 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08001592 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001593 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08001594 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001595 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08001596 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001597 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08001598 self.waitUntilSettled()
1599
James E. Blair7d0dedc2013-02-21 17:26:09 -08001600 a_zref = b_zref = c_zref = d_zref = None
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001601 for x in self.builds:
James E. Blair7d0dedc2013-02-21 17:26:09 -08001602 if x.parameters['ZUUL_CHANGE'] == '3':
1603 a_zref = x.parameters['ZUUL_REF']
1604 if x.parameters['ZUUL_CHANGE'] == '4':
1605 b_zref = x.parameters['ZUUL_REF']
1606 if x.parameters['ZUUL_CHANGE'] == '5':
1607 c_zref = x.parameters['ZUUL_REF']
1608 if x.parameters['ZUUL_CHANGE'] == '6':
1609 d_zref = x.parameters['ZUUL_REF']
1610
1611 # There are... four... refs.
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001612 self.assertIsNotNone(a_zref)
1613 self.assertIsNotNone(b_zref)
1614 self.assertIsNotNone(c_zref)
1615 self.assertIsNotNone(d_zref)
James E. Blair7d0dedc2013-02-21 17:26:09 -08001616
1617 # And they should all be different
1618 refs = set([a_zref, b_zref, c_zref, d_zref])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001619 self.assertEqual(len(refs), 4)
James E. Blair7d0dedc2013-02-21 17:26:09 -08001620
1621 # a ref should have a, not b, and should not be in project2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001622 self.assertTrue(self.ref_has_change(a_zref, A))
1623 self.assertFalse(self.ref_has_change(a_zref, B))
1624 self.assertFalse(self.ref_has_change(a_zref, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08001625
1626 # b ref should have a and b, and should not be in project2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001627 self.assertTrue(self.ref_has_change(b_zref, A))
1628 self.assertTrue(self.ref_has_change(b_zref, B))
1629 self.assertFalse(self.ref_has_change(b_zref, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08001630
1631 # c ref should have a and b in 1, c in 2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001632 self.assertTrue(self.ref_has_change(c_zref, A))
1633 self.assertTrue(self.ref_has_change(c_zref, B))
1634 self.assertTrue(self.ref_has_change(c_zref, C))
1635 self.assertFalse(self.ref_has_change(c_zref, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08001636
1637 # d ref should have a and b in 1, c and d in 2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001638 self.assertTrue(self.ref_has_change(d_zref, A))
1639 self.assertTrue(self.ref_has_change(d_zref, B))
1640 self.assertTrue(self.ref_has_change(d_zref, C))
1641 self.assertTrue(self.ref_has_change(d_zref, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08001642
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001643 self.worker.hold_jobs_in_build = False
1644 self.worker.release()
James E. Blair7d0dedc2013-02-21 17:26:09 -08001645 self.waitUntilSettled()
1646
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001647 self.assertEqual(A.data['status'], 'MERGED')
1648 self.assertEqual(A.reported, 2)
1649 self.assertEqual(B.data['status'], 'MERGED')
1650 self.assertEqual(B.reported, 2)
1651 self.assertEqual(C.data['status'], 'MERGED')
1652 self.assertEqual(C.reported, 2)
1653 self.assertEqual(D.data['status'], 'MERGED')
1654 self.assertEqual(D.reported, 2)
James E. Blair70c71582013-03-06 08:50:50 -08001655
James E. Blair11041d22014-05-02 14:49:53 -07001656 def test_pipeline_requirements_approval_check_and_gate(self):
1657 "Test pipeline requirements triggers both check and gate"
1658 self.config.set('zuul', 'layout_config',
1659 'tests/fixtures/layout-pipeline-requirements.yaml')
1660 self.sched.reconfigure(self.config)
1661 self.registerJobs()
1662 self._test_required_approval_check_and_gate()
1663
James E. Blairc053d022014-01-22 14:57:33 -08001664 def test_required_approval_check_and_gate(self):
1665 "Test required-approval triggers both check and gate"
1666 self.config.set('zuul', 'layout_config',
1667 'tests/fixtures/layout-require-approval.yaml')
1668 self.sched.reconfigure(self.config)
1669 self.registerJobs()
James E. Blair11041d22014-05-02 14:49:53 -07001670 self._test_required_approval_check_and_gate()
James E. Blairc053d022014-01-22 14:57:33 -08001671
James E. Blair11041d22014-05-02 14:49:53 -07001672 def _test_required_approval_check_and_gate(self):
James E. Blairc053d022014-01-22 14:57:33 -08001673 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1674 A.addApproval('CRVW', 2)
1675 # Add a too-old +1
1676 A.addApproval('VRFY', 1, granted_on=time.time() - 72 * 60 * 60)
1677
1678 aprv = A.addApproval('APRV', 1)
1679 self.fake_gerrit.addEvent(aprv)
1680 self.waitUntilSettled()
1681 # Should have run a check job
1682 self.assertEqual(len(self.history), 1)
1683 self.assertEqual(self.history[0].name, 'project-check')
1684
1685 # Report the result of that check job (overrides previous vrfy)
1686 # Skynet alert: this should trigger a gate job now that
1687 # all reqs are met
1688 self.fake_gerrit.addEvent(A.addApproval('VRFY', 1))
1689 self.waitUntilSettled()
1690 self.assertEqual(len(self.history), 2)
1691 self.assertEqual(self.history[1].name, 'project-gate')
1692
James E. Blair11041d22014-05-02 14:49:53 -07001693 def test_pipeline_requirements_approval_newer(self):
1694 "Test pipeline requirements newer trigger parameter"
1695 self.config.set('zuul', 'layout_config',
1696 'tests/fixtures/layout-pipeline-requirements.yaml')
1697 self.sched.reconfigure(self.config)
1698 self.registerJobs()
1699 self._test_required_approval_newer()
1700
James E. Blairc053d022014-01-22 14:57:33 -08001701 def test_required_approval_newer(self):
1702 "Test required-approval newer trigger parameter"
1703 self.config.set('zuul', 'layout_config',
1704 'tests/fixtures/layout-require-approval.yaml')
1705 self.sched.reconfigure(self.config)
1706 self.registerJobs()
James E. Blair11041d22014-05-02 14:49:53 -07001707 self._test_required_approval_newer()
1708
1709 def _test_required_approval_newer(self):
1710 self.config.set('zuul', 'layout_config',
1711 'tests/fixtures/layout-require-approval.yaml')
1712 self.sched.reconfigure(self.config)
1713 self.registerJobs()
James E. Blairc053d022014-01-22 14:57:33 -08001714
1715 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1716 A.addApproval('CRVW', 2)
1717 aprv = A.addApproval('APRV', 1)
1718 self.fake_gerrit.addEvent(aprv)
1719 self.waitUntilSettled()
1720 # No +1 from Jenkins so should not be enqueued
1721 self.assertEqual(len(self.history), 0)
1722
1723 # Add a too-old +1, should trigger check but not gate
1724 A.addApproval('VRFY', 1, granted_on=time.time() - 72 * 60 * 60)
1725 self.fake_gerrit.addEvent(aprv)
1726 self.waitUntilSettled()
1727 self.assertEqual(len(self.history), 1)
1728 self.assertEqual(self.history[0].name, 'project-check')
1729
1730 # Add a recent +1
1731 self.fake_gerrit.addEvent(A.addApproval('VRFY', 1))
1732 self.fake_gerrit.addEvent(aprv)
1733 self.waitUntilSettled()
1734 self.assertEqual(len(self.history), 2)
1735 self.assertEqual(self.history[1].name, 'project-gate')
1736
James E. Blair11041d22014-05-02 14:49:53 -07001737 def test_pipeline_requirements_approval_older(self):
1738 "Test pipeline requirements older trigger parameter"
1739 self.config.set('zuul', 'layout_config',
1740 'tests/fixtures/layout-pipeline-requirements.yaml')
1741 self.sched.reconfigure(self.config)
1742 self.registerJobs()
1743 self._test_required_approval_older()
1744
James E. Blairc053d022014-01-22 14:57:33 -08001745 def test_required_approval_older(self):
1746 "Test required-approval older trigger parameter"
1747 self.config.set('zuul', 'layout_config',
1748 'tests/fixtures/layout-require-approval.yaml')
1749 self.sched.reconfigure(self.config)
1750 self.registerJobs()
James E. Blair11041d22014-05-02 14:49:53 -07001751 self._test_required_approval_older()
1752
1753 def _test_required_approval_older(self):
1754 self.config.set('zuul', 'layout_config',
1755 'tests/fixtures/layout-require-approval.yaml')
1756 self.sched.reconfigure(self.config)
1757 self.registerJobs()
James E. Blairc053d022014-01-22 14:57:33 -08001758
1759 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1760 crvw = A.addApproval('CRVW', 2)
1761 self.fake_gerrit.addEvent(crvw)
1762 self.waitUntilSettled()
1763 # No +1 from Jenkins so should not be enqueued
1764 self.assertEqual(len(self.history), 0)
1765
1766 # Add an old +1 and trigger check with a comment
1767 A.addApproval('VRFY', 1, granted_on=time.time() - 72 * 60 * 60)
1768 self.fake_gerrit.addEvent(crvw)
1769 self.waitUntilSettled()
1770 self.assertEqual(len(self.history), 1)
1771 self.assertEqual(self.history[0].name, 'project-check')
1772
1773 # Add a recent +1 and make sure nothing changes
1774 A.addApproval('VRFY', 1)
1775 self.fake_gerrit.addEvent(crvw)
1776 self.waitUntilSettled()
1777 self.assertEqual(len(self.history), 1)
1778
1779 # The last thing we did was query a change then do nothing
1780 # with a pipeline, so it will be in the cache; clean it up so
1781 # it does not fail the test.
1782 for pipeline in self.sched.layout.pipelines.values():
1783 pipeline.trigger.maintainCache([])
1784
James E. Blair4a28a882013-08-23 15:17:33 -07001785 def test_rerun_on_error(self):
1786 "Test that if a worker fails to run a job, it is run again"
1787 self.worker.hold_jobs_in_build = True
1788 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1789 A.addApproval('CRVW', 2)
1790 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1791 self.waitUntilSettled()
1792
1793 self.builds[0].run_error = True
1794 self.worker.hold_jobs_in_build = False
1795 self.worker.release()
1796 self.waitUntilSettled()
1797 self.assertEqual(self.countJobResults(self.history, 'RUN_ERROR'), 1)
1798 self.assertEqual(self.countJobResults(self.history, 'SUCCESS'), 3)
1799
James E. Blair412e5582013-04-22 15:50:12 -07001800 def test_statsd(self):
1801 "Test each of the statsd methods used in the scheduler"
1802 import extras
1803 statsd = extras.try_import('statsd.statsd')
1804 statsd.incr('test-incr')
1805 statsd.timing('test-timing', 3)
Alex Gaynor813d39b2014-05-17 16:17:16 -07001806 statsd.gauge('test-gauge', 12)
James E. Blair412e5582013-04-22 15:50:12 -07001807 self.assertReportedStat('test-incr', '1|c')
1808 self.assertReportedStat('test-timing', '3|ms')
Alex Gaynor813d39b2014-05-17 16:17:16 -07001809 self.assertReportedStat('test-gauge', '12|g')
James E. Blair412e5582013-04-22 15:50:12 -07001810
James E. Blairdad52252014-02-07 16:59:17 -08001811 def test_stuck_job_cleanup(self):
1812 "Test that pending jobs are cleaned up if removed from layout"
James E. Blair18c64442014-03-18 10:14:45 -07001813 # This job won't be registered at startup because it is not in
1814 # the standard layout, but we need it to already be registerd
1815 # for when we reconfigure, as that is when Zuul will attempt
1816 # to run the new job.
1817 self.worker.registerFunction('build:gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08001818 self.gearman_server.hold_jobs_in_queue = True
1819 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1820 A.addApproval('CRVW', 2)
1821 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1822 self.waitUntilSettled()
1823 self.assertEqual(len(self.gearman_server.getQueue()), 1)
1824
1825 self.config.set('zuul', 'layout_config',
1826 'tests/fixtures/layout-no-jobs.yaml')
1827 self.sched.reconfigure(self.config)
1828 self.waitUntilSettled()
1829
James E. Blair18c64442014-03-18 10:14:45 -07001830 self.gearman_server.release('gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08001831 self.waitUntilSettled()
1832 self.assertEqual(len(self.gearman_server.getQueue()), 0)
1833 self.assertTrue(self.sched._areAllBuildsComplete())
1834
1835 self.assertEqual(len(self.history), 1)
James E. Blair18c64442014-03-18 10:14:45 -07001836 self.assertEqual(self.history[0].name, 'gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08001837 self.assertEqual(self.history[0].result, 'SUCCESS')
1838
James E. Blair70c71582013-03-06 08:50:50 -08001839 def test_file_jobs(self):
1840 "Test that file jobs run only when appropriate"
1841 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1842 A.addPatchset(['pip-requires'])
1843 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1844 A.addApproval('CRVW', 2)
1845 B.addApproval('CRVW', 2)
1846 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1847 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1848 self.waitUntilSettled()
1849
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001850 testfile_jobs = [x for x in self.history
James E. Blair70c71582013-03-06 08:50:50 -08001851 if x.name == 'project-testfile']
1852
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001853 self.assertEqual(len(testfile_jobs), 1)
1854 self.assertEqual(testfile_jobs[0].changes, '1,2')
1855 self.assertEqual(A.data['status'], 'MERGED')
1856 self.assertEqual(A.reported, 2)
1857 self.assertEqual(B.data['status'], 'MERGED')
1858 self.assertEqual(B.reported, 2)
James E. Blair3c5e5b52013-04-26 11:17:03 -07001859
1860 def test_test_config(self):
1861 "Test that we can test the config"
1862 sched = zuul.scheduler.Scheduler()
James E. Blair6c358e72013-07-29 17:06:47 -07001863 sched.registerTrigger(None, 'gerrit')
James E. Blair63bb0ef2013-07-29 17:14:51 -07001864 sched.registerTrigger(None, 'timer')
Clark Boylanb640e052014-04-03 16:41:46 -07001865 sched.testConfig(self.config.get('zuul', 'layout_config'))
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001866
1867 def test_build_description(self):
1868 "Test that build descriptions update"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001869 self.worker.registerFunction('set_description:' +
1870 self.worker.worker_id)
1871
1872 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1873 A.addApproval('CRVW', 2)
1874 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1875 self.waitUntilSettled()
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001876 desc = self.history[0].description
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001877 self.log.debug("Description: %s" % desc)
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001878 self.assertTrue(re.search("Branch.*master", desc))
1879 self.assertTrue(re.search("Pipeline.*gate", desc))
1880 self.assertTrue(re.search("project-merge.*SUCCESS", desc))
1881 self.assertTrue(re.search("project-test1.*SUCCESS", desc))
1882 self.assertTrue(re.search("project-test2.*SUCCESS", desc))
1883 self.assertTrue(re.search("Reported result.*SUCCESS", desc))
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001884
James E. Blairc8a1e052014-02-25 09:29:26 -08001885 def test_queue_names(self):
1886 "Test shared change queue names"
1887 project1 = self.sched.layout.projects['org/project1']
1888 project2 = self.sched.layout.projects['org/project2']
1889 q1 = self.sched.layout.pipelines['gate'].getQueue(project1)
1890 q2 = self.sched.layout.pipelines['gate'].getQueue(project2)
1891 self.assertEqual(q1.name, 'integration')
1892 self.assertEqual(q2.name, 'integration')
1893
1894 self.config.set('zuul', 'layout_config',
1895 'tests/fixtures/layout-bad-queue.yaml')
1896 with testtools.ExpectedException(
1897 Exception, "More than one name assigned to change queue"):
1898 self.sched.reconfigure(self.config)
1899
James E. Blair64ed6f22013-07-10 14:07:23 -07001900 def test_queue_precedence(self):
1901 "Test that queue precedence works"
1902
1903 self.gearman_server.hold_jobs_in_queue = True
James E. Blair8de58bd2013-07-18 16:23:33 -07001904 self.worker.hold_jobs_in_build = True
James E. Blair64ed6f22013-07-10 14:07:23 -07001905 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1906 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1907 A.addApproval('CRVW', 2)
1908 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1909
1910 self.waitUntilSettled()
1911 self.gearman_server.hold_jobs_in_queue = False
1912 self.gearman_server.release()
1913 self.waitUntilSettled()
1914
James E. Blair8de58bd2013-07-18 16:23:33 -07001915 # Run one build at a time to ensure non-race order:
1916 for x in range(6):
1917 self.release(self.builds[0])
1918 self.waitUntilSettled()
1919 self.worker.hold_jobs_in_build = False
1920 self.waitUntilSettled()
1921
James E. Blair64ed6f22013-07-10 14:07:23 -07001922 self.log.debug(self.history)
1923 self.assertEqual(self.history[0].pipeline, 'gate')
1924 self.assertEqual(self.history[1].pipeline, 'check')
1925 self.assertEqual(self.history[2].pipeline, 'gate')
1926 self.assertEqual(self.history[3].pipeline, 'gate')
1927 self.assertEqual(self.history[4].pipeline, 'check')
1928 self.assertEqual(self.history[5].pipeline, 'check')
1929
Yuriy Taradaya6d452f2014-04-16 12:36:20 +04001930 def test_json_status(self, compressed=False):
James E. Blair1843a552013-07-03 14:19:52 -07001931 "Test that we can retrieve JSON status info"
1932 self.worker.hold_jobs_in_build = True
1933 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1934 A.addApproval('CRVW', 2)
1935 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1936 self.waitUntilSettled()
1937
1938 port = self.webapp.server.socket.getsockname()[1]
1939
Yuriy Taradaya6d452f2014-04-16 12:36:20 +04001940 req = urllib2.Request("http://localhost:%s/status.json" % port)
1941 if compressed:
1942 req.add_header("accept-encoding", "gzip")
1943 f = urllib2.urlopen(req)
James E. Blair1843a552013-07-03 14:19:52 -07001944 data = f.read()
Yuriy Taradaya6d452f2014-04-16 12:36:20 +04001945 if compressed:
1946 gz = gzip.GzipFile(fileobj=StringIO(data))
1947 data = gz.read()
James E. Blair1843a552013-07-03 14:19:52 -07001948
1949 self.worker.hold_jobs_in_build = False
1950 self.worker.release()
1951 self.waitUntilSettled()
1952
1953 data = json.loads(data)
1954 status_jobs = set()
1955 for p in data['pipelines']:
1956 for q in p['change_queues']:
Clark Boylanaf2476f2014-01-23 14:47:36 -08001957 if q['dependent']:
1958 self.assertEqual(q['window'], 20)
1959 else:
1960 self.assertEqual(q['window'], 0)
James E. Blair1843a552013-07-03 14:19:52 -07001961 for head in q['heads']:
1962 for change in head:
Clark Boylanaf2476f2014-01-23 14:47:36 -08001963 self.assertTrue(change['active'])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001964 self.assertEqual(change['id'], '1,1')
James E. Blair1843a552013-07-03 14:19:52 -07001965 for job in change['jobs']:
1966 status_jobs.add(job['name'])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001967 self.assertIn('project-merge', status_jobs)
1968 self.assertIn('project-test1', status_jobs)
1969 self.assertIn('project-test2', status_jobs)
James E. Blair1843a552013-07-03 14:19:52 -07001970
Yuriy Taradaya6d452f2014-04-16 12:36:20 +04001971 def test_json_status_gzip(self):
1972 self.test_json_status(True)
1973
James E. Blairc3d428e2013-12-03 15:06:48 -08001974 def test_merging_queues(self):
1975 "Test that transitively-connected change queues are merged"
1976 self.config.set('zuul', 'layout_config',
1977 'tests/fixtures/layout-merge-queues.yaml')
1978 self.sched.reconfigure(self.config)
1979 self.assertEqual(len(self.sched.layout.pipelines['gate'].queues), 1)
1980
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001981 def test_node_label(self):
1982 "Test that a job runs on a specific node label"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001983 self.worker.registerFunction('build:node-project-test1:debian')
1984
1985 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
1986 A.addApproval('CRVW', 2)
1987 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1988 self.waitUntilSettled()
James E. Blair4ca985f2013-05-30 12:27:43 -07001989
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001990 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
1991 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
1992 'debian')
1993 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
James E. Blaircdccd972013-07-01 12:10:22 -07001994
1995 def test_live_reconfiguration(self):
1996 "Test that live reconfiguration works"
1997 self.worker.hold_jobs_in_build = True
1998 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1999 A.addApproval('CRVW', 2)
2000 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2001 self.waitUntilSettled()
2002
2003 self.sched.reconfigure(self.config)
2004
2005 self.worker.hold_jobs_in_build = False
2006 self.worker.release()
2007 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002008 self.assertEqual(self.getJobFromHistory('project-merge').result,
2009 'SUCCESS')
2010 self.assertEqual(self.getJobFromHistory('project-test1').result,
2011 'SUCCESS')
2012 self.assertEqual(self.getJobFromHistory('project-test2').result,
2013 'SUCCESS')
2014 self.assertEqual(A.data['status'], 'MERGED')
2015 self.assertEqual(A.reported, 2)
James E. Blair287c06d2013-07-24 10:39:30 -07002016
James E. Blaire712d9f2013-07-31 11:40:11 -07002017 def test_live_reconfiguration_functions(self):
2018 "Test live reconfiguration with a custom function"
2019 self.worker.registerFunction('build:node-project-test1:debian')
2020 self.worker.registerFunction('build:node-project-test1:wheezy')
2021 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
2022 A.addApproval('CRVW', 2)
2023 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2024 self.waitUntilSettled()
2025
2026 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2027 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2028 'debian')
2029 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2030
2031 self.config.set('zuul', 'layout_config',
2032 'tests/fixtures/layout-live-'
2033 'reconfiguration-functions.yaml')
2034 self.sched.reconfigure(self.config)
2035 self.worker.build_history = []
2036
2037 B = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'B')
2038 B.addApproval('CRVW', 2)
2039 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2040 self.waitUntilSettled()
2041
2042 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2043 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2044 'wheezy')
2045 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2046
James E. Blair287c06d2013-07-24 10:39:30 -07002047 def test_delayed_repo_init(self):
2048 self.config.set('zuul', 'layout_config',
2049 'tests/fixtures/layout-delayed-repo-init.yaml')
2050 self.sched.reconfigure(self.config)
2051
2052 self.init_repo("org/new-project")
2053 A = self.fake_gerrit.addFakeChange('org/new-project', 'master', 'A')
2054
2055 A.addApproval('CRVW', 2)
2056 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2057 self.waitUntilSettled()
2058 self.assertEqual(self.getJobFromHistory('project-merge').result,
2059 'SUCCESS')
2060 self.assertEqual(self.getJobFromHistory('project-test1').result,
2061 'SUCCESS')
2062 self.assertEqual(self.getJobFromHistory('project-test2').result,
2063 'SUCCESS')
2064 self.assertEqual(A.data['status'], 'MERGED')
2065 self.assertEqual(A.reported, 2)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002066
Clark Boylan6dbbc482013-10-18 10:57:31 -07002067 def test_repo_deleted(self):
2068 self.config.set('zuul', 'layout_config',
2069 'tests/fixtures/layout-repo-deleted.yaml')
2070 self.sched.reconfigure(self.config)
2071
2072 self.init_repo("org/delete-project")
2073 A = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'A')
2074
2075 A.addApproval('CRVW', 2)
2076 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2077 self.waitUntilSettled()
2078 self.assertEqual(self.getJobFromHistory('project-merge').result,
2079 'SUCCESS')
2080 self.assertEqual(self.getJobFromHistory('project-test1').result,
2081 'SUCCESS')
2082 self.assertEqual(self.getJobFromHistory('project-test2').result,
2083 'SUCCESS')
2084 self.assertEqual(A.data['status'], 'MERGED')
2085 self.assertEqual(A.reported, 2)
2086
2087 # Delete org/new-project zuul repo. Should be recloned.
2088 shutil.rmtree(os.path.join(self.git_root, "org/delete-project"))
2089
2090 B = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'B')
2091
2092 B.addApproval('CRVW', 2)
2093 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2094 self.waitUntilSettled()
2095 self.assertEqual(self.getJobFromHistory('project-merge').result,
2096 'SUCCESS')
2097 self.assertEqual(self.getJobFromHistory('project-test1').result,
2098 'SUCCESS')
2099 self.assertEqual(self.getJobFromHistory('project-test2').result,
2100 'SUCCESS')
2101 self.assertEqual(B.data['status'], 'MERGED')
2102 self.assertEqual(B.reported, 2)
2103
James E. Blair63bb0ef2013-07-29 17:14:51 -07002104 def test_timer(self):
2105 "Test that a periodic job is triggered"
2106 self.worker.hold_jobs_in_build = True
2107 self.config.set('zuul', 'layout_config',
2108 'tests/fixtures/layout-timer.yaml')
2109 self.sched.reconfigure(self.config)
2110 self.registerJobs()
2111
Clark Boylan3ee090a2014-04-03 20:55:09 -07002112 # The pipeline triggers every second, so we should have seen
2113 # several by now.
2114 time.sleep(5)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002115 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002116
2117 self.assertEqual(len(self.builds), 2)
2118
James E. Blair63bb0ef2013-07-29 17:14:51 -07002119 port = self.webapp.server.socket.getsockname()[1]
2120
2121 f = urllib.urlopen("http://localhost:%s/status.json" % port)
2122 data = f.read()
2123
2124 self.worker.hold_jobs_in_build = False
Clark Boylan3ee090a2014-04-03 20:55:09 -07002125 # Stop queuing timer triggered jobs so that the assertions
2126 # below don't race against more jobs being queued.
2127 self.config.set('zuul', 'layout_config',
2128 'tests/fixtures/layout-no-timer.yaml')
2129 self.sched.reconfigure(self.config)
2130 self.registerJobs()
James E. Blair63bb0ef2013-07-29 17:14:51 -07002131 self.worker.release()
2132 self.waitUntilSettled()
2133
2134 self.assertEqual(self.getJobFromHistory(
2135 'project-bitrot-stable-old').result, 'SUCCESS')
2136 self.assertEqual(self.getJobFromHistory(
2137 'project-bitrot-stable-older').result, 'SUCCESS')
2138
2139 data = json.loads(data)
2140 status_jobs = set()
2141 for p in data['pipelines']:
2142 for q in p['change_queues']:
2143 for head in q['heads']:
2144 for change in head:
Alex Gaynorddb9ef32013-09-16 21:04:58 -07002145 self.assertEqual(change['id'], None)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002146 for job in change['jobs']:
2147 status_jobs.add(job['name'])
2148 self.assertIn('project-bitrot-stable-old', status_jobs)
2149 self.assertIn('project-bitrot-stable-older', status_jobs)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002150
James E. Blair4f6033c2014-03-27 15:49:09 -07002151 def test_idle(self):
2152 "Test that frequent periodic jobs work"
2153 self.worker.hold_jobs_in_build = True
James E. Blair4f6033c2014-03-27 15:49:09 -07002154
Clark Boylan3ee090a2014-04-03 20:55:09 -07002155 for x in range(1, 3):
2156 # Test that timer triggers periodic jobs even across
2157 # layout config reloads.
2158 # Start timer trigger
2159 self.config.set('zuul', 'layout_config',
2160 'tests/fixtures/layout-idle.yaml')
2161 self.sched.reconfigure(self.config)
2162 self.registerJobs()
James E. Blair4f6033c2014-03-27 15:49:09 -07002163
Clark Boylan3ee090a2014-04-03 20:55:09 -07002164 # The pipeline triggers every second, so we should have seen
2165 # several by now.
2166 time.sleep(5)
2167 self.waitUntilSettled()
2168
2169 # Stop queuing timer triggered jobs so that the assertions
2170 # below don't race against more jobs being queued.
2171 self.config.set('zuul', 'layout_config',
2172 'tests/fixtures/layout-no-timer.yaml')
2173 self.sched.reconfigure(self.config)
2174 self.registerJobs()
2175
2176 self.assertEqual(len(self.builds), 2)
2177 self.worker.release('.*')
2178 self.waitUntilSettled()
2179 self.assertEqual(len(self.builds), 0)
2180 self.assertEqual(len(self.history), x * 2)
James E. Blair4f6033c2014-03-27 15:49:09 -07002181
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002182 def test_check_smtp_pool(self):
2183 self.config.set('zuul', 'layout_config',
2184 'tests/fixtures/layout-smtp.yaml')
2185 self.sched.reconfigure(self.config)
2186
2187 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2188 self.waitUntilSettled()
2189
2190 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2191 self.waitUntilSettled()
2192
James E. Blairff80a2f2013-12-27 13:24:06 -08002193 self.assertEqual(len(self.smtp_messages), 2)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002194
2195 # A.messages only holds what FakeGerrit places in it. Thus we
2196 # work on the knowledge of what the first message should be as
2197 # it is only configured to go to SMTP.
2198
2199 self.assertEqual('zuul@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08002200 self.smtp_messages[0]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002201 self.assertEqual(['you@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08002202 self.smtp_messages[0]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002203 self.assertEqual('Starting check jobs.',
James E. Blairff80a2f2013-12-27 13:24:06 -08002204 self.smtp_messages[0]['body'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002205
2206 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08002207 self.smtp_messages[1]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002208 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08002209 self.smtp_messages[1]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002210 self.assertEqual(A.messages[0],
James E. Blairff80a2f2013-12-27 13:24:06 -08002211 self.smtp_messages[1]['body'])
James E. Blairad28e912013-11-27 10:43:22 -08002212
James E. Blaire5910202013-12-27 09:50:31 -08002213 def test_timer_smtp(self):
2214 "Test that a periodic job is triggered"
Clark Boylan3ee090a2014-04-03 20:55:09 -07002215 self.worker.hold_jobs_in_build = True
James E. Blaire5910202013-12-27 09:50:31 -08002216 self.config.set('zuul', 'layout_config',
2217 'tests/fixtures/layout-timer-smtp.yaml')
2218 self.sched.reconfigure(self.config)
2219 self.registerJobs()
2220
Clark Boylan3ee090a2014-04-03 20:55:09 -07002221 # The pipeline triggers every second, so we should have seen
2222 # several by now.
2223 time.sleep(5)
James E. Blaire5910202013-12-27 09:50:31 -08002224 self.waitUntilSettled()
2225
Clark Boylan3ee090a2014-04-03 20:55:09 -07002226 self.assertEqual(len(self.builds), 2)
2227 self.worker.release('.*')
2228 self.waitUntilSettled()
2229 self.assertEqual(len(self.history), 2)
2230
James E. Blaire5910202013-12-27 09:50:31 -08002231 self.assertEqual(self.getJobFromHistory(
2232 'project-bitrot-stable-old').result, 'SUCCESS')
2233 self.assertEqual(self.getJobFromHistory(
2234 'project-bitrot-stable-older').result, 'SUCCESS')
2235
James E. Blairff80a2f2013-12-27 13:24:06 -08002236 self.assertEqual(len(self.smtp_messages), 1)
James E. Blaire5910202013-12-27 09:50:31 -08002237
2238 # A.messages only holds what FakeGerrit places in it. Thus we
2239 # work on the knowledge of what the first message should be as
2240 # it is only configured to go to SMTP.
2241
2242 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08002243 self.smtp_messages[0]['from_email'])
James E. Blaire5910202013-12-27 09:50:31 -08002244 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08002245 self.smtp_messages[0]['to_email'])
James E. Blaire5910202013-12-27 09:50:31 -08002246 self.assertIn('Subject: Periodic check for org/project succeeded',
James E. Blairff80a2f2013-12-27 13:24:06 -08002247 self.smtp_messages[0]['headers'])
James E. Blaire5910202013-12-27 09:50:31 -08002248
Clark Boylan3ee090a2014-04-03 20:55:09 -07002249 # Stop queuing timer triggered jobs and let any that may have
2250 # queued through so that end of test assertions pass.
2251 self.config.set('zuul', 'layout_config',
2252 'tests/fixtures/layout-no-timer.yaml')
2253 self.sched.reconfigure(self.config)
2254 self.registerJobs()
2255 self.worker.release('.*')
2256 self.waitUntilSettled()
2257
James E. Blairad28e912013-11-27 10:43:22 -08002258 def test_client_enqueue(self):
2259 "Test that the RPC client can enqueue a change"
2260 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2261 A.addApproval('CRVW', 2)
2262 A.addApproval('APRV', 1)
2263
2264 client = zuul.rpcclient.RPCClient('127.0.0.1',
2265 self.gearman_server.port)
2266 r = client.enqueue(pipeline='gate',
2267 project='org/project',
2268 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08002269 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08002270 self.waitUntilSettled()
2271 self.assertEqual(self.getJobFromHistory('project-merge').result,
2272 'SUCCESS')
2273 self.assertEqual(self.getJobFromHistory('project-test1').result,
2274 'SUCCESS')
2275 self.assertEqual(self.getJobFromHistory('project-test2').result,
2276 'SUCCESS')
2277 self.assertEqual(A.data['status'], 'MERGED')
2278 self.assertEqual(A.reported, 2)
2279 self.assertEqual(r, True)
2280
2281 def test_client_enqueue_negative(self):
2282 "Test that the RPC client returns errors"
2283 client = zuul.rpcclient.RPCClient('127.0.0.1',
2284 self.gearman_server.port)
2285 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
2286 "Invalid project"):
2287 r = client.enqueue(pipeline='gate',
2288 project='project-does-not-exist',
2289 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08002290 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08002291 client.shutdown()
2292 self.assertEqual(r, False)
2293
2294 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
2295 "Invalid pipeline"):
2296 r = client.enqueue(pipeline='pipeline-does-not-exist',
2297 project='org/project',
2298 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08002299 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08002300 client.shutdown()
2301 self.assertEqual(r, False)
2302
2303 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
2304 "Invalid trigger"):
2305 r = client.enqueue(pipeline='gate',
2306 project='org/project',
2307 trigger='trigger-does-not-exist',
James E. Blair36658cf2013-12-06 17:53:48 -08002308 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08002309 client.shutdown()
2310 self.assertEqual(r, False)
2311
2312 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
2313 "Invalid change"):
2314 r = client.enqueue(pipeline='gate',
2315 project='org/project',
2316 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08002317 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08002318 client.shutdown()
2319 self.assertEqual(r, False)
2320
2321 self.waitUntilSettled()
2322 self.assertEqual(len(self.history), 0)
2323 self.assertEqual(len(self.builds), 0)
James E. Blair36658cf2013-12-06 17:53:48 -08002324
2325 def test_client_promote(self):
2326 "Test that the RPC client can promote a change"
2327 self.worker.hold_jobs_in_build = True
2328 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2329 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2330 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
2331 A.addApproval('CRVW', 2)
2332 B.addApproval('CRVW', 2)
2333 C.addApproval('CRVW', 2)
2334
2335 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2336 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2337 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2338
2339 self.waitUntilSettled()
2340
Sean Daguef39b9ca2014-01-10 21:34:35 -05002341 items = self.sched.layout.pipelines['gate'].getAllItems()
2342 enqueue_times = {}
2343 for item in items:
2344 enqueue_times[str(item.change)] = item.enqueue_time
2345
James E. Blair36658cf2013-12-06 17:53:48 -08002346 client = zuul.rpcclient.RPCClient('127.0.0.1',
2347 self.gearman_server.port)
2348 r = client.promote(pipeline='gate',
2349 change_ids=['2,1', '3,1'])
2350
Sean Daguef39b9ca2014-01-10 21:34:35 -05002351 # ensure that enqueue times are durable
2352 items = self.sched.layout.pipelines['gate'].getAllItems()
2353 for item in items:
2354 self.assertEqual(
2355 enqueue_times[str(item.change)], item.enqueue_time)
2356
James E. Blair78acec92014-02-06 07:11:32 -08002357 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08002358 self.worker.release('.*-merge')
2359 self.waitUntilSettled()
2360 self.worker.release('.*-merge')
2361 self.waitUntilSettled()
2362 self.worker.release('.*-merge')
2363 self.waitUntilSettled()
2364
2365 self.assertEqual(len(self.builds), 6)
2366 self.assertEqual(self.builds[0].name, 'project-test1')
2367 self.assertEqual(self.builds[1].name, 'project-test2')
2368 self.assertEqual(self.builds[2].name, 'project-test1')
2369 self.assertEqual(self.builds[3].name, 'project-test2')
2370 self.assertEqual(self.builds[4].name, 'project-test1')
2371 self.assertEqual(self.builds[5].name, 'project-test2')
2372
2373 self.assertTrue(self.job_has_changes(self.builds[0], B))
2374 self.assertFalse(self.job_has_changes(self.builds[0], A))
2375 self.assertFalse(self.job_has_changes(self.builds[0], C))
2376
2377 self.assertTrue(self.job_has_changes(self.builds[2], B))
2378 self.assertTrue(self.job_has_changes(self.builds[2], C))
2379 self.assertFalse(self.job_has_changes(self.builds[2], A))
2380
2381 self.assertTrue(self.job_has_changes(self.builds[4], B))
2382 self.assertTrue(self.job_has_changes(self.builds[4], C))
2383 self.assertTrue(self.job_has_changes(self.builds[4], A))
2384
2385 self.worker.release()
2386 self.waitUntilSettled()
2387
2388 self.assertEqual(A.data['status'], 'MERGED')
2389 self.assertEqual(A.reported, 2)
2390 self.assertEqual(B.data['status'], 'MERGED')
2391 self.assertEqual(B.reported, 2)
2392 self.assertEqual(C.data['status'], 'MERGED')
2393 self.assertEqual(C.reported, 2)
2394
2395 client.shutdown()
2396 self.assertEqual(r, True)
2397
2398 def test_client_promote_dependent(self):
2399 "Test that the RPC client can promote a dependent change"
2400 # C (depends on B) -> B -> A ; then promote C to get:
2401 # A -> C (depends on B) -> B
2402 self.worker.hold_jobs_in_build = True
2403 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2404 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2405 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
2406
2407 C.setDependsOn(B, 1)
2408
2409 A.addApproval('CRVW', 2)
2410 B.addApproval('CRVW', 2)
2411 C.addApproval('CRVW', 2)
2412
2413 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2414 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2415 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2416
2417 self.waitUntilSettled()
2418
2419 client = zuul.rpcclient.RPCClient('127.0.0.1',
2420 self.gearman_server.port)
2421 r = client.promote(pipeline='gate',
2422 change_ids=['3,1'])
2423
James E. Blair78acec92014-02-06 07:11:32 -08002424 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08002425 self.worker.release('.*-merge')
2426 self.waitUntilSettled()
2427 self.worker.release('.*-merge')
2428 self.waitUntilSettled()
2429 self.worker.release('.*-merge')
2430 self.waitUntilSettled()
2431
2432 self.assertEqual(len(self.builds), 6)
2433 self.assertEqual(self.builds[0].name, 'project-test1')
2434 self.assertEqual(self.builds[1].name, 'project-test2')
2435 self.assertEqual(self.builds[2].name, 'project-test1')
2436 self.assertEqual(self.builds[3].name, 'project-test2')
2437 self.assertEqual(self.builds[4].name, 'project-test1')
2438 self.assertEqual(self.builds[5].name, 'project-test2')
2439
2440 self.assertTrue(self.job_has_changes(self.builds[0], B))
2441 self.assertFalse(self.job_has_changes(self.builds[0], A))
2442 self.assertFalse(self.job_has_changes(self.builds[0], C))
2443
2444 self.assertTrue(self.job_has_changes(self.builds[2], B))
2445 self.assertTrue(self.job_has_changes(self.builds[2], C))
2446 self.assertFalse(self.job_has_changes(self.builds[2], A))
2447
2448 self.assertTrue(self.job_has_changes(self.builds[4], B))
2449 self.assertTrue(self.job_has_changes(self.builds[4], C))
2450 self.assertTrue(self.job_has_changes(self.builds[4], A))
2451
2452 self.worker.release()
2453 self.waitUntilSettled()
2454
2455 self.assertEqual(A.data['status'], 'MERGED')
2456 self.assertEqual(A.reported, 2)
2457 self.assertEqual(B.data['status'], 'MERGED')
2458 self.assertEqual(B.reported, 2)
2459 self.assertEqual(C.data['status'], 'MERGED')
2460 self.assertEqual(C.reported, 2)
2461
2462 client.shutdown()
2463 self.assertEqual(r, True)
2464
2465 def test_client_promote_negative(self):
2466 "Test that the RPC client returns errors for promotion"
2467 self.worker.hold_jobs_in_build = True
2468 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2469 A.addApproval('CRVW', 2)
2470 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2471 self.waitUntilSettled()
2472
2473 client = zuul.rpcclient.RPCClient('127.0.0.1',
2474 self.gearman_server.port)
2475
2476 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
2477 r = client.promote(pipeline='nonexistent',
2478 change_ids=['2,1', '3,1'])
2479 client.shutdown()
2480 self.assertEqual(r, False)
2481
2482 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
2483 r = client.promote(pipeline='gate',
2484 change_ids=['4,1'])
2485 client.shutdown()
2486 self.assertEqual(r, False)
2487
2488 self.worker.hold_jobs_in_build = False
2489 self.worker.release()
2490 self.waitUntilSettled()
Clark Boylan7603a372014-01-21 11:43:20 -08002491
2492 def test_queue_rate_limiting(self):
2493 "Test that DependentPipelines are rate limited with dep across window"
2494 self.config.set('zuul', 'layout_config',
2495 'tests/fixtures/layout-rate-limit.yaml')
2496 self.sched.reconfigure(self.config)
2497 self.worker.hold_jobs_in_build = True
2498 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2499 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2500 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
2501
2502 C.setDependsOn(B, 1)
2503 self.worker.addFailTest('project-test1', A)
2504
2505 A.addApproval('CRVW', 2)
2506 B.addApproval('CRVW', 2)
2507 C.addApproval('CRVW', 2)
2508
2509 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2510 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2511 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2512 self.waitUntilSettled()
2513
2514 # Only A and B will have their merge jobs queued because
2515 # window is 2.
2516 self.assertEqual(len(self.builds), 2)
2517 self.assertEqual(self.builds[0].name, 'project-merge')
2518 self.assertEqual(self.builds[1].name, 'project-merge')
2519
2520 self.worker.release('.*-merge')
2521 self.waitUntilSettled()
2522 self.worker.release('.*-merge')
2523 self.waitUntilSettled()
2524
2525 # Only A and B will have their test jobs queued because
2526 # window is 2.
2527 self.assertEqual(len(self.builds), 4)
2528 self.assertEqual(self.builds[0].name, 'project-test1')
2529 self.assertEqual(self.builds[1].name, 'project-test2')
2530 self.assertEqual(self.builds[2].name, 'project-test1')
2531 self.assertEqual(self.builds[3].name, 'project-test2')
2532
2533 self.worker.release('project-.*')
2534 self.waitUntilSettled()
2535
2536 queue = self.sched.layout.pipelines['gate'].queues[0]
2537 # A failed so window is reduced by 1 to 1.
2538 self.assertEqual(queue.window, 1)
2539 self.assertEqual(queue.window_floor, 1)
2540 self.assertEqual(A.data['status'], 'NEW')
2541
2542 # Gate is reset and only B's merge job is queued because
2543 # window shrunk to 1.
2544 self.assertEqual(len(self.builds), 1)
2545 self.assertEqual(self.builds[0].name, 'project-merge')
2546
2547 self.worker.release('.*-merge')
2548 self.waitUntilSettled()
2549
2550 # Only B's test jobs are queued because window is still 1.
2551 self.assertEqual(len(self.builds), 2)
2552 self.assertEqual(self.builds[0].name, 'project-test1')
2553 self.assertEqual(self.builds[1].name, 'project-test2')
2554
2555 self.worker.release('project-.*')
2556 self.waitUntilSettled()
2557
2558 # B was successfully merged so window is increased to 2.
2559 self.assertEqual(queue.window, 2)
2560 self.assertEqual(queue.window_floor, 1)
2561 self.assertEqual(B.data['status'], 'MERGED')
2562
2563 # Only C is left and its merge job is queued.
2564 self.assertEqual(len(self.builds), 1)
2565 self.assertEqual(self.builds[0].name, 'project-merge')
2566
2567 self.worker.release('.*-merge')
2568 self.waitUntilSettled()
2569
2570 # After successful merge job the test jobs for C are queued.
2571 self.assertEqual(len(self.builds), 2)
2572 self.assertEqual(self.builds[0].name, 'project-test1')
2573 self.assertEqual(self.builds[1].name, 'project-test2')
2574
2575 self.worker.release('project-.*')
2576 self.waitUntilSettled()
2577
2578 # C successfully merged so window is bumped to 3.
2579 self.assertEqual(queue.window, 3)
2580 self.assertEqual(queue.window_floor, 1)
2581 self.assertEqual(C.data['status'], 'MERGED')
2582
2583 def test_queue_rate_limiting_dependent(self):
2584 "Test that DependentPipelines are rate limited with dep in window"
2585 self.config.set('zuul', 'layout_config',
2586 'tests/fixtures/layout-rate-limit.yaml')
2587 self.sched.reconfigure(self.config)
2588 self.worker.hold_jobs_in_build = True
2589 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2590 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2591 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
2592
2593 B.setDependsOn(A, 1)
2594
2595 self.worker.addFailTest('project-test1', A)
2596
2597 A.addApproval('CRVW', 2)
2598 B.addApproval('CRVW', 2)
2599 C.addApproval('CRVW', 2)
2600
2601 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2602 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2603 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2604 self.waitUntilSettled()
2605
2606 # Only A and B will have their merge jobs queued because
2607 # window is 2.
2608 self.assertEqual(len(self.builds), 2)
2609 self.assertEqual(self.builds[0].name, 'project-merge')
2610 self.assertEqual(self.builds[1].name, 'project-merge')
2611
2612 self.worker.release('.*-merge')
2613 self.waitUntilSettled()
2614 self.worker.release('.*-merge')
2615 self.waitUntilSettled()
2616
2617 # Only A and B will have their test jobs queued because
2618 # window is 2.
2619 self.assertEqual(len(self.builds), 4)
2620 self.assertEqual(self.builds[0].name, 'project-test1')
2621 self.assertEqual(self.builds[1].name, 'project-test2')
2622 self.assertEqual(self.builds[2].name, 'project-test1')
2623 self.assertEqual(self.builds[3].name, 'project-test2')
2624
2625 self.worker.release('project-.*')
2626 self.waitUntilSettled()
2627
2628 queue = self.sched.layout.pipelines['gate'].queues[0]
2629 # A failed so window is reduced by 1 to 1.
2630 self.assertEqual(queue.window, 1)
2631 self.assertEqual(queue.window_floor, 1)
2632 self.assertEqual(A.data['status'], 'NEW')
2633 self.assertEqual(B.data['status'], 'NEW')
2634
2635 # Gate is reset and only C's merge job is queued because
2636 # window shrunk to 1 and A and B were dequeued.
2637 self.assertEqual(len(self.builds), 1)
2638 self.assertEqual(self.builds[0].name, 'project-merge')
2639
2640 self.worker.release('.*-merge')
2641 self.waitUntilSettled()
2642
2643 # Only C's test jobs are queued because window is still 1.
2644 self.assertEqual(len(self.builds), 2)
2645 self.assertEqual(self.builds[0].name, 'project-test1')
2646 self.assertEqual(self.builds[1].name, 'project-test2')
2647
2648 self.worker.release('project-.*')
2649 self.waitUntilSettled()
2650
2651 # C was successfully merged so window is increased to 2.
2652 self.assertEqual(queue.window, 2)
2653 self.assertEqual(queue.window_floor, 1)
2654 self.assertEqual(C.data['status'], 'MERGED')
Joshua Heskethba8776a2014-01-12 14:35:40 +08002655
2656 def test_worker_update_metadata(self):
2657 "Test if a worker can send back metadata about itself"
2658 self.worker.hold_jobs_in_build = True
2659
2660 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2661 A.addApproval('CRVW', 2)
2662 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2663 self.waitUntilSettled()
2664
2665 self.assertEqual(len(self.launcher.builds), 1)
2666
2667 self.log.debug('Current builds:')
2668 self.log.debug(self.launcher.builds)
2669
2670 start = time.time()
2671 while True:
2672 if time.time() - start > 10:
2673 raise Exception("Timeout waiting for gearman server to report "
2674 + "back to the client")
2675 build = self.launcher.builds.values()[0]
2676 if build.worker.name == "My Worker":
2677 break
2678 else:
2679 time.sleep(0)
2680
2681 self.log.debug(build)
2682 self.assertEqual("My Worker", build.worker.name)
2683 self.assertEqual("localhost", build.worker.hostname)
2684 self.assertEqual(['127.0.0.1', '192.168.1.1'], build.worker.ips)
2685 self.assertEqual("zuul.example.org", build.worker.fqdn)
2686 self.assertEqual("FakeBuilder", build.worker.program)
2687 self.assertEqual("v1.1", build.worker.version)
2688 self.assertEqual({'something': 'else'}, build.worker.extra)
2689
2690 self.worker.hold_jobs_in_build = False
2691 self.worker.release()
2692 self.waitUntilSettled()
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11002693
2694 def test_footer_message(self):
2695 "Test a pipeline's footer message is correctly added to the report."
2696 self.config.set('zuul', 'layout_config',
2697 'tests/fixtures/layout-footer-message.yaml')
2698 self.sched.reconfigure(self.config)
2699 self.registerJobs()
2700
2701 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2702 A.addApproval('CRVW', 2)
2703 self.worker.addFailTest('test1', A)
2704 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2705 self.waitUntilSettled()
2706
2707 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2708 B.addApproval('CRVW', 2)
2709 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2710 self.waitUntilSettled()
2711
2712 self.assertEqual(2, len(self.smtp_messages))
2713
2714 failure_body = """\
2715Build failed. For information on how to proceed, see \
2716http://wiki.example.org/Test_Failures
2717
2718- test1 http://logs.example.com/1/1/gate/test1/0 : FAILURE in 0s
2719- test2 http://logs.example.com/1/1/gate/test2/1 : SUCCESS in 0s
2720
2721For CI problems and help debugging, contact ci@example.org"""
2722
2723 success_body = """\
2724Build succeeded.
2725
2726- test1 http://logs.example.com/2/1/gate/test1/2 : SUCCESS in 0s
2727- test2 http://logs.example.com/2/1/gate/test2/3 : SUCCESS in 0s
2728
2729For CI problems and help debugging, contact ci@example.org"""
2730
2731 self.assertEqual(failure_body, self.smtp_messages[0]['body'])
2732 self.assertEqual(success_body, self.smtp_messages[1]['body'])
Joshua Heskethb7179772014-01-30 23:30:46 +11002733
2734 def test_merge_failure_reporters(self):
2735 """Check that the config is set up correctly"""
2736
2737 self.config.set('zuul', 'layout_config',
2738 'tests/fixtures/layout-merge-failure.yaml')
2739 self.sched.reconfigure(self.config)
2740 self.registerJobs()
2741
2742 self.assertEqual(
2743 "Merge Failed.\n\nThis change was unable to be automatically "
2744 "merged with the current state of the repository. Please rebase "
2745 "your change and upload a new patchset.",
2746 self.sched.layout.pipelines['check'].merge_failure_message)
2747 self.assertEqual(
2748 "The merge failed! For more information...",
2749 self.sched.layout.pipelines['gate'].merge_failure_message)
2750
2751 self.assertEqual(
2752 len(self.sched.layout.pipelines['check'].merge_failure_actions), 1)
2753 self.assertEqual(
2754 len(self.sched.layout.pipelines['gate'].merge_failure_actions), 2)
2755
2756 self.assertTrue(isinstance(
2757 self.sched.layout.pipelines['check'].merge_failure_actions[0].
2758 reporter, zuul.reporter.gerrit.Reporter))
2759
2760 self.assertTrue(
2761 (
2762 isinstance(self.sched.layout.pipelines['gate'].
2763 merge_failure_actions[0].reporter,
2764 zuul.reporter.smtp.Reporter) and
2765 isinstance(self.sched.layout.pipelines['gate'].
2766 merge_failure_actions[1].reporter,
2767 zuul.reporter.gerrit.Reporter)
2768 ) or (
2769 isinstance(self.sched.layout.pipelines['gate'].
2770 merge_failure_actions[0].reporter,
2771 zuul.reporter.gerrit.Reporter) and
2772 isinstance(self.sched.layout.pipelines['gate'].
2773 merge_failure_actions[1].reporter,
2774 zuul.reporter.smtp.Reporter)
2775 )
2776 )
2777
2778 def test_merge_failure_reports(self):
2779 """Check that when a change fails to merge the correct message is sent
2780 to the correct reporter"""
2781 self.config.set('zuul', 'layout_config',
2782 'tests/fixtures/layout-merge-failure.yaml')
2783 self.sched.reconfigure(self.config)
2784 self.registerJobs()
2785
2786 # Check a test failure isn't reported to SMTP
2787 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2788 A.addApproval('CRVW', 2)
2789 self.worker.addFailTest('project-test1', A)
2790 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2791 self.waitUntilSettled()
2792
2793 self.assertEqual(3, len(self.history)) # 3 jobs
2794 self.assertEqual(0, len(self.smtp_messages))
2795
2796 # Check a merge failure is reported to SMTP
2797 # B should be merged, but C will conflict with B
2798 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2799 B.addPatchset(['conflict'])
2800 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
2801 C.addPatchset(['conflict'])
2802 B.addApproval('CRVW', 2)
2803 C.addApproval('CRVW', 2)
2804 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2805 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2806 self.waitUntilSettled()
2807
2808 self.assertEqual(6, len(self.history)) # A and B jobs
2809 self.assertEqual(1, len(self.smtp_messages))
2810 self.assertEqual('The merge failed! For more information...',
2811 self.smtp_messages[0]['body'])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11002812
2813 def test_swift_instructions(self):
2814 "Test that the correct swift instructions are sent to the workers"
2815 self.config.set('zuul', 'layout_config',
2816 'tests/fixtures/layout-swift.yaml')
2817 self.sched.reconfigure(self.config)
2818 self.registerJobs()
2819
2820 self.worker.hold_jobs_in_build = True
2821 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2822
2823 A.addApproval('CRVW', 2)
2824 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2825 self.waitUntilSettled()
2826
2827 self.assertEqual(
2828 "https://storage.example.org/V1/AUTH_account/merge_logs/1/1/1/"
2829 "gate/test-merge/",
2830 self.builds[0].parameters['SWIFT_logs_URL'][:-32])
2831 self.assertEqual(5,
2832 len(self.builds[0].parameters['SWIFT_logs_HMAC_BODY'].
2833 split('\n')))
2834 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[0].parameters)
2835
2836 self.assertEqual(
2837 "https://storage.example.org/V1/AUTH_account/logs/1/1/1/"
2838 "gate/test-test/",
2839 self.builds[1].parameters['SWIFT_logs_URL'][:-32])
2840 self.assertEqual(5,
2841 len(self.builds[1].parameters['SWIFT_logs_HMAC_BODY'].
2842 split('\n')))
2843 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[1].parameters)
2844
2845 self.assertEqual(
2846 "https://storage.example.org/V1/AUTH_account/stash/1/1/1/"
2847 "gate/test-test/",
2848 self.builds[1].parameters['SWIFT_MOSTLY_URL'][:-32])
2849 self.assertEqual(5,
2850 len(self.builds[1].
2851 parameters['SWIFT_MOSTLY_HMAC_BODY'].split('\n')))
2852 self.assertIn('SWIFT_MOSTLY_SIGNATURE', self.builds[1].parameters)
2853
2854 self.worker.hold_jobs_in_build = False
2855 self.worker.release()
2856 self.waitUntilSettled()
Joshua Hesketh85af4e92014-02-21 08:28:58 -08002857
2858 def test_client_get_running_jobs(self):
2859 "Test that the RPC client can get a list of running jobs"
2860 self.worker.hold_jobs_in_build = True
2861 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2862 A.addApproval('CRVW', 2)
2863 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2864 self.waitUntilSettled()
2865
2866 client = zuul.rpcclient.RPCClient('127.0.0.1',
2867 self.gearman_server.port)
2868
2869 # Wait for gearman server to send the initial workData back to zuul
2870 start = time.time()
2871 while True:
2872 if time.time() - start > 10:
2873 raise Exception("Timeout waiting for gearman server to report "
2874 + "back to the client")
2875 build = self.launcher.builds.values()[0]
2876 if build.worker.name == "My Worker":
2877 break
2878 else:
2879 time.sleep(0)
2880
2881 running_items = client.get_running_jobs()
2882
2883 self.assertEqual(1, len(running_items))
2884 running_item = running_items[0]
2885 self.assertEqual([], running_item['failing_reasons'])
2886 self.assertEqual([], running_item['items_behind'])
2887 self.assertEqual('https://hostname/1', running_item['url'])
2888 self.assertEqual(None, running_item['item_ahead'])
2889 self.assertEqual('org/project', running_item['project'])
2890 self.assertEqual(None, running_item['remaining_time'])
2891 self.assertEqual(True, running_item['active'])
2892 self.assertEqual('1,1', running_item['id'])
2893
2894 self.assertEqual(3, len(running_item['jobs']))
2895 for job in running_item['jobs']:
2896 if job['name'] == 'project-merge':
2897 self.assertEqual('project-merge', job['name'])
2898 self.assertEqual('gate', job['pipeline'])
2899 self.assertEqual(False, job['retry'])
2900 self.assertEqual(13, len(job['parameters']))
2901 self.assertEqual('https://server/job/project-merge/0/',
2902 job['url'])
2903 self.assertEqual(7, len(job['worker']))
2904 self.assertEqual(False, job['canceled'])
2905 self.assertEqual(True, job['voting'])
2906 self.assertEqual(None, job['result'])
2907 self.assertEqual('gate', job['pipeline'])
2908 break
2909
2910 self.worker.hold_jobs_in_build = False
2911 self.worker.release()
2912 self.waitUntilSettled()
2913
2914 running_items = client.get_running_jobs()
2915 self.assertEqual(0, len(running_items))
James E. Blairbadc1ad2014-04-28 13:55:14 -07002916
2917 def test_nonvoting_pipeline(self):
2918 "Test that a nonvoting pipeline (experimental) can still report"
2919
Joshua Heskethcc017ea2014-04-30 19:55:25 +10002920 A = self.fake_gerrit.addFakeChange('org/experimental-project',
2921 'master', 'A')
James E. Blairbadc1ad2014-04-28 13:55:14 -07002922 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2923 self.waitUntilSettled()
Joshua Heskethcc017ea2014-04-30 19:55:25 +10002924 self.assertEqual(
2925 self.getJobFromHistory('experimental-project-test').result,
2926 'SUCCESS')
James E. Blairbadc1ad2014-04-28 13:55:14 -07002927 self.assertEqual(A.reported, 1)
Clark Boylana9702ad2014-05-08 17:17:24 -07002928
2929 def test_old_patchset_doesnt_trigger(self):
2930 "Test that jobs never run against old patchsets"
2931 self.config.set('zuul', 'layout_config',
2932 'tests/fixtures/layout-current-patchset.yaml')
2933 self.sched.reconfigure(self.config)
2934 self.registerJobs()
2935 # Create two patchsets and let their tests settle out. Then
2936 # comment on first patchset and check that no additional
2937 # jobs are run.
2938 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2939 # Added because the layout file really wants an approval but this
2940 # doesn't match anyways.
2941 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1))
2942 self.waitUntilSettled()
2943 A.addPatchset()
2944 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1))
2945 self.waitUntilSettled()
2946
2947 old_history_count = len(self.history)
2948 self.assertEqual(old_history_count, 2) # one job for each ps
2949 self.fake_gerrit.addEvent(A.getChangeCommentEvent(1))
2950 self.waitUntilSettled()
2951
2952 # Assert no new jobs ran after event for old patchset.
2953 self.assertEqual(len(self.history), old_history_count)
2954
2955 # The last thing we did was add an event for a change then do
2956 # nothing with a pipeline, so it will be in the cache;
2957 # clean it up so it does not fail the test.
2958 for pipeline in self.sched.layout.pipelines.values():
2959 pipeline.trigger.maintainCache([])