blob: 6e65774a94943eabf7555c020e9c4a188bc30bfc [file] [log] [blame]
James E. Blairb0fcae42012-07-17 11:12:10 -07001#!/usr/bin/env python
2
3# Copyright 2012 Hewlett-Packard Development Company, L.P.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16
James E. Blairb0fcae42012-07-17 11:12:10 -070017import json
Monty Taylorbc758832013-06-17 17:22:42 -040018import logging
19import os
James E. Blairb0fcae42012-07-17 11:12:10 -070020import re
James E. Blair4886cc12012-07-18 15:39:41 -070021import shutil
Monty Taylorbc758832013-06-17 17:22:42 -040022import time
James E. Blair1843a552013-07-03 14:19:52 -070023import urllib
Monty Taylorbc758832013-06-17 17:22:42 -040024import urllib2
Monty Taylorbc758832013-06-17 17:22:42 -040025
James E. Blair4886cc12012-07-18 15:39:41 -070026import git
Monty Taylorbc758832013-06-17 17:22:42 -040027import testtools
James E. Blairb0fcae42012-07-17 11:12:10 -070028
James E. Blairb0fcae42012-07-17 11:12:10 -070029import zuul.scheduler
James E. Blairad28e912013-11-27 10:43:22 -080030import zuul.rpcclient
Joshua Hesketh1879cf72013-08-19 14:13:15 +100031import zuul.reporter.gerrit
Joshua Hesketh5fea8672013-08-19 17:32:01 +100032import zuul.reporter.smtp
James E. Blairb0fcae42012-07-17 11:12:10 -070033
Clark Boylanb640e052014-04-03 16:41:46 -070034from tests.base import ZuulTestCase, repack_repo
James E. Blairb0fcae42012-07-17 11:12:10 -070035
James E. Blair1f4c2bb2013-04-26 08:40:46 -070036logging.basicConfig(level=logging.DEBUG,
37 format='%(asctime)s %(name)-32s '
38 '%(levelname)-8s %(message)s')
James E. Blairb0fcae42012-07-17 11:12:10 -070039
40
Clark Boylanb640e052014-04-03 16:41:46 -070041class TestScheduler(ZuulTestCase):
James E. Blairb0fcae42012-07-17 11:12:10 -070042 def test_jobs_launched(self):
43 "Test that jobs are launched and a change is merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -070044
James E. Blairb0fcae42012-07-17 11:12:10 -070045 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8c803f82012-07-31 16:25:42 -070046 A.addApproval('CRVW', 2)
James E. Blairb0fcae42012-07-17 11:12:10 -070047 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
48 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -040049 self.assertEqual(self.getJobFromHistory('project-merge').result,
50 'SUCCESS')
51 self.assertEqual(self.getJobFromHistory('project-test1').result,
52 'SUCCESS')
53 self.assertEqual(self.getJobFromHistory('project-test2').result,
54 'SUCCESS')
55 self.assertEqual(A.data['status'], 'MERGED')
56 self.assertEqual(A.reported, 2)
James E. Blairb0fcae42012-07-17 11:12:10 -070057
James E. Blair66eeebf2013-07-27 17:44:32 -070058 self.assertReportedStat('gerrit.event.comment-added', value='1|c')
59 self.assertReportedStat('zuul.pipeline.gate.current_changes',
60 value='1|g')
61 self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
62 kind='ms')
63 self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
64 value='1|c')
65 self.assertReportedStat('zuul.pipeline.gate.resident_time', kind='ms')
66 self.assertReportedStat('zuul.pipeline.gate.total_changes',
67 value='1|c')
James E. Blair412e5582013-04-22 15:50:12 -070068 self.assertReportedStat(
James E. Blair66eeebf2013-07-27 17:44:32 -070069 'zuul.pipeline.gate.org.project.resident_time', kind='ms')
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.total_changes', value='1|c')
James E. Blair412e5582013-04-22 15:50:12 -070072
James E. Blair3cb10702013-08-24 08:56:03 -070073 def test_initial_pipeline_gauges(self):
74 "Test that each pipeline reported its length on start"
75 pipeline_names = self.sched.layout.pipelines.keys()
76 self.assertNotEqual(len(pipeline_names), 0)
77 for name in pipeline_names:
78 self.assertReportedStat('zuul.pipeline.%s.current_changes' % name,
79 value='0|g')
80
James E. Blair42f74822013-05-14 15:18:03 -070081 def test_duplicate_pipelines(self):
82 "Test that a change matching multiple pipelines works"
James E. Blair1b4d9722013-05-21 10:32:04 -070083
James E. Blair42f74822013-05-14 15:18:03 -070084 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
85 self.fake_gerrit.addEvent(A.getChangeRestoredEvent())
86 self.waitUntilSettled()
James E. Blair42f74822013-05-14 15:18:03 -070087
Monty Taylor98f0f3e2013-07-06 16:02:31 -040088 self.assertEqual(len(self.history), 2)
Monty Taylor6bef8ef2013-06-02 08:17:12 -040089 self.history[0].name == 'project-test1'
90 self.history[1].name == 'project-test1'
James E. Blair42f74822013-05-14 15:18:03 -070091
Monty Taylor98f0f3e2013-07-06 16:02:31 -040092 self.assertEqual(len(A.messages), 2)
James E. Blair42f74822013-05-14 15:18:03 -070093 if 'dup1/project-test1' in A.messages[0]:
Monty Taylor98f0f3e2013-07-06 16:02:31 -040094 self.assertIn('dup1/project-test1', A.messages[0])
95 self.assertNotIn('dup2/project-test1', A.messages[0])
96 self.assertNotIn('dup1/project-test1', A.messages[1])
97 self.assertIn('dup2/project-test1', A.messages[1])
James E. Blair42f74822013-05-14 15:18:03 -070098 else:
Monty Taylor98f0f3e2013-07-06 16:02:31 -040099 self.assertIn('dup1/project-test1', A.messages[1])
100 self.assertNotIn('dup2/project-test1', A.messages[1])
101 self.assertNotIn('dup1/project-test1', A.messages[0])
102 self.assertIn('dup2/project-test1', A.messages[0])
James E. Blair42f74822013-05-14 15:18:03 -0700103
James E. Blairb0fcae42012-07-17 11:12:10 -0700104 def test_parallel_changes(self):
105 "Test that changes are tested in parallel and merged in series"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700106
107 self.worker.hold_jobs_in_build = True
James E. Blairb0fcae42012-07-17 11:12:10 -0700108 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
109 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
110 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700111 A.addApproval('CRVW', 2)
112 B.addApproval('CRVW', 2)
113 C.addApproval('CRVW', 2)
James E. Blairb0fcae42012-07-17 11:12:10 -0700114
115 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
116 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
117 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
118
119 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400120 self.assertEqual(len(self.builds), 1)
121 self.assertEqual(self.builds[0].name, 'project-merge')
122 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700123
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700124 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700125 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400126 self.assertEqual(len(self.builds), 3)
127 self.assertEqual(self.builds[0].name, 'project-test1')
128 self.assertTrue(self.job_has_changes(self.builds[0], A))
129 self.assertEqual(self.builds[1].name, 'project-test2')
130 self.assertTrue(self.job_has_changes(self.builds[1], A))
131 self.assertEqual(self.builds[2].name, 'project-merge')
132 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700133
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700134 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700135 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400136 self.assertEqual(len(self.builds), 5)
137 self.assertEqual(self.builds[0].name, 'project-test1')
138 self.assertTrue(self.job_has_changes(self.builds[0], A))
139 self.assertEqual(self.builds[1].name, 'project-test2')
140 self.assertTrue(self.job_has_changes(self.builds[1], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700141
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400142 self.assertEqual(self.builds[2].name, 'project-test1')
143 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
144 self.assertEqual(self.builds[3].name, 'project-test2')
145 self.assertTrue(self.job_has_changes(self.builds[3], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700146
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400147 self.assertEqual(self.builds[4].name, 'project-merge')
148 self.assertTrue(self.job_has_changes(self.builds[4], A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700149
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700150 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700151 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400152 self.assertEqual(len(self.builds), 6)
153 self.assertEqual(self.builds[0].name, 'project-test1')
154 self.assertTrue(self.job_has_changes(self.builds[0], A))
155 self.assertEqual(self.builds[1].name, 'project-test2')
156 self.assertTrue(self.job_has_changes(self.builds[1], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700157
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400158 self.assertEqual(self.builds[2].name, 'project-test1')
159 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
160 self.assertEqual(self.builds[3].name, 'project-test2')
161 self.assertTrue(self.job_has_changes(self.builds[3], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700162
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400163 self.assertEqual(self.builds[4].name, 'project-test1')
164 self.assertTrue(self.job_has_changes(self.builds[4], A, B, C))
165 self.assertEqual(self.builds[5].name, 'project-test2')
166 self.assertTrue(self.job_has_changes(self.builds[5], A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700167
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700168 self.worker.hold_jobs_in_build = False
169 self.worker.release()
James E. Blairb0fcae42012-07-17 11:12:10 -0700170 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400171 self.assertEqual(len(self.builds), 0)
James E. Blairb0fcae42012-07-17 11:12:10 -0700172
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400173 self.assertEqual(len(self.history), 9)
174 self.assertEqual(A.data['status'], 'MERGED')
175 self.assertEqual(B.data['status'], 'MERGED')
176 self.assertEqual(C.data['status'], 'MERGED')
177 self.assertEqual(A.reported, 2)
178 self.assertEqual(B.reported, 2)
179 self.assertEqual(C.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700180
181 def test_failed_changes(self):
182 "Test that a change behind a failed change is retested"
James E. Blaire2819012013-06-28 17:17:26 -0400183 self.worker.hold_jobs_in_build = True
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700184
James E. Blairb02a3bb2012-07-30 17:49:55 -0700185 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
186 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8c803f82012-07-31 16:25:42 -0700187 A.addApproval('CRVW', 2)
188 B.addApproval('CRVW', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700189
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700190 self.worker.addFailTest('project-test1', A)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700191
James E. Blaire2819012013-06-28 17:17:26 -0400192 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
193 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700194 self.waitUntilSettled()
James E. Blaire2819012013-06-28 17:17:26 -0400195
196 self.worker.release('.*-merge')
197 self.waitUntilSettled()
198
199 self.worker.hold_jobs_in_build = False
200 self.worker.release()
201
202 self.waitUntilSettled()
203 # It's certain that the merge job for change 2 will run, but
204 # the test1 and test2 jobs may or may not run.
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400205 self.assertTrue(len(self.history) > 6)
206 self.assertEqual(A.data['status'], 'NEW')
207 self.assertEqual(B.data['status'], 'MERGED')
208 self.assertEqual(A.reported, 2)
209 self.assertEqual(B.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700210
211 def test_independent_queues(self):
212 "Test that changes end up in the right queues"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700213
214 self.worker.hold_jobs_in_build = True
Zhongyue Luo5d556072012-09-21 02:00:47 +0900215 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700216 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
217 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700218 A.addApproval('CRVW', 2)
219 B.addApproval('CRVW', 2)
220 C.addApproval('CRVW', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700221
222 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
223 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
224 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
225
James E. Blairb02a3bb2012-07-30 17:49:55 -0700226 self.waitUntilSettled()
227
228 # There should be one merge job at the head of each queue running
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400229 self.assertEqual(len(self.builds), 2)
230 self.assertEqual(self.builds[0].name, 'project-merge')
231 self.assertTrue(self.job_has_changes(self.builds[0], A))
232 self.assertEqual(self.builds[1].name, 'project1-merge')
233 self.assertTrue(self.job_has_changes(self.builds[1], B))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700234
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700235 # Release the current merge builds
236 self.worker.release('.*-merge')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700237 self.waitUntilSettled()
238 # Release the merge job for project2 which is behind project1
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700239 self.worker.release('.*-merge')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700240 self.waitUntilSettled()
241
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700242 # All the test builds should be running:
James E. Blairb02a3bb2012-07-30 17:49:55 -0700243 # project1 (3) + project2 (3) + project (2) = 8
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400244 self.assertEqual(len(self.builds), 8)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700245
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700246 self.worker.release()
James E. Blairb02a3bb2012-07-30 17:49:55 -0700247 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400248 self.assertEqual(len(self.builds), 0)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700249
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400250 self.assertEqual(len(self.history), 11)
251 self.assertEqual(A.data['status'], 'MERGED')
252 self.assertEqual(B.data['status'], 'MERGED')
253 self.assertEqual(C.data['status'], 'MERGED')
254 self.assertEqual(A.reported, 2)
255 self.assertEqual(B.reported, 2)
256 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700257
258 def test_failed_change_at_head(self):
259 "Test that if a change at the head fails, jobs behind it are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700260
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700261 self.worker.hold_jobs_in_build = True
James E. Blaird466dc42012-07-31 10:42:56 -0700262 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
263 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
264 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700265 A.addApproval('CRVW', 2)
266 B.addApproval('CRVW', 2)
267 C.addApproval('CRVW', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700268
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700269 self.worker.addFailTest('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700270
271 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
272 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
273 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
274
275 self.waitUntilSettled()
James E. Blaird466dc42012-07-31 10:42:56 -0700276
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400277 self.assertEqual(len(self.builds), 1)
278 self.assertEqual(self.builds[0].name, 'project-merge')
279 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blaird466dc42012-07-31 10:42:56 -0700280
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700281 self.worker.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700282 self.waitUntilSettled()
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()
287
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400288 self.assertEqual(len(self.builds), 6)
289 self.assertEqual(self.builds[0].name, 'project-test1')
290 self.assertEqual(self.builds[1].name, 'project-test2')
291 self.assertEqual(self.builds[2].name, 'project-test1')
292 self.assertEqual(self.builds[3].name, 'project-test2')
293 self.assertEqual(self.builds[4].name, 'project-test1')
294 self.assertEqual(self.builds[5].name, 'project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700295
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400296 self.release(self.builds[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700297 self.waitUntilSettled()
298
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400299 # project-test2, project-merge for B
300 self.assertEqual(len(self.builds), 2)
301 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 4)
James E. Blaird466dc42012-07-31 10:42:56 -0700302
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700303 self.worker.hold_jobs_in_build = False
304 self.worker.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700305 self.waitUntilSettled()
306
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400307 self.assertEqual(len(self.builds), 0)
308 self.assertEqual(len(self.history), 15)
309 self.assertEqual(A.data['status'], 'NEW')
310 self.assertEqual(B.data['status'], 'MERGED')
311 self.assertEqual(C.data['status'], 'MERGED')
312 self.assertEqual(A.reported, 2)
313 self.assertEqual(B.reported, 2)
314 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700315
James E. Blair0aac4872013-08-23 14:02:38 -0700316 def test_failed_change_in_middle(self):
317 "Test a failed change in the middle of the queue"
318
319 self.worker.hold_jobs_in_build = True
320 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
321 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
322 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
323 A.addApproval('CRVW', 2)
324 B.addApproval('CRVW', 2)
325 C.addApproval('CRVW', 2)
326
327 self.worker.addFailTest('project-test1', B)
328
329 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
330 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
331 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
332
333 self.waitUntilSettled()
334
335 self.worker.release('.*-merge')
336 self.waitUntilSettled()
337 self.worker.release('.*-merge')
338 self.waitUntilSettled()
339 self.worker.release('.*-merge')
340 self.waitUntilSettled()
341
342 self.assertEqual(len(self.builds), 6)
343 self.assertEqual(self.builds[0].name, 'project-test1')
344 self.assertEqual(self.builds[1].name, 'project-test2')
345 self.assertEqual(self.builds[2].name, 'project-test1')
346 self.assertEqual(self.builds[3].name, 'project-test2')
347 self.assertEqual(self.builds[4].name, 'project-test1')
348 self.assertEqual(self.builds[5].name, 'project-test2')
349
350 self.release(self.builds[2])
351 self.waitUntilSettled()
352
James E. Blair972e3c72013-08-29 12:04:55 -0700353 # project-test1 and project-test2 for A
354 # project-test2 for B
355 # project-merge for C (without B)
356 self.assertEqual(len(self.builds), 4)
James E. Blair0aac4872013-08-23 14:02:38 -0700357 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 2)
358
James E. Blair972e3c72013-08-29 12:04:55 -0700359 self.worker.release('.*-merge')
360 self.waitUntilSettled()
361
362 # project-test1 and project-test2 for A
363 # project-test2 for B
364 # project-test1 and project-test2 for C
365 self.assertEqual(len(self.builds), 5)
366
James E. Blair0aac4872013-08-23 14:02:38 -0700367 items = self.sched.layout.pipelines['gate'].getAllItems()
368 builds = items[0].current_build_set.getBuilds()
369 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
370 self.assertEqual(self.countJobResults(builds, None), 2)
371 builds = items[1].current_build_set.getBuilds()
372 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
373 self.assertEqual(self.countJobResults(builds, 'FAILURE'), 1)
374 self.assertEqual(self.countJobResults(builds, None), 1)
375 builds = items[2].current_build_set.getBuilds()
376 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
James E. Blair972e3c72013-08-29 12:04:55 -0700377 self.assertEqual(self.countJobResults(builds, None), 2)
James E. Blair0aac4872013-08-23 14:02:38 -0700378
379 self.worker.hold_jobs_in_build = False
380 self.worker.release()
381 self.waitUntilSettled()
382
383 self.assertEqual(len(self.builds), 0)
384 self.assertEqual(len(self.history), 12)
385 self.assertEqual(A.data['status'], 'MERGED')
386 self.assertEqual(B.data['status'], 'NEW')
387 self.assertEqual(C.data['status'], 'MERGED')
388 self.assertEqual(A.reported, 2)
389 self.assertEqual(B.reported, 2)
390 self.assertEqual(C.reported, 2)
391
James E. Blaird466dc42012-07-31 10:42:56 -0700392 def test_failed_change_at_head_with_queue(self):
393 "Test that if a change at the head fails, queued jobs are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700394
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700395 self.gearman_server.hold_jobs_in_queue = True
James E. Blaird466dc42012-07-31 10:42:56 -0700396 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
397 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
398 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700399 A.addApproval('CRVW', 2)
400 B.addApproval('CRVW', 2)
401 C.addApproval('CRVW', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700402
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700403 self.worker.addFailTest('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700404
405 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
406 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
407 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
408
409 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700410 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400411 self.assertEqual(len(self.builds), 0)
412 self.assertEqual(len(queue), 1)
413 self.assertEqual(queue[0].name, 'build:project-merge')
414 self.assertTrue(self.job_has_changes(queue[0], A))
James E. Blaird466dc42012-07-31 10:42:56 -0700415
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700416 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700417 self.waitUntilSettled()
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. Blair701c5b42013-06-06 09:34:59 -0700422 queue = self.gearman_server.getQueue()
James E. Blaird466dc42012-07-31 10:42:56 -0700423
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400424 self.assertEqual(len(self.builds), 0)
425 self.assertEqual(len(queue), 6)
426 self.assertEqual(queue[0].name, 'build:project-test1')
427 self.assertEqual(queue[1].name, 'build:project-test2')
428 self.assertEqual(queue[2].name, 'build:project-test1')
429 self.assertEqual(queue[3].name, 'build:project-test2')
430 self.assertEqual(queue[4].name, 'build:project-test1')
431 self.assertEqual(queue[5].name, 'build:project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700432
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700433 self.release(queue[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700434 self.waitUntilSettled()
435
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400436 self.assertEqual(len(self.builds), 0)
James E. Blair701c5b42013-06-06 09:34:59 -0700437 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400438 self.assertEqual(len(queue), 2) # project-test2, project-merge for B
439 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 0)
James E. Blaird466dc42012-07-31 10:42:56 -0700440
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700441 self.gearman_server.hold_jobs_in_queue = False
442 self.gearman_server.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700443 self.waitUntilSettled()
444
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400445 self.assertEqual(len(self.builds), 0)
446 self.assertEqual(len(self.history), 11)
447 self.assertEqual(A.data['status'], 'NEW')
448 self.assertEqual(B.data['status'], 'MERGED')
449 self.assertEqual(C.data['status'], 'MERGED')
450 self.assertEqual(A.reported, 2)
451 self.assertEqual(B.reported, 2)
452 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700453
James E. Blairfef71632013-09-23 11:15:47 -0700454 def test_two_failed_changes_at_head(self):
455 "Test that changes are reparented correctly if 2 fail at head"
456
457 self.worker.hold_jobs_in_build = True
458 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
459 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
460 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
461 A.addApproval('CRVW', 2)
462 B.addApproval('CRVW', 2)
463 C.addApproval('CRVW', 2)
464
465 self.worker.addFailTest('project-test1', A)
466 self.worker.addFailTest('project-test1', B)
467
468 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
469 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
470 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
471 self.waitUntilSettled()
472
473 self.worker.release('.*-merge')
474 self.waitUntilSettled()
475 self.worker.release('.*-merge')
476 self.waitUntilSettled()
477 self.worker.release('.*-merge')
478 self.waitUntilSettled()
479
480 self.assertEqual(len(self.builds), 6)
481 self.assertEqual(self.builds[0].name, 'project-test1')
482 self.assertEqual(self.builds[1].name, 'project-test2')
483 self.assertEqual(self.builds[2].name, 'project-test1')
484 self.assertEqual(self.builds[3].name, 'project-test2')
485 self.assertEqual(self.builds[4].name, 'project-test1')
486 self.assertEqual(self.builds[5].name, 'project-test2')
487
488 self.assertTrue(self.job_has_changes(self.builds[0], A))
489 self.assertTrue(self.job_has_changes(self.builds[2], A))
490 self.assertTrue(self.job_has_changes(self.builds[2], B))
491 self.assertTrue(self.job_has_changes(self.builds[4], A))
492 self.assertTrue(self.job_has_changes(self.builds[4], B))
493 self.assertTrue(self.job_has_changes(self.builds[4], C))
494
495 # Fail change B first
496 self.release(self.builds[2])
497 self.waitUntilSettled()
498
499 # restart of C after B failure
500 self.worker.release('.*-merge')
501 self.waitUntilSettled()
502
503 self.assertEqual(len(self.builds), 5)
504 self.assertEqual(self.builds[0].name, 'project-test1')
505 self.assertEqual(self.builds[1].name, 'project-test2')
506 self.assertEqual(self.builds[2].name, 'project-test2')
507 self.assertEqual(self.builds[3].name, 'project-test1')
508 self.assertEqual(self.builds[4].name, 'project-test2')
509
510 self.assertTrue(self.job_has_changes(self.builds[1], A))
511 self.assertTrue(self.job_has_changes(self.builds[2], A))
512 self.assertTrue(self.job_has_changes(self.builds[2], B))
513 self.assertTrue(self.job_has_changes(self.builds[4], A))
514 self.assertFalse(self.job_has_changes(self.builds[4], B))
515 self.assertTrue(self.job_has_changes(self.builds[4], C))
516
517 # Finish running all passing jobs for change A
518 self.release(self.builds[1])
519 self.waitUntilSettled()
520 # Fail and report change A
521 self.release(self.builds[0])
522 self.waitUntilSettled()
523
524 # restart of B,C after A failure
525 self.worker.release('.*-merge')
526 self.waitUntilSettled()
527 self.worker.release('.*-merge')
528 self.waitUntilSettled()
529
530 self.assertEqual(len(self.builds), 4)
531 self.assertEqual(self.builds[0].name, 'project-test1') # B
532 self.assertEqual(self.builds[1].name, 'project-test2') # B
533 self.assertEqual(self.builds[2].name, 'project-test1') # C
534 self.assertEqual(self.builds[3].name, 'project-test2') # C
535
536 self.assertFalse(self.job_has_changes(self.builds[1], A))
537 self.assertTrue(self.job_has_changes(self.builds[1], B))
538 self.assertFalse(self.job_has_changes(self.builds[1], C))
539
540 self.assertFalse(self.job_has_changes(self.builds[2], A))
541 # After A failed and B and C restarted, B should be back in
542 # C's tests because it has not failed yet.
543 self.assertTrue(self.job_has_changes(self.builds[2], B))
544 self.assertTrue(self.job_has_changes(self.builds[2], C))
545
546 self.worker.hold_jobs_in_build = False
547 self.worker.release()
548 self.waitUntilSettled()
549
550 self.assertEqual(len(self.builds), 0)
551 self.assertEqual(len(self.history), 21)
552 self.assertEqual(A.data['status'], 'NEW')
553 self.assertEqual(B.data['status'], 'NEW')
554 self.assertEqual(C.data['status'], 'MERGED')
555 self.assertEqual(A.reported, 2)
556 self.assertEqual(B.reported, 2)
557 self.assertEqual(C.reported, 2)
558
James E. Blair8c803f82012-07-31 16:25:42 -0700559 def test_patch_order(self):
560 "Test that dependent patches are tested in the right order"
561 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
562 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
563 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
564 A.addApproval('CRVW', 2)
565 B.addApproval('CRVW', 2)
566 C.addApproval('CRVW', 2)
567
568 M2 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M2')
569 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
570 M2.setMerged()
571 M1.setMerged()
572
573 # C -> B -> A -> M1 -> M2
574 # M2 is here to make sure it is never queried. If it is, it
575 # means zuul is walking down the entire history of merged
576 # changes.
577
578 C.setDependsOn(B, 1)
579 B.setDependsOn(A, 1)
580 A.setDependsOn(M1, 1)
581 M1.setDependsOn(M2, 1)
582
583 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
584
585 self.waitUntilSettled()
586
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400587 self.assertEqual(A.data['status'], 'NEW')
588 self.assertEqual(B.data['status'], 'NEW')
589 self.assertEqual(C.data['status'], 'NEW')
James E. Blair8c803f82012-07-31 16:25:42 -0700590
591 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
592 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
593
594 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400595 self.assertEqual(M2.queried, 0)
596 self.assertEqual(A.data['status'], 'MERGED')
597 self.assertEqual(B.data['status'], 'MERGED')
598 self.assertEqual(C.data['status'], 'MERGED')
599 self.assertEqual(A.reported, 2)
600 self.assertEqual(B.reported, 2)
601 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700602
James E. Blair0e933c52013-07-11 10:18:52 -0700603 def test_trigger_cache(self):
604 "Test that the trigger cache operates correctly"
605 self.worker.hold_jobs_in_build = True
606
607 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
608 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
609 X = self.fake_gerrit.addFakeChange('org/project', 'master', 'X')
610 A.addApproval('CRVW', 2)
611 B.addApproval('CRVW', 2)
612
613 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
614 M1.setMerged()
615
616 B.setDependsOn(A, 1)
617 A.setDependsOn(M1, 1)
618
619 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
620 self.fake_gerrit.addEvent(X.getPatchsetCreatedEvent(1))
621
622 self.waitUntilSettled()
623
624 for build in self.builds:
625 if build.parameters['ZUUL_PIPELINE'] == 'check':
626 build.release()
627 self.waitUntilSettled()
628 for build in self.builds:
629 if build.parameters['ZUUL_PIPELINE'] == 'check':
630 build.release()
631 self.waitUntilSettled()
632
633 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
634 self.waitUntilSettled()
635
Antoine Mussof0506fa2014-06-03 15:03:38 +0200636 self.log.debug("len %s" % self.gerrit._change_cache.keys())
James E. Blair0e933c52013-07-11 10:18:52 -0700637 # there should still be changes in the cache
James E. Blair6c358e72013-07-29 17:06:47 -0700638 self.assertNotEqual(len(self.gerrit._change_cache.keys()), 0)
James E. Blair0e933c52013-07-11 10:18:52 -0700639
640 self.worker.hold_jobs_in_build = False
641 self.worker.release()
642 self.waitUntilSettled()
643
644 self.assertEqual(A.data['status'], 'MERGED')
645 self.assertEqual(B.data['status'], 'MERGED')
646 self.assertEqual(A.queried, 2) # Initial and isMerged
647 self.assertEqual(B.queried, 3) # Initial A, refresh from B, isMerged
648
James E. Blair8c803f82012-07-31 16:25:42 -0700649 def test_can_merge(self):
James E. Blair4886cc12012-07-18 15:39:41 -0700650 "Test whether a change is ready to merge"
James E. Blair8c803f82012-07-31 16:25:42 -0700651 # TODO: move to test_gerrit (this is a unit test!)
652 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair6c358e72013-07-29 17:06:47 -0700653 trigger = self.sched.layout.pipelines['gate'].trigger
654 a = self.sched.triggers['gerrit'].getChange(1, 2)
James E. Blaireff88162013-07-01 12:44:14 -0400655 mgr = self.sched.layout.pipelines['gate'].manager
James E. Blair6c358e72013-07-29 17:06:47 -0700656 self.assertFalse(trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700657
658 A.addApproval('CRVW', 2)
James E. Blair6c358e72013-07-29 17:06:47 -0700659 a = trigger.getChange(1, 2, refresh=True)
660 self.assertFalse(trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700661
662 A.addApproval('APRV', 1)
James E. Blair6c358e72013-07-29 17:06:47 -0700663 a = trigger.getChange(1, 2, refresh=True)
664 self.assertTrue(trigger.canMerge(a, mgr.getSubmitAllowNeeds()))
665 trigger.maintainCache([])
James E. Blair4886cc12012-07-18 15:39:41 -0700666
James E. Blair11041d22014-05-02 14:49:53 -0700667 def test_pipeline_requirements_closed_change(self):
668 "Test that pipeline requirements for closed changes are effective"
669 self.config.set('zuul', 'layout_config',
670 'tests/fixtures/layout-pipeline-requirements.yaml')
671 self.sched.reconfigure(self.config)
672
673 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
674 status='MERGED')
675 self.fake_gerrit.addEvent(A.addApproval('CRVW', 2))
676 self.waitUntilSettled()
677 self.assertEqual(len(self.history), 0)
678 self.assertEqual(len(self.builds), 0)
679
680 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B',
681 status='MERGED')
682 B.addApproval('CRVW', 2)
683 B.addApproval('VRFY', 1)
684 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
685 self.waitUntilSettled()
686 self.assertEqual(len(self.history), 0)
687 self.assertEqual(len(self.builds), 0)
688
689 for pipeline in self.sched.layout.pipelines.values():
690 pipeline.trigger.maintainCache([])
691
James E. Blair4886cc12012-07-18 15:39:41 -0700692 def test_build_configuration(self):
693 "Test that zuul merges the right commits for testing"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700694
695 self.gearman_server.hold_jobs_in_queue = True
James E. Blair4886cc12012-07-18 15:39:41 -0700696 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
697 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
698 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
699 A.addApproval('CRVW', 2)
700 B.addApproval('CRVW', 2)
701 C.addApproval('CRVW', 2)
702 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
703 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
704 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
705 self.waitUntilSettled()
706
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700707 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700708 self.waitUntilSettled()
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. Blair701c5b42013-06-06 09:34:59 -0700713 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700714 ref = self.getParameter(queue[-1], 'ZUUL_REF')
715 self.gearman_server.hold_jobs_in_queue = False
716 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700717 self.waitUntilSettled()
James E. Blair4886cc12012-07-18 15:39:41 -0700718
Monty Taylorbc758832013-06-17 17:22:42 -0400719 path = os.path.join(self.git_root, "org/project")
James E. Blair4886cc12012-07-18 15:39:41 -0700720 repo = git.Repo(path)
721 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
722 repo_messages.reverse()
James E. Blair4886cc12012-07-18 15:39:41 -0700723 correct_messages = ['initial commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400724 self.assertEqual(repo_messages, correct_messages)
James E. Blair973721f2012-08-15 10:19:43 -0700725
726 def test_build_configuration_conflict(self):
727 "Test that merge conflicts are handled"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700728
729 self.gearman_server.hold_jobs_in_queue = True
James E. Blair6736beb2013-07-11 15:18:15 -0700730 A = self.fake_gerrit.addFakeChange('org/conflict-project',
731 'master', 'A')
James E. Blair973721f2012-08-15 10:19:43 -0700732 A.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700733 B = self.fake_gerrit.addFakeChange('org/conflict-project',
734 'master', 'B')
James E. Blair973721f2012-08-15 10:19:43 -0700735 B.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700736 C = self.fake_gerrit.addFakeChange('org/conflict-project',
737 'master', 'C')
James E. Blair973721f2012-08-15 10:19:43 -0700738 A.addApproval('CRVW', 2)
739 B.addApproval('CRVW', 2)
740 C.addApproval('CRVW', 2)
741 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
742 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
743 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
744 self.waitUntilSettled()
745
James E. Blair6736beb2013-07-11 15:18:15 -0700746 self.assertEqual(A.reported, 1)
747 self.assertEqual(B.reported, 1)
748 self.assertEqual(C.reported, 1)
749
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700750 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700751 self.waitUntilSettled()
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. Blair972e3c72013-08-29 12:04:55 -0700756
757 self.assertEqual(len(self.history), 2) # A and C merge jobs
758
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700759 self.gearman_server.hold_jobs_in_queue = False
760 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700761 self.waitUntilSettled()
762
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400763 self.assertEqual(A.data['status'], 'MERGED')
764 self.assertEqual(B.data['status'], 'NEW')
765 self.assertEqual(C.data['status'], 'MERGED')
766 self.assertEqual(A.reported, 2)
767 self.assertEqual(B.reported, 2)
768 self.assertEqual(C.reported, 2)
James E. Blair972e3c72013-08-29 12:04:55 -0700769 self.assertEqual(len(self.history), 6)
James E. Blair6736beb2013-07-11 15:18:15 -0700770
James E. Blairdaabed22012-08-15 15:38:57 -0700771 def test_post(self):
772 "Test that post jobs run"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700773
Zhongyue Luo5d556072012-09-21 02:00:47 +0900774 e = {
775 "type": "ref-updated",
776 "submitter": {
777 "name": "User Name",
778 },
779 "refUpdate": {
780 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
781 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
782 "refName": "master",
783 "project": "org/project",
784 }
785 }
James E. Blairdaabed22012-08-15 15:38:57 -0700786 self.fake_gerrit.addEvent(e)
787 self.waitUntilSettled()
788
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400789 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400790 self.assertEqual(len(self.history), 1)
791 self.assertIn('project-post', job_names)
James E. Blairc6294a52012-08-17 10:19:48 -0700792
793 def test_build_configuration_branch(self):
794 "Test that the right commits are on alternate branches"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700795
796 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -0700797 A = self.fake_gerrit.addFakeChange('org/project', 'mp', 'A')
798 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
799 C = self.fake_gerrit.addFakeChange('org/project', 'mp', 'C')
800 A.addApproval('CRVW', 2)
801 B.addApproval('CRVW', 2)
802 C.addApproval('CRVW', 2)
803 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
804 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
805 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
806 self.waitUntilSettled()
807
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700808 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -0700809 self.waitUntilSettled()
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. Blair701c5b42013-06-06 09:34:59 -0700814 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700815 ref = self.getParameter(queue[-1], 'ZUUL_REF')
816 self.gearman_server.hold_jobs_in_queue = False
817 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -0700818 self.waitUntilSettled()
819
Monty Taylorbc758832013-06-17 17:22:42 -0400820 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -0700821 repo = git.Repo(path)
822 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
823 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -0700824 correct_messages = ['initial commit', 'mp commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400825 self.assertEqual(repo_messages, correct_messages)
James E. Blairc6294a52012-08-17 10:19:48 -0700826
827 def test_build_configuration_branch_interaction(self):
828 "Test that switching between branches works"
829 self.test_build_configuration()
830 self.test_build_configuration_branch()
831 # C has been merged, undo that
Monty Taylorbc758832013-06-17 17:22:42 -0400832 path = os.path.join(self.upstream_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -0700833 repo = git.Repo(path)
834 repo.heads.master.commit = repo.commit('init')
835 self.test_build_configuration()
836
837 def test_build_configuration_multi_branch(self):
838 "Test that dependent changes on multiple branches are merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700839
840 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -0700841 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
842 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
843 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
844 A.addApproval('CRVW', 2)
845 B.addApproval('CRVW', 2)
846 C.addApproval('CRVW', 2)
847 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
848 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
849 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
850 self.waitUntilSettled()
James E. Blairbb1fe502014-03-04 10:15:06 -0800851 queue = self.gearman_server.getQueue()
852 job_A = None
853 for job in queue:
854 if 'project-merge' in job.name:
855 job_A = job
856 ref_A = self.getParameter(job_A, 'ZUUL_REF')
857 commit_A = self.getParameter(job_A, 'ZUUL_COMMIT')
858 self.log.debug("Got Zuul ref for change A: %s" % ref_A)
859 self.log.debug("Got Zuul commit for change A: %s" % commit_A)
James E. Blairc6294a52012-08-17 10:19:48 -0700860
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700861 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -0700862 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700863 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -0700864 job_B = None
865 for job in queue:
866 if 'project-merge' in job.name:
867 job_B = job
868 ref_B = self.getParameter(job_B, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -0800869 commit_B = self.getParameter(job_B, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -0700870 self.log.debug("Got Zuul ref for change B: %s" % ref_B)
James E. Blairbb1fe502014-03-04 10:15:06 -0800871 self.log.debug("Got Zuul commit for change B: %s" % commit_B)
872
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700873 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -0700874 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700875 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -0700876 for job in queue:
877 if 'project-merge' in job.name:
878 job_C = job
879 ref_C = self.getParameter(job_C, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -0800880 commit_C = self.getParameter(job_C, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -0700881 self.log.debug("Got Zuul ref for change C: %s" % ref_C)
James E. Blairbb1fe502014-03-04 10:15:06 -0800882 self.log.debug("Got Zuul commit for change C: %s" % commit_C)
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700883 self.gearman_server.hold_jobs_in_queue = False
884 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -0700885 self.waitUntilSettled()
886
Monty Taylorbc758832013-06-17 17:22:42 -0400887 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -0700888 repo = git.Repo(path)
889
890 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -0700891 for c in repo.iter_commits(ref_C)]
James E. Blairbb1fe502014-03-04 10:15:06 -0800892 repo_shas = [c.hexsha for c in repo.iter_commits(ref_C)]
James E. Blairc6294a52012-08-17 10:19:48 -0700893 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -0700894 correct_messages = ['initial commit', 'A-1', 'C-1']
James E. Blairbb1fe502014-03-04 10:15:06 -0800895 # Ensure the right commits are in the history for this ref
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400896 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -0800897 # Ensure ZUUL_REF -> ZUUL_COMMIT
898 self.assertEqual(repo_shas[0], commit_C)
James E. Blairc6294a52012-08-17 10:19:48 -0700899
900 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -0700901 for c in repo.iter_commits(ref_B)]
James E. Blairbb1fe502014-03-04 10:15:06 -0800902 repo_shas = [c.hexsha for c in repo.iter_commits(ref_B)]
James E. Blairc6294a52012-08-17 10:19:48 -0700903 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -0700904 correct_messages = ['initial commit', 'mp commit', 'B-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400905 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -0800906 self.assertEqual(repo_shas[0], commit_B)
907
908 repo_messages = [c.message.strip()
909 for c in repo.iter_commits(ref_A)]
910 repo_shas = [c.hexsha for c in repo.iter_commits(ref_A)]
911 repo_messages.reverse()
912 correct_messages = ['initial commit', 'A-1']
913 self.assertEqual(repo_messages, correct_messages)
914 self.assertEqual(repo_shas[0], commit_A)
915
916 self.assertNotEqual(ref_A, ref_B, ref_C)
917 self.assertNotEqual(commit_A, commit_B, commit_C)
James E. Blair7f71c802012-08-22 13:04:32 -0700918
919 def test_one_job_project(self):
920 "Test that queueing works with one job"
921 A = self.fake_gerrit.addFakeChange('org/one-job-project',
922 'master', 'A')
923 B = self.fake_gerrit.addFakeChange('org/one-job-project',
924 'master', 'B')
925 A.addApproval('CRVW', 2)
926 B.addApproval('CRVW', 2)
927 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
928 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
929 self.waitUntilSettled()
930
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400931 self.assertEqual(A.data['status'], 'MERGED')
932 self.assertEqual(A.reported, 2)
933 self.assertEqual(B.data['status'], 'MERGED')
934 self.assertEqual(B.reported, 2)
James E. Blaircaec0c52012-08-22 14:52:22 -0700935
Antoine Musso80edd5a2013-02-13 15:37:53 +0100936 def test_job_from_templates_launched(self):
937 "Test whether a job generated via a template can be launched"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700938
Antoine Musso80edd5a2013-02-13 15:37:53 +0100939 A = self.fake_gerrit.addFakeChange(
940 'org/templated-project', 'master', 'A')
941 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
942 self.waitUntilSettled()
Antoine Musso80edd5a2013-02-13 15:37:53 +0100943
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400944 self.assertEqual(self.getJobFromHistory('project-test1').result,
945 'SUCCESS')
946 self.assertEqual(self.getJobFromHistory('project-test2').result,
947 'SUCCESS')
Antoine Musso80edd5a2013-02-13 15:37:53 +0100948
James E. Blair3e98c022013-12-16 15:25:38 -0800949 def test_layered_templates(self):
950 "Test whether a job generated via a template can be launched"
951
952 A = self.fake_gerrit.addFakeChange(
953 'org/layered-project', 'master', 'A')
954 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
955 self.waitUntilSettled()
956
957 self.assertEqual(self.getJobFromHistory('project-test1').result,
958 'SUCCESS')
959 self.assertEqual(self.getJobFromHistory('project-test2').result,
960 'SUCCESS')
James E. Blairaea6cf62013-12-16 15:38:12 -0800961 self.assertEqual(self.getJobFromHistory('layered-project-test3'
962 ).result, 'SUCCESS')
963 self.assertEqual(self.getJobFromHistory('layered-project-test4'
964 ).result, 'SUCCESS')
James E. Blair12a92b12014-03-26 11:54:53 -0700965 self.assertEqual(self.getJobFromHistory('layered-project-foo-test5'
966 ).result, 'SUCCESS')
James E. Blair3e98c022013-12-16 15:25:38 -0800967 self.assertEqual(self.getJobFromHistory('project-test6').result,
968 'SUCCESS')
969
James E. Blaircaec0c52012-08-22 14:52:22 -0700970 def test_dependent_changes_dequeue(self):
971 "Test that dependent patches are not needlessly tested"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700972
James E. Blaircaec0c52012-08-22 14:52:22 -0700973 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
974 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
975 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
976 A.addApproval('CRVW', 2)
977 B.addApproval('CRVW', 2)
978 C.addApproval('CRVW', 2)
979
980 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
981 M1.setMerged()
982
983 # C -> B -> A -> M1
984
985 C.setDependsOn(B, 1)
986 B.setDependsOn(A, 1)
987 A.setDependsOn(M1, 1)
988
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700989 self.worker.addFailTest('project-merge', A)
James E. Blaircaec0c52012-08-22 14:52:22 -0700990
991 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
992 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
993 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
994
995 self.waitUntilSettled()
996
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400997 self.assertEqual(A.data['status'], 'NEW')
998 self.assertEqual(A.reported, 2)
999 self.assertEqual(B.data['status'], 'NEW')
1000 self.assertEqual(B.reported, 2)
1001 self.assertEqual(C.data['status'], 'NEW')
1002 self.assertEqual(C.reported, 2)
1003 self.assertEqual(len(self.history), 1)
James E. Blairec590122012-08-22 15:19:31 -07001004
James E. Blair972e3c72013-08-29 12:04:55 -07001005 def test_failing_dependent_changes(self):
1006 "Test that failing dependent patches are taken out of stream"
1007 self.worker.hold_jobs_in_build = True
1008 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1009 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1010 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1011 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1012 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
1013 A.addApproval('CRVW', 2)
1014 B.addApproval('CRVW', 2)
1015 C.addApproval('CRVW', 2)
1016 D.addApproval('CRVW', 2)
1017 E.addApproval('CRVW', 2)
1018
1019 # E, D -> C -> B, A
1020
1021 D.setDependsOn(C, 1)
1022 C.setDependsOn(B, 1)
1023
1024 self.worker.addFailTest('project-test1', B)
1025
1026 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1027 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1028 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1029 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1030 self.fake_gerrit.addEvent(E.addApproval('APRV', 1))
1031
1032 self.waitUntilSettled()
1033 self.worker.release('.*-merge')
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
1044 self.worker.hold_jobs_in_build = False
1045 for build in self.builds:
1046 if build.parameters['ZUUL_CHANGE'] != '1':
1047 build.release()
1048 self.waitUntilSettled()
1049
1050 self.worker.release()
1051 self.waitUntilSettled()
1052
1053 self.assertEqual(A.data['status'], 'MERGED')
1054 self.assertEqual(A.reported, 2)
1055 self.assertEqual(B.data['status'], 'NEW')
1056 self.assertEqual(B.reported, 2)
1057 self.assertEqual(C.data['status'], 'NEW')
1058 self.assertEqual(C.reported, 2)
1059 self.assertEqual(D.data['status'], 'NEW')
1060 self.assertEqual(D.reported, 2)
1061 self.assertEqual(E.data['status'], 'MERGED')
1062 self.assertEqual(E.reported, 2)
1063 self.assertEqual(len(self.history), 18)
1064
James E. Blairec590122012-08-22 15:19:31 -07001065 def test_head_is_dequeued_once(self):
James E. Blair2fa50962013-01-30 21:50:41 -08001066 "Test that if a change at the head fails it is dequeued only once"
James E. Blairec590122012-08-22 15:19:31 -07001067 # If it's dequeued more than once, we should see extra
1068 # aborted jobs.
James E. Blairec590122012-08-22 15:19:31 -07001069
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001070 self.worker.hold_jobs_in_build = True
James E. Blairec590122012-08-22 15:19:31 -07001071 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1072 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1073 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
1074 A.addApproval('CRVW', 2)
1075 B.addApproval('CRVW', 2)
1076 C.addApproval('CRVW', 2)
1077
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001078 self.worker.addFailTest('project1-test1', A)
1079 self.worker.addFailTest('project1-test2', A)
1080 self.worker.addFailTest('project1-project2-integration', A)
James E. Blairec590122012-08-22 15:19:31 -07001081
1082 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1083 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1084 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1085
1086 self.waitUntilSettled()
James E. Blairec590122012-08-22 15:19:31 -07001087
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001088 self.assertEqual(len(self.builds), 1)
1089 self.assertEqual(self.builds[0].name, 'project1-merge')
1090 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blairec590122012-08-22 15:19:31 -07001091
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001092 self.worker.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001093 self.waitUntilSettled()
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()
1098
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001099 self.assertEqual(len(self.builds), 9)
1100 self.assertEqual(self.builds[0].name, 'project1-test1')
1101 self.assertEqual(self.builds[1].name, 'project1-test2')
1102 self.assertEqual(self.builds[2].name, 'project1-project2-integration')
1103 self.assertEqual(self.builds[3].name, 'project1-test1')
1104 self.assertEqual(self.builds[4].name, 'project1-test2')
1105 self.assertEqual(self.builds[5].name, 'project1-project2-integration')
1106 self.assertEqual(self.builds[6].name, 'project1-test1')
1107 self.assertEqual(self.builds[7].name, 'project1-test2')
1108 self.assertEqual(self.builds[8].name, 'project1-project2-integration')
James E. Blairec590122012-08-22 15:19:31 -07001109
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001110 self.release(self.builds[0])
James E. Blairec590122012-08-22 15:19:31 -07001111 self.waitUntilSettled()
1112
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001113 self.assertEqual(len(self.builds), 3) # test2,integration, merge for B
1114 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 6)
James E. Blairec590122012-08-22 15:19:31 -07001115
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001116 self.worker.hold_jobs_in_build = False
1117 self.worker.release()
James E. Blairec590122012-08-22 15:19:31 -07001118 self.waitUntilSettled()
1119
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001120 self.assertEqual(len(self.builds), 0)
1121 self.assertEqual(len(self.history), 20)
James E. Blaircaec0c52012-08-22 14:52:22 -07001122
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001123 self.assertEqual(A.data['status'], 'NEW')
1124 self.assertEqual(B.data['status'], 'MERGED')
1125 self.assertEqual(C.data['status'], 'MERGED')
1126 self.assertEqual(A.reported, 2)
1127 self.assertEqual(B.reported, 2)
1128 self.assertEqual(C.reported, 2)
James E. Blair4ec821f2012-08-23 15:28:28 -07001129
1130 def test_nonvoting_job(self):
1131 "Test that non-voting jobs don't vote."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001132
James E. Blair4ec821f2012-08-23 15:28:28 -07001133 A = self.fake_gerrit.addFakeChange('org/nonvoting-project',
1134 'master', 'A')
1135 A.addApproval('CRVW', 2)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001136 self.worker.addFailTest('nonvoting-project-test2', A)
James E. Blair4ec821f2012-08-23 15:28:28 -07001137 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1138
1139 self.waitUntilSettled()
James E. Blair4ec821f2012-08-23 15:28:28 -07001140
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001141 self.assertEqual(A.data['status'], 'MERGED')
1142 self.assertEqual(A.reported, 2)
1143 self.assertEqual(
1144 self.getJobFromHistory('nonvoting-project-merge').result,
1145 'SUCCESS')
1146 self.assertEqual(
1147 self.getJobFromHistory('nonvoting-project-test1').result,
1148 'SUCCESS')
1149 self.assertEqual(
1150 self.getJobFromHistory('nonvoting-project-test2').result,
1151 'FAILURE')
James E. Blaire0487072012-08-29 17:38:31 -07001152
1153 def test_check_queue_success(self):
1154 "Test successful check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001155
James E. Blaire0487072012-08-29 17:38:31 -07001156 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1157 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1158
1159 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001160
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001161 self.assertEqual(A.data['status'], 'NEW')
1162 self.assertEqual(A.reported, 1)
1163 self.assertEqual(self.getJobFromHistory('project-merge').result,
1164 'SUCCESS')
1165 self.assertEqual(self.getJobFromHistory('project-test1').result,
1166 'SUCCESS')
1167 self.assertEqual(self.getJobFromHistory('project-test2').result,
1168 'SUCCESS')
James E. Blaire0487072012-08-29 17:38:31 -07001169
1170 def test_check_queue_failure(self):
1171 "Test failed check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001172
James E. Blaire0487072012-08-29 17:38:31 -07001173 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001174 self.worker.addFailTest('project-test2', A)
James E. Blaire0487072012-08-29 17:38:31 -07001175 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1176
1177 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001178
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001179 self.assertEqual(A.data['status'], 'NEW')
1180 self.assertEqual(A.reported, 1)
1181 self.assertEqual(self.getJobFromHistory('project-merge').result,
James E. Blair78e31b32013-07-09 09:11:34 -07001182 'SUCCESS')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001183 self.assertEqual(self.getJobFromHistory('project-test1').result,
1184 'SUCCESS')
1185 self.assertEqual(self.getJobFromHistory('project-test2').result,
1186 'FAILURE')
James E. Blair127bc182012-08-28 15:55:15 -07001187
1188 def test_dependent_behind_dequeue(self):
1189 "test that dependent changes behind dequeued changes work"
1190 # This complicated test is a reproduction of a real life bug
1191 self.sched.reconfigure(self.config)
James E. Blair127bc182012-08-28 15:55:15 -07001192
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001193 self.worker.hold_jobs_in_build = True
James E. Blair127bc182012-08-28 15:55:15 -07001194 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1195 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1196 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
1197 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
1198 E = self.fake_gerrit.addFakeChange('org/project2', 'master', 'E')
1199 F = self.fake_gerrit.addFakeChange('org/project3', 'master', 'F')
1200 D.setDependsOn(C, 1)
1201 E.setDependsOn(D, 1)
1202 A.addApproval('CRVW', 2)
1203 B.addApproval('CRVW', 2)
1204 C.addApproval('CRVW', 2)
1205 D.addApproval('CRVW', 2)
1206 E.addApproval('CRVW', 2)
1207 F.addApproval('CRVW', 2)
1208
1209 A.fail_merge = True
James E. Blair127bc182012-08-28 15:55:15 -07001210
1211 # Change object re-use in the gerrit trigger is hidden if
1212 # changes are added in quick succession; waiting makes it more
1213 # like real life.
1214 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1215 self.waitUntilSettled()
1216 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1217 self.waitUntilSettled()
1218
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001219 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001220 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001221 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001222 self.waitUntilSettled()
1223
1224 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1225 self.waitUntilSettled()
1226 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1227 self.waitUntilSettled()
1228 self.fake_gerrit.addEvent(E.addApproval('APRV', 1))
1229 self.waitUntilSettled()
1230 self.fake_gerrit.addEvent(F.addApproval('APRV', 1))
1231 self.waitUntilSettled()
1232
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001233 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001234 self.waitUntilSettled()
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()
1241
1242 # all jobs running
James E. Blaire955e062012-10-08 09:49:03 -07001243
1244 # Grab pointers to the jobs we want to release before
1245 # releasing any, because list indexes may change as
1246 # the jobs complete.
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001247 a, b, c = self.builds[:3]
James E. Blaire955e062012-10-08 09:49:03 -07001248 a.release()
1249 b.release()
1250 c.release()
James E. Blair127bc182012-08-28 15:55:15 -07001251 self.waitUntilSettled()
1252
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001253 self.worker.hold_jobs_in_build = False
1254 self.worker.release()
James E. Blair127bc182012-08-28 15:55:15 -07001255 self.waitUntilSettled()
1256
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001257 self.assertEqual(A.data['status'], 'NEW')
1258 self.assertEqual(B.data['status'], 'MERGED')
1259 self.assertEqual(C.data['status'], 'MERGED')
1260 self.assertEqual(D.data['status'], 'MERGED')
1261 self.assertEqual(E.data['status'], 'MERGED')
1262 self.assertEqual(F.data['status'], 'MERGED')
James E. Blair127bc182012-08-28 15:55:15 -07001263
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001264 self.assertEqual(A.reported, 2)
1265 self.assertEqual(B.reported, 2)
1266 self.assertEqual(C.reported, 2)
1267 self.assertEqual(D.reported, 2)
1268 self.assertEqual(E.reported, 2)
1269 self.assertEqual(F.reported, 2)
James E. Blair127bc182012-08-28 15:55:15 -07001270
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001271 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 15)
1272 self.assertEqual(len(self.history), 44)
James E. Blair05fed602012-09-07 12:45:24 -07001273
1274 def test_merger_repack(self):
1275 "Test that the merger works after a repack"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001276
James E. Blair05fed602012-09-07 12:45:24 -07001277 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1278 A.addApproval('CRVW', 2)
1279 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1280 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001281 self.assertEqual(self.getJobFromHistory('project-merge').result,
1282 'SUCCESS')
1283 self.assertEqual(self.getJobFromHistory('project-test1').result,
1284 'SUCCESS')
1285 self.assertEqual(self.getJobFromHistory('project-test2').result,
1286 'SUCCESS')
1287 self.assertEqual(A.data['status'], 'MERGED')
1288 self.assertEqual(A.reported, 2)
James E. Blair05fed602012-09-07 12:45:24 -07001289 self.assertEmptyQueues()
James E. Blair4ca985f2013-05-30 12:27:43 -07001290 self.worker.build_history = []
James E. Blair05fed602012-09-07 12:45:24 -07001291
Monty Taylorbc758832013-06-17 17:22:42 -04001292 path = os.path.join(self.git_root, "org/project")
1293 print repack_repo(path)
James E. Blair05fed602012-09-07 12:45:24 -07001294
1295 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1296 A.addApproval('CRVW', 2)
1297 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1298 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001299 self.assertEqual(self.getJobFromHistory('project-merge').result,
1300 'SUCCESS')
1301 self.assertEqual(self.getJobFromHistory('project-test1').result,
1302 'SUCCESS')
1303 self.assertEqual(self.getJobFromHistory('project-test2').result,
1304 'SUCCESS')
1305 self.assertEqual(A.data['status'], 'MERGED')
1306 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001307
James E. Blair4886f282012-11-15 09:27:33 -08001308 def test_merger_repack_large_change(self):
1309 "Test that the merger works with large changes after a repack"
1310 # https://bugs.launchpad.net/zuul/+bug/1078946
James E. Blairac2c3242014-01-24 13:38:51 -08001311 # This test assumes the repo is already cloned; make sure it is
1312 url = self.sched.triggers['gerrit'].getGitUrl(
1313 self.sched.layout.projects['org/project1'])
James E. Blair4076e2b2014-01-28 12:42:20 -08001314 self.merge_server.merger.addProject('org/project1', url)
James E. Blair4886f282012-11-15 09:27:33 -08001315 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1316 A.addPatchset(large=True)
Monty Taylorbc758832013-06-17 17:22:42 -04001317 path = os.path.join(self.upstream_root, "org/project1")
1318 print repack_repo(path)
1319 path = os.path.join(self.git_root, "org/project1")
1320 print repack_repo(path)
James E. Blair4886f282012-11-15 09:27:33 -08001321
1322 A.addApproval('CRVW', 2)
1323 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1324 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001325 self.assertEqual(self.getJobFromHistory('project1-merge').result,
1326 'SUCCESS')
1327 self.assertEqual(self.getJobFromHistory('project1-test1').result,
1328 'SUCCESS')
1329 self.assertEqual(self.getJobFromHistory('project1-test2').result,
1330 'SUCCESS')
1331 self.assertEqual(A.data['status'], 'MERGED')
1332 self.assertEqual(A.reported, 2)
James E. Blair4886f282012-11-15 09:27:33 -08001333
James E. Blair7ee88a22012-09-12 18:59:31 +02001334 def test_nonexistent_job(self):
1335 "Test launching a job that doesn't exist"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001336 # Set to the state immediately after a restart
1337 self.resetGearmanServer()
1338 self.launcher.negative_function_cache_ttl = 0
James E. Blair7ee88a22012-09-12 18:59:31 +02001339
1340 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1341 A.addApproval('CRVW', 2)
1342 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1343 # There may be a thread about to report a lost change
1344 while A.reported < 2:
1345 self.waitUntilSettled()
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001346 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001347 self.assertFalse(job_names)
1348 self.assertEqual(A.data['status'], 'NEW')
1349 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001350 self.assertEmptyQueues()
1351
1352 # Make sure things still work:
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001353 self.registerJobs()
James E. Blair7ee88a22012-09-12 18:59:31 +02001354 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1355 A.addApproval('CRVW', 2)
1356 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1357 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001358 self.assertEqual(self.getJobFromHistory('project-merge').result,
1359 'SUCCESS')
1360 self.assertEqual(self.getJobFromHistory('project-test1').result,
1361 'SUCCESS')
1362 self.assertEqual(self.getJobFromHistory('project-test2').result,
1363 'SUCCESS')
1364 self.assertEqual(A.data['status'], 'MERGED')
1365 self.assertEqual(A.reported, 2)
James E. Blairf62d4282012-12-31 17:01:50 -08001366
1367 def test_single_nonexistent_post_job(self):
1368 "Test launching a single post job that doesn't exist"
James E. Blairf62d4282012-12-31 17:01:50 -08001369 e = {
1370 "type": "ref-updated",
1371 "submitter": {
1372 "name": "User Name",
1373 },
1374 "refUpdate": {
1375 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
1376 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
1377 "refName": "master",
1378 "project": "org/project",
1379 }
1380 }
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001381 # Set to the state immediately after a restart
1382 self.resetGearmanServer()
1383 self.launcher.negative_function_cache_ttl = 0
1384
James E. Blairf62d4282012-12-31 17:01:50 -08001385 self.fake_gerrit.addEvent(e)
1386 self.waitUntilSettled()
1387
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001388 self.assertEqual(len(self.history), 0)
James E. Blair2fa50962013-01-30 21:50:41 -08001389
1390 def test_new_patchset_dequeues_old(self):
1391 "Test that a new patchset causes the old to be dequeued"
1392 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001393 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001394 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1395 M.setMerged()
1396
1397 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1398 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1399 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1400 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1401 A.addApproval('CRVW', 2)
1402 B.addApproval('CRVW', 2)
1403 C.addApproval('CRVW', 2)
1404 D.addApproval('CRVW', 2)
1405
1406 C.setDependsOn(B, 1)
1407 B.setDependsOn(A, 1)
1408 A.setDependsOn(M, 1)
1409
1410 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1411 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1412 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1413 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1414 self.waitUntilSettled()
1415
1416 B.addPatchset()
1417 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1418 self.waitUntilSettled()
1419
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001420 self.worker.hold_jobs_in_build = False
1421 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001422 self.waitUntilSettled()
1423
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001424 self.assertEqual(A.data['status'], 'MERGED')
1425 self.assertEqual(A.reported, 2)
1426 self.assertEqual(B.data['status'], 'NEW')
1427 self.assertEqual(B.reported, 2)
1428 self.assertEqual(C.data['status'], 'NEW')
1429 self.assertEqual(C.reported, 2)
1430 self.assertEqual(D.data['status'], 'MERGED')
1431 self.assertEqual(D.reported, 2)
1432 self.assertEqual(len(self.history), 9) # 3 each for A, B, D.
James E. Blair2fa50962013-01-30 21:50:41 -08001433
Arx Cruzb1b010d2013-10-28 19:49:59 -02001434 def test_zuul_url_return(self):
1435 "Test if ZUUL_URL is returning when zuul_url is set in zuul.conf"
James E. Blair4076e2b2014-01-28 12:42:20 -08001436 self.assertTrue(self.sched.config.has_option('merger', 'zuul_url'))
Arx Cruzb1b010d2013-10-28 19:49:59 -02001437 self.worker.hold_jobs_in_build = True
1438
1439 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1440 A.addApproval('CRVW', 2)
1441 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1442 self.waitUntilSettled()
1443
1444 self.assertEqual(len(self.builds), 1)
1445 for build in self.builds:
1446 self.assertTrue('ZUUL_URL' in build.parameters)
1447
1448 self.worker.hold_jobs_in_build = False
1449 self.worker.release()
1450 self.waitUntilSettled()
1451
James E. Blair2fa50962013-01-30 21:50:41 -08001452 def test_new_patchset_dequeues_old_on_head(self):
1453 "Test that a new patchset causes the old to be dequeued (at head)"
1454 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001455 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001456 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1457 M.setMerged()
1458 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1459 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1460 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1461 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1462 A.addApproval('CRVW', 2)
1463 B.addApproval('CRVW', 2)
1464 C.addApproval('CRVW', 2)
1465 D.addApproval('CRVW', 2)
1466
1467 C.setDependsOn(B, 1)
1468 B.setDependsOn(A, 1)
1469 A.setDependsOn(M, 1)
1470
1471 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1472 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1473 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1474 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1475 self.waitUntilSettled()
1476
1477 A.addPatchset()
1478 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1479 self.waitUntilSettled()
1480
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001481 self.worker.hold_jobs_in_build = False
1482 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001483 self.waitUntilSettled()
1484
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001485 self.assertEqual(A.data['status'], 'NEW')
1486 self.assertEqual(A.reported, 2)
1487 self.assertEqual(B.data['status'], 'NEW')
1488 self.assertEqual(B.reported, 2)
1489 self.assertEqual(C.data['status'], 'NEW')
1490 self.assertEqual(C.reported, 2)
1491 self.assertEqual(D.data['status'], 'MERGED')
1492 self.assertEqual(D.reported, 2)
1493 self.assertEqual(len(self.history), 7)
James E. Blair2fa50962013-01-30 21:50:41 -08001494
1495 def test_new_patchset_dequeues_old_without_dependents(self):
1496 "Test that a new patchset causes only the old to be dequeued"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001497 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001498 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1499 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1500 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1501 A.addApproval('CRVW', 2)
1502 B.addApproval('CRVW', 2)
1503 C.addApproval('CRVW', 2)
1504
1505 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1506 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1507 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1508 self.waitUntilSettled()
1509
1510 B.addPatchset()
1511 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1512 self.waitUntilSettled()
1513
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001514 self.worker.hold_jobs_in_build = False
1515 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001516 self.waitUntilSettled()
1517
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001518 self.assertEqual(A.data['status'], 'MERGED')
1519 self.assertEqual(A.reported, 2)
1520 self.assertEqual(B.data['status'], 'NEW')
1521 self.assertEqual(B.reported, 2)
1522 self.assertEqual(C.data['status'], 'MERGED')
1523 self.assertEqual(C.reported, 2)
1524 self.assertEqual(len(self.history), 9)
James E. Blair2fa50962013-01-30 21:50:41 -08001525
1526 def test_new_patchset_dequeues_old_independent_queue(self):
1527 "Test that a new patchset causes the old to be dequeued (independent)"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001528 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001529 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1530 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1531 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1532 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1533 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1534 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
1535 self.waitUntilSettled()
1536
1537 B.addPatchset()
1538 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1539 self.waitUntilSettled()
1540
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001541 self.worker.hold_jobs_in_build = False
1542 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001543 self.waitUntilSettled()
1544
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001545 self.assertEqual(A.data['status'], 'NEW')
1546 self.assertEqual(A.reported, 1)
1547 self.assertEqual(B.data['status'], 'NEW')
1548 self.assertEqual(B.reported, 1)
1549 self.assertEqual(C.data['status'], 'NEW')
1550 self.assertEqual(C.reported, 1)
1551 self.assertEqual(len(self.history), 10)
1552 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 1)
James E. Blair7d0dedc2013-02-21 17:26:09 -08001553
James E. Blair18c64442014-03-18 10:14:45 -07001554 def test_noop_job(self):
1555 "Test that the internal noop job works"
1556 A = self.fake_gerrit.addFakeChange('org/noop-project', 'master', 'A')
1557 A.addApproval('CRVW', 2)
1558 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1559 self.waitUntilSettled()
1560
1561 self.assertEqual(len(self.gearman_server.getQueue()), 0)
1562 self.assertTrue(self.sched._areAllBuildsComplete())
1563 self.assertEqual(len(self.history), 0)
1564 self.assertEqual(A.data['status'], 'MERGED')
1565 self.assertEqual(A.reported, 2)
1566
James E. Blair7d0dedc2013-02-21 17:26:09 -08001567 def test_zuul_refs(self):
1568 "Test that zuul refs exist and have the right changes"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001569 self.worker.hold_jobs_in_build = True
James E. Blair7d0dedc2013-02-21 17:26:09 -08001570 M1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'M1')
1571 M1.setMerged()
1572 M2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'M2')
1573 M2.setMerged()
1574
1575 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1576 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1577 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
1578 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
1579 A.addApproval('CRVW', 2)
1580 B.addApproval('CRVW', 2)
1581 C.addApproval('CRVW', 2)
1582 D.addApproval('CRVW', 2)
1583 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1584 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1585 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1586 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1587
1588 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001589 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08001590 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()
1597
James E. Blair7d0dedc2013-02-21 17:26:09 -08001598 a_zref = b_zref = c_zref = d_zref = None
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001599 for x in self.builds:
James E. Blair7d0dedc2013-02-21 17:26:09 -08001600 if x.parameters['ZUUL_CHANGE'] == '3':
1601 a_zref = x.parameters['ZUUL_REF']
1602 if x.parameters['ZUUL_CHANGE'] == '4':
1603 b_zref = x.parameters['ZUUL_REF']
1604 if x.parameters['ZUUL_CHANGE'] == '5':
1605 c_zref = x.parameters['ZUUL_REF']
1606 if x.parameters['ZUUL_CHANGE'] == '6':
1607 d_zref = x.parameters['ZUUL_REF']
1608
1609 # There are... four... refs.
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001610 self.assertIsNotNone(a_zref)
1611 self.assertIsNotNone(b_zref)
1612 self.assertIsNotNone(c_zref)
1613 self.assertIsNotNone(d_zref)
James E. Blair7d0dedc2013-02-21 17:26:09 -08001614
1615 # And they should all be different
1616 refs = set([a_zref, b_zref, c_zref, d_zref])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001617 self.assertEqual(len(refs), 4)
James E. Blair7d0dedc2013-02-21 17:26:09 -08001618
1619 # a ref should have a, not b, and should not be in project2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001620 self.assertTrue(self.ref_has_change(a_zref, A))
1621 self.assertFalse(self.ref_has_change(a_zref, B))
1622 self.assertFalse(self.ref_has_change(a_zref, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08001623
1624 # b ref should have a and b, and should not be in project2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001625 self.assertTrue(self.ref_has_change(b_zref, A))
1626 self.assertTrue(self.ref_has_change(b_zref, B))
1627 self.assertFalse(self.ref_has_change(b_zref, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08001628
1629 # c ref should have a and b in 1, c in 2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001630 self.assertTrue(self.ref_has_change(c_zref, A))
1631 self.assertTrue(self.ref_has_change(c_zref, B))
1632 self.assertTrue(self.ref_has_change(c_zref, C))
1633 self.assertFalse(self.ref_has_change(c_zref, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08001634
1635 # d ref should have a and b in 1, c and d in 2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001636 self.assertTrue(self.ref_has_change(d_zref, A))
1637 self.assertTrue(self.ref_has_change(d_zref, B))
1638 self.assertTrue(self.ref_has_change(d_zref, C))
1639 self.assertTrue(self.ref_has_change(d_zref, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08001640
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001641 self.worker.hold_jobs_in_build = False
1642 self.worker.release()
James E. Blair7d0dedc2013-02-21 17:26:09 -08001643 self.waitUntilSettled()
1644
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001645 self.assertEqual(A.data['status'], 'MERGED')
1646 self.assertEqual(A.reported, 2)
1647 self.assertEqual(B.data['status'], 'MERGED')
1648 self.assertEqual(B.reported, 2)
1649 self.assertEqual(C.data['status'], 'MERGED')
1650 self.assertEqual(C.reported, 2)
1651 self.assertEqual(D.data['status'], 'MERGED')
1652 self.assertEqual(D.reported, 2)
James E. Blair70c71582013-03-06 08:50:50 -08001653
James E. Blair11041d22014-05-02 14:49:53 -07001654 def test_pipeline_requirements_approval_check_and_gate(self):
1655 "Test pipeline requirements triggers both check and gate"
1656 self.config.set('zuul', 'layout_config',
1657 'tests/fixtures/layout-pipeline-requirements.yaml')
1658 self.sched.reconfigure(self.config)
1659 self.registerJobs()
1660 self._test_required_approval_check_and_gate()
1661
James E. Blairc053d022014-01-22 14:57:33 -08001662 def test_required_approval_check_and_gate(self):
1663 "Test required-approval triggers both check and gate"
1664 self.config.set('zuul', 'layout_config',
1665 'tests/fixtures/layout-require-approval.yaml')
1666 self.sched.reconfigure(self.config)
1667 self.registerJobs()
James E. Blair11041d22014-05-02 14:49:53 -07001668 self._test_required_approval_check_and_gate()
James E. Blairc053d022014-01-22 14:57:33 -08001669
James E. Blair11041d22014-05-02 14:49:53 -07001670 def _test_required_approval_check_and_gate(self):
James E. Blairc053d022014-01-22 14:57:33 -08001671 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1672 A.addApproval('CRVW', 2)
1673 # Add a too-old +1
1674 A.addApproval('VRFY', 1, granted_on=time.time() - 72 * 60 * 60)
1675
1676 aprv = A.addApproval('APRV', 1)
1677 self.fake_gerrit.addEvent(aprv)
1678 self.waitUntilSettled()
1679 # Should have run a check job
1680 self.assertEqual(len(self.history), 1)
1681 self.assertEqual(self.history[0].name, 'project-check')
1682
1683 # Report the result of that check job (overrides previous vrfy)
1684 # Skynet alert: this should trigger a gate job now that
1685 # all reqs are met
1686 self.fake_gerrit.addEvent(A.addApproval('VRFY', 1))
1687 self.waitUntilSettled()
1688 self.assertEqual(len(self.history), 2)
1689 self.assertEqual(self.history[1].name, 'project-gate')
1690
James E. Blair11041d22014-05-02 14:49:53 -07001691 def test_pipeline_requirements_approval_newer(self):
1692 "Test pipeline requirements newer trigger parameter"
1693 self.config.set('zuul', 'layout_config',
1694 'tests/fixtures/layout-pipeline-requirements.yaml')
1695 self.sched.reconfigure(self.config)
1696 self.registerJobs()
1697 self._test_required_approval_newer()
1698
James E. Blairc053d022014-01-22 14:57:33 -08001699 def test_required_approval_newer(self):
1700 "Test required-approval newer trigger parameter"
1701 self.config.set('zuul', 'layout_config',
1702 'tests/fixtures/layout-require-approval.yaml')
1703 self.sched.reconfigure(self.config)
1704 self.registerJobs()
James E. Blair11041d22014-05-02 14:49:53 -07001705 self._test_required_approval_newer()
1706
1707 def _test_required_approval_newer(self):
1708 self.config.set('zuul', 'layout_config',
1709 'tests/fixtures/layout-require-approval.yaml')
1710 self.sched.reconfigure(self.config)
1711 self.registerJobs()
James E. Blairc053d022014-01-22 14:57:33 -08001712
1713 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1714 A.addApproval('CRVW', 2)
1715 aprv = A.addApproval('APRV', 1)
1716 self.fake_gerrit.addEvent(aprv)
1717 self.waitUntilSettled()
1718 # No +1 from Jenkins so should not be enqueued
1719 self.assertEqual(len(self.history), 0)
1720
1721 # Add a too-old +1, should trigger check but not gate
1722 A.addApproval('VRFY', 1, granted_on=time.time() - 72 * 60 * 60)
1723 self.fake_gerrit.addEvent(aprv)
1724 self.waitUntilSettled()
1725 self.assertEqual(len(self.history), 1)
1726 self.assertEqual(self.history[0].name, 'project-check')
1727
1728 # Add a recent +1
1729 self.fake_gerrit.addEvent(A.addApproval('VRFY', 1))
1730 self.fake_gerrit.addEvent(aprv)
1731 self.waitUntilSettled()
1732 self.assertEqual(len(self.history), 2)
1733 self.assertEqual(self.history[1].name, 'project-gate')
1734
James E. Blair11041d22014-05-02 14:49:53 -07001735 def test_pipeline_requirements_approval_older(self):
1736 "Test pipeline requirements older trigger parameter"
1737 self.config.set('zuul', 'layout_config',
1738 'tests/fixtures/layout-pipeline-requirements.yaml')
1739 self.sched.reconfigure(self.config)
1740 self.registerJobs()
1741 self._test_required_approval_older()
1742
James E. Blairc053d022014-01-22 14:57:33 -08001743 def test_required_approval_older(self):
1744 "Test required-approval older trigger parameter"
1745 self.config.set('zuul', 'layout_config',
1746 'tests/fixtures/layout-require-approval.yaml')
1747 self.sched.reconfigure(self.config)
1748 self.registerJobs()
James E. Blair11041d22014-05-02 14:49:53 -07001749 self._test_required_approval_older()
1750
1751 def _test_required_approval_older(self):
1752 self.config.set('zuul', 'layout_config',
1753 'tests/fixtures/layout-require-approval.yaml')
1754 self.sched.reconfigure(self.config)
1755 self.registerJobs()
James E. Blairc053d022014-01-22 14:57:33 -08001756
1757 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1758 crvw = A.addApproval('CRVW', 2)
1759 self.fake_gerrit.addEvent(crvw)
1760 self.waitUntilSettled()
1761 # No +1 from Jenkins so should not be enqueued
1762 self.assertEqual(len(self.history), 0)
1763
1764 # Add an old +1 and trigger check with a comment
1765 A.addApproval('VRFY', 1, granted_on=time.time() - 72 * 60 * 60)
1766 self.fake_gerrit.addEvent(crvw)
1767 self.waitUntilSettled()
1768 self.assertEqual(len(self.history), 1)
1769 self.assertEqual(self.history[0].name, 'project-check')
1770
1771 # Add a recent +1 and make sure nothing changes
1772 A.addApproval('VRFY', 1)
1773 self.fake_gerrit.addEvent(crvw)
1774 self.waitUntilSettled()
1775 self.assertEqual(len(self.history), 1)
1776
1777 # The last thing we did was query a change then do nothing
1778 # with a pipeline, so it will be in the cache; clean it up so
1779 # it does not fail the test.
1780 for pipeline in self.sched.layout.pipelines.values():
1781 pipeline.trigger.maintainCache([])
1782
James E. Blair4a28a882013-08-23 15:17:33 -07001783 def test_rerun_on_error(self):
1784 "Test that if a worker fails to run a job, it is run again"
1785 self.worker.hold_jobs_in_build = True
1786 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1787 A.addApproval('CRVW', 2)
1788 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1789 self.waitUntilSettled()
1790
1791 self.builds[0].run_error = True
1792 self.worker.hold_jobs_in_build = False
1793 self.worker.release()
1794 self.waitUntilSettled()
1795 self.assertEqual(self.countJobResults(self.history, 'RUN_ERROR'), 1)
1796 self.assertEqual(self.countJobResults(self.history, 'SUCCESS'), 3)
1797
James E. Blair412e5582013-04-22 15:50:12 -07001798 def test_statsd(self):
1799 "Test each of the statsd methods used in the scheduler"
1800 import extras
1801 statsd = extras.try_import('statsd.statsd')
1802 statsd.incr('test-incr')
1803 statsd.timing('test-timing', 3)
Alex Gaynor813d39b2014-05-17 16:17:16 -07001804 statsd.gauge('test-gauge', 12)
James E. Blair412e5582013-04-22 15:50:12 -07001805 self.assertReportedStat('test-incr', '1|c')
1806 self.assertReportedStat('test-timing', '3|ms')
Alex Gaynor813d39b2014-05-17 16:17:16 -07001807 self.assertReportedStat('test-gauge', '12|g')
James E. Blair412e5582013-04-22 15:50:12 -07001808
James E. Blairdad52252014-02-07 16:59:17 -08001809 def test_stuck_job_cleanup(self):
1810 "Test that pending jobs are cleaned up if removed from layout"
James E. Blair18c64442014-03-18 10:14:45 -07001811 # This job won't be registered at startup because it is not in
1812 # the standard layout, but we need it to already be registerd
1813 # for when we reconfigure, as that is when Zuul will attempt
1814 # to run the new job.
1815 self.worker.registerFunction('build:gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08001816 self.gearman_server.hold_jobs_in_queue = True
1817 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1818 A.addApproval('CRVW', 2)
1819 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1820 self.waitUntilSettled()
1821 self.assertEqual(len(self.gearman_server.getQueue()), 1)
1822
1823 self.config.set('zuul', 'layout_config',
1824 'tests/fixtures/layout-no-jobs.yaml')
1825 self.sched.reconfigure(self.config)
1826 self.waitUntilSettled()
1827
James E. Blair18c64442014-03-18 10:14:45 -07001828 self.gearman_server.release('gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08001829 self.waitUntilSettled()
1830 self.assertEqual(len(self.gearman_server.getQueue()), 0)
1831 self.assertTrue(self.sched._areAllBuildsComplete())
1832
1833 self.assertEqual(len(self.history), 1)
James E. Blair18c64442014-03-18 10:14:45 -07001834 self.assertEqual(self.history[0].name, 'gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08001835 self.assertEqual(self.history[0].result, 'SUCCESS')
1836
James E. Blair70c71582013-03-06 08:50:50 -08001837 def test_file_jobs(self):
1838 "Test that file jobs run only when appropriate"
1839 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1840 A.addPatchset(['pip-requires'])
1841 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1842 A.addApproval('CRVW', 2)
1843 B.addApproval('CRVW', 2)
1844 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1845 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1846 self.waitUntilSettled()
1847
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001848 testfile_jobs = [x for x in self.history
James E. Blair70c71582013-03-06 08:50:50 -08001849 if x.name == 'project-testfile']
1850
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001851 self.assertEqual(len(testfile_jobs), 1)
1852 self.assertEqual(testfile_jobs[0].changes, '1,2')
1853 self.assertEqual(A.data['status'], 'MERGED')
1854 self.assertEqual(A.reported, 2)
1855 self.assertEqual(B.data['status'], 'MERGED')
1856 self.assertEqual(B.reported, 2)
James E. Blair3c5e5b52013-04-26 11:17:03 -07001857
1858 def test_test_config(self):
1859 "Test that we can test the config"
1860 sched = zuul.scheduler.Scheduler()
James E. Blair6c358e72013-07-29 17:06:47 -07001861 sched.registerTrigger(None, 'gerrit')
James E. Blair63bb0ef2013-07-29 17:14:51 -07001862 sched.registerTrigger(None, 'timer')
Clark Boylanb640e052014-04-03 16:41:46 -07001863 sched.testConfig(self.config.get('zuul', 'layout_config'))
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001864
1865 def test_build_description(self):
1866 "Test that build descriptions update"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001867 self.worker.registerFunction('set_description:' +
1868 self.worker.worker_id)
1869
1870 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1871 A.addApproval('CRVW', 2)
1872 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1873 self.waitUntilSettled()
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001874 desc = self.history[0].description
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001875 self.log.debug("Description: %s" % desc)
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001876 self.assertTrue(re.search("Branch.*master", desc))
1877 self.assertTrue(re.search("Pipeline.*gate", desc))
1878 self.assertTrue(re.search("project-merge.*SUCCESS", desc))
1879 self.assertTrue(re.search("project-test1.*SUCCESS", desc))
1880 self.assertTrue(re.search("project-test2.*SUCCESS", desc))
1881 self.assertTrue(re.search("Reported result.*SUCCESS", desc))
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001882
James E. Blairc8a1e052014-02-25 09:29:26 -08001883 def test_queue_names(self):
1884 "Test shared change queue names"
1885 project1 = self.sched.layout.projects['org/project1']
1886 project2 = self.sched.layout.projects['org/project2']
1887 q1 = self.sched.layout.pipelines['gate'].getQueue(project1)
1888 q2 = self.sched.layout.pipelines['gate'].getQueue(project2)
1889 self.assertEqual(q1.name, 'integration')
1890 self.assertEqual(q2.name, 'integration')
1891
1892 self.config.set('zuul', 'layout_config',
1893 'tests/fixtures/layout-bad-queue.yaml')
1894 with testtools.ExpectedException(
1895 Exception, "More than one name assigned to change queue"):
1896 self.sched.reconfigure(self.config)
1897
James E. Blair64ed6f22013-07-10 14:07:23 -07001898 def test_queue_precedence(self):
1899 "Test that queue precedence works"
1900
1901 self.gearman_server.hold_jobs_in_queue = True
James E. Blair8de58bd2013-07-18 16:23:33 -07001902 self.worker.hold_jobs_in_build = True
James E. Blair64ed6f22013-07-10 14:07:23 -07001903 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1904 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1905 A.addApproval('CRVW', 2)
1906 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1907
1908 self.waitUntilSettled()
1909 self.gearman_server.hold_jobs_in_queue = False
1910 self.gearman_server.release()
1911 self.waitUntilSettled()
1912
James E. Blair8de58bd2013-07-18 16:23:33 -07001913 # Run one build at a time to ensure non-race order:
1914 for x in range(6):
1915 self.release(self.builds[0])
1916 self.waitUntilSettled()
1917 self.worker.hold_jobs_in_build = False
1918 self.waitUntilSettled()
1919
James E. Blair64ed6f22013-07-10 14:07:23 -07001920 self.log.debug(self.history)
1921 self.assertEqual(self.history[0].pipeline, 'gate')
1922 self.assertEqual(self.history[1].pipeline, 'check')
1923 self.assertEqual(self.history[2].pipeline, 'gate')
1924 self.assertEqual(self.history[3].pipeline, 'gate')
1925 self.assertEqual(self.history[4].pipeline, 'check')
1926 self.assertEqual(self.history[5].pipeline, 'check')
1927
Clark Boylana5edbe42014-06-03 16:39:10 -07001928 def test_json_status(self):
James E. Blair1843a552013-07-03 14:19:52 -07001929 "Test that we can retrieve JSON status info"
1930 self.worker.hold_jobs_in_build = True
1931 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1932 A.addApproval('CRVW', 2)
1933 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1934 self.waitUntilSettled()
1935
1936 port = self.webapp.server.socket.getsockname()[1]
1937
Yuriy Taradaya6d452f2014-04-16 12:36:20 +04001938 req = urllib2.Request("http://localhost:%s/status.json" % port)
Yuriy Taradaya6d452f2014-04-16 12:36:20 +04001939 f = urllib2.urlopen(req)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07001940 headers = f.info()
1941 self.assertIn('Content-Length', headers)
1942 self.assertIn('Content-Type', headers)
1943 self.assertEqual(headers['Content-Type'],
1944 'application/json; charset=UTF-8')
1945 self.assertIn('Last-Modified', headers)
James E. Blair1843a552013-07-03 14:19:52 -07001946 data = f.read()
1947
1948 self.worker.hold_jobs_in_build = False
1949 self.worker.release()
1950 self.waitUntilSettled()
1951
1952 data = json.loads(data)
1953 status_jobs = set()
1954 for p in data['pipelines']:
1955 for q in p['change_queues']:
Clark Boylanaf2476f2014-01-23 14:47:36 -08001956 if q['dependent']:
1957 self.assertEqual(q['window'], 20)
1958 else:
1959 self.assertEqual(q['window'], 0)
James E. Blair1843a552013-07-03 14:19:52 -07001960 for head in q['heads']:
1961 for change in head:
Clark Boylanaf2476f2014-01-23 14:47:36 -08001962 self.assertTrue(change['active'])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001963 self.assertEqual(change['id'], '1,1')
James E. Blair1843a552013-07-03 14:19:52 -07001964 for job in change['jobs']:
1965 status_jobs.add(job['name'])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001966 self.assertIn('project-merge', status_jobs)
1967 self.assertIn('project-test1', status_jobs)
1968 self.assertIn('project-test2', status_jobs)
James E. Blair1843a552013-07-03 14:19:52 -07001969
James E. Blairc3d428e2013-12-03 15:06:48 -08001970 def test_merging_queues(self):
1971 "Test that transitively-connected change queues are merged"
1972 self.config.set('zuul', 'layout_config',
1973 'tests/fixtures/layout-merge-queues.yaml')
1974 self.sched.reconfigure(self.config)
1975 self.assertEqual(len(self.sched.layout.pipelines['gate'].queues), 1)
1976
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001977 def test_node_label(self):
1978 "Test that a job runs on a specific node label"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001979 self.worker.registerFunction('build:node-project-test1:debian')
1980
1981 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
1982 A.addApproval('CRVW', 2)
1983 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1984 self.waitUntilSettled()
James E. Blair4ca985f2013-05-30 12:27:43 -07001985
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001986 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
1987 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
1988 'debian')
1989 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
James E. Blaircdccd972013-07-01 12:10:22 -07001990
1991 def test_live_reconfiguration(self):
1992 "Test that live reconfiguration works"
1993 self.worker.hold_jobs_in_build = True
1994 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1995 A.addApproval('CRVW', 2)
1996 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1997 self.waitUntilSettled()
1998
1999 self.sched.reconfigure(self.config)
2000
2001 self.worker.hold_jobs_in_build = False
2002 self.worker.release()
2003 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002004 self.assertEqual(self.getJobFromHistory('project-merge').result,
2005 'SUCCESS')
2006 self.assertEqual(self.getJobFromHistory('project-test1').result,
2007 'SUCCESS')
2008 self.assertEqual(self.getJobFromHistory('project-test2').result,
2009 'SUCCESS')
2010 self.assertEqual(A.data['status'], 'MERGED')
2011 self.assertEqual(A.reported, 2)
James E. Blair287c06d2013-07-24 10:39:30 -07002012
James E. Blaire712d9f2013-07-31 11:40:11 -07002013 def test_live_reconfiguration_functions(self):
2014 "Test live reconfiguration with a custom function"
2015 self.worker.registerFunction('build:node-project-test1:debian')
2016 self.worker.registerFunction('build:node-project-test1:wheezy')
2017 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
2018 A.addApproval('CRVW', 2)
2019 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2020 self.waitUntilSettled()
2021
2022 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2023 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2024 'debian')
2025 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2026
2027 self.config.set('zuul', 'layout_config',
2028 'tests/fixtures/layout-live-'
2029 'reconfiguration-functions.yaml')
2030 self.sched.reconfigure(self.config)
2031 self.worker.build_history = []
2032
2033 B = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'B')
2034 B.addApproval('CRVW', 2)
2035 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2036 self.waitUntilSettled()
2037
2038 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2039 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2040 'wheezy')
2041 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2042
James E. Blair287c06d2013-07-24 10:39:30 -07002043 def test_delayed_repo_init(self):
2044 self.config.set('zuul', 'layout_config',
2045 'tests/fixtures/layout-delayed-repo-init.yaml')
2046 self.sched.reconfigure(self.config)
2047
2048 self.init_repo("org/new-project")
2049 A = self.fake_gerrit.addFakeChange('org/new-project', 'master', 'A')
2050
2051 A.addApproval('CRVW', 2)
2052 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2053 self.waitUntilSettled()
2054 self.assertEqual(self.getJobFromHistory('project-merge').result,
2055 'SUCCESS')
2056 self.assertEqual(self.getJobFromHistory('project-test1').result,
2057 'SUCCESS')
2058 self.assertEqual(self.getJobFromHistory('project-test2').result,
2059 'SUCCESS')
2060 self.assertEqual(A.data['status'], 'MERGED')
2061 self.assertEqual(A.reported, 2)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002062
Clark Boylan6dbbc482013-10-18 10:57:31 -07002063 def test_repo_deleted(self):
2064 self.config.set('zuul', 'layout_config',
2065 'tests/fixtures/layout-repo-deleted.yaml')
2066 self.sched.reconfigure(self.config)
2067
2068 self.init_repo("org/delete-project")
2069 A = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'A')
2070
2071 A.addApproval('CRVW', 2)
2072 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2073 self.waitUntilSettled()
2074 self.assertEqual(self.getJobFromHistory('project-merge').result,
2075 'SUCCESS')
2076 self.assertEqual(self.getJobFromHistory('project-test1').result,
2077 'SUCCESS')
2078 self.assertEqual(self.getJobFromHistory('project-test2').result,
2079 'SUCCESS')
2080 self.assertEqual(A.data['status'], 'MERGED')
2081 self.assertEqual(A.reported, 2)
2082
2083 # Delete org/new-project zuul repo. Should be recloned.
2084 shutil.rmtree(os.path.join(self.git_root, "org/delete-project"))
2085
2086 B = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'B')
2087
2088 B.addApproval('CRVW', 2)
2089 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2090 self.waitUntilSettled()
2091 self.assertEqual(self.getJobFromHistory('project-merge').result,
2092 'SUCCESS')
2093 self.assertEqual(self.getJobFromHistory('project-test1').result,
2094 'SUCCESS')
2095 self.assertEqual(self.getJobFromHistory('project-test2').result,
2096 'SUCCESS')
2097 self.assertEqual(B.data['status'], 'MERGED')
2098 self.assertEqual(B.reported, 2)
2099
James E. Blair63bb0ef2013-07-29 17:14:51 -07002100 def test_timer(self):
2101 "Test that a periodic job is triggered"
2102 self.worker.hold_jobs_in_build = True
2103 self.config.set('zuul', 'layout_config',
2104 'tests/fixtures/layout-timer.yaml')
2105 self.sched.reconfigure(self.config)
2106 self.registerJobs()
2107
Clark Boylan3ee090a2014-04-03 20:55:09 -07002108 # The pipeline triggers every second, so we should have seen
2109 # several by now.
2110 time.sleep(5)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002111 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002112
2113 self.assertEqual(len(self.builds), 2)
2114
James E. Blair63bb0ef2013-07-29 17:14:51 -07002115 port = self.webapp.server.socket.getsockname()[1]
2116
2117 f = urllib.urlopen("http://localhost:%s/status.json" % port)
2118 data = f.read()
2119
2120 self.worker.hold_jobs_in_build = False
Clark Boylan3ee090a2014-04-03 20:55:09 -07002121 # Stop queuing timer triggered jobs so that the assertions
2122 # below don't race against more jobs being queued.
2123 self.config.set('zuul', 'layout_config',
2124 'tests/fixtures/layout-no-timer.yaml')
2125 self.sched.reconfigure(self.config)
2126 self.registerJobs()
James E. Blair63bb0ef2013-07-29 17:14:51 -07002127 self.worker.release()
2128 self.waitUntilSettled()
2129
2130 self.assertEqual(self.getJobFromHistory(
2131 'project-bitrot-stable-old').result, 'SUCCESS')
2132 self.assertEqual(self.getJobFromHistory(
2133 'project-bitrot-stable-older').result, 'SUCCESS')
2134
2135 data = json.loads(data)
2136 status_jobs = set()
2137 for p in data['pipelines']:
2138 for q in p['change_queues']:
2139 for head in q['heads']:
2140 for change in head:
Alex Gaynorddb9ef32013-09-16 21:04:58 -07002141 self.assertEqual(change['id'], None)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002142 for job in change['jobs']:
2143 status_jobs.add(job['name'])
2144 self.assertIn('project-bitrot-stable-old', status_jobs)
2145 self.assertIn('project-bitrot-stable-older', status_jobs)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002146
James E. Blair4f6033c2014-03-27 15:49:09 -07002147 def test_idle(self):
2148 "Test that frequent periodic jobs work"
2149 self.worker.hold_jobs_in_build = True
James E. Blair4f6033c2014-03-27 15:49:09 -07002150
Clark Boylan3ee090a2014-04-03 20:55:09 -07002151 for x in range(1, 3):
2152 # Test that timer triggers periodic jobs even across
2153 # layout config reloads.
2154 # Start timer trigger
2155 self.config.set('zuul', 'layout_config',
2156 'tests/fixtures/layout-idle.yaml')
2157 self.sched.reconfigure(self.config)
2158 self.registerJobs()
James E. Blair4f6033c2014-03-27 15:49:09 -07002159
Clark Boylan3ee090a2014-04-03 20:55:09 -07002160 # The pipeline triggers every second, so we should have seen
2161 # several by now.
2162 time.sleep(5)
2163 self.waitUntilSettled()
2164
2165 # Stop queuing timer triggered jobs so that the assertions
2166 # below don't race against more jobs being queued.
2167 self.config.set('zuul', 'layout_config',
2168 'tests/fixtures/layout-no-timer.yaml')
2169 self.sched.reconfigure(self.config)
2170 self.registerJobs()
2171
2172 self.assertEqual(len(self.builds), 2)
2173 self.worker.release('.*')
2174 self.waitUntilSettled()
2175 self.assertEqual(len(self.builds), 0)
2176 self.assertEqual(len(self.history), x * 2)
James E. Blair4f6033c2014-03-27 15:49:09 -07002177
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002178 def test_check_smtp_pool(self):
2179 self.config.set('zuul', 'layout_config',
2180 'tests/fixtures/layout-smtp.yaml')
2181 self.sched.reconfigure(self.config)
2182
2183 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2184 self.waitUntilSettled()
2185
2186 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2187 self.waitUntilSettled()
2188
James E. Blairff80a2f2013-12-27 13:24:06 -08002189 self.assertEqual(len(self.smtp_messages), 2)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002190
2191 # A.messages only holds what FakeGerrit places in it. Thus we
2192 # work on the knowledge of what the first message should be as
2193 # it is only configured to go to SMTP.
2194
2195 self.assertEqual('zuul@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08002196 self.smtp_messages[0]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002197 self.assertEqual(['you@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08002198 self.smtp_messages[0]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002199 self.assertEqual('Starting check jobs.',
James E. Blairff80a2f2013-12-27 13:24:06 -08002200 self.smtp_messages[0]['body'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002201
2202 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08002203 self.smtp_messages[1]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002204 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08002205 self.smtp_messages[1]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002206 self.assertEqual(A.messages[0],
James E. Blairff80a2f2013-12-27 13:24:06 -08002207 self.smtp_messages[1]['body'])
James E. Blairad28e912013-11-27 10:43:22 -08002208
James E. Blaire5910202013-12-27 09:50:31 -08002209 def test_timer_smtp(self):
2210 "Test that a periodic job is triggered"
Clark Boylan3ee090a2014-04-03 20:55:09 -07002211 self.worker.hold_jobs_in_build = True
James E. Blaire5910202013-12-27 09:50:31 -08002212 self.config.set('zuul', 'layout_config',
2213 'tests/fixtures/layout-timer-smtp.yaml')
2214 self.sched.reconfigure(self.config)
2215 self.registerJobs()
2216
Clark Boylan3ee090a2014-04-03 20:55:09 -07002217 # The pipeline triggers every second, so we should have seen
2218 # several by now.
2219 time.sleep(5)
James E. Blaire5910202013-12-27 09:50:31 -08002220 self.waitUntilSettled()
2221
Clark Boylan3ee090a2014-04-03 20:55:09 -07002222 self.assertEqual(len(self.builds), 2)
2223 self.worker.release('.*')
2224 self.waitUntilSettled()
2225 self.assertEqual(len(self.history), 2)
2226
James E. Blaire5910202013-12-27 09:50:31 -08002227 self.assertEqual(self.getJobFromHistory(
2228 'project-bitrot-stable-old').result, 'SUCCESS')
2229 self.assertEqual(self.getJobFromHistory(
2230 'project-bitrot-stable-older').result, 'SUCCESS')
2231
James E. Blairff80a2f2013-12-27 13:24:06 -08002232 self.assertEqual(len(self.smtp_messages), 1)
James E. Blaire5910202013-12-27 09:50:31 -08002233
2234 # A.messages only holds what FakeGerrit places in it. Thus we
2235 # work on the knowledge of what the first message should be as
2236 # it is only configured to go to SMTP.
2237
2238 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08002239 self.smtp_messages[0]['from_email'])
James E. Blaire5910202013-12-27 09:50:31 -08002240 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08002241 self.smtp_messages[0]['to_email'])
James E. Blaire5910202013-12-27 09:50:31 -08002242 self.assertIn('Subject: Periodic check for org/project succeeded',
James E. Blairff80a2f2013-12-27 13:24:06 -08002243 self.smtp_messages[0]['headers'])
James E. Blaire5910202013-12-27 09:50:31 -08002244
Clark Boylan3ee090a2014-04-03 20:55:09 -07002245 # Stop queuing timer triggered jobs and let any that may have
2246 # queued through so that end of test assertions pass.
2247 self.config.set('zuul', 'layout_config',
2248 'tests/fixtures/layout-no-timer.yaml')
2249 self.sched.reconfigure(self.config)
2250 self.registerJobs()
2251 self.worker.release('.*')
2252 self.waitUntilSettled()
2253
James E. Blairad28e912013-11-27 10:43:22 -08002254 def test_client_enqueue(self):
2255 "Test that the RPC client can enqueue a change"
2256 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2257 A.addApproval('CRVW', 2)
2258 A.addApproval('APRV', 1)
2259
2260 client = zuul.rpcclient.RPCClient('127.0.0.1',
2261 self.gearman_server.port)
2262 r = client.enqueue(pipeline='gate',
2263 project='org/project',
2264 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08002265 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08002266 self.waitUntilSettled()
2267 self.assertEqual(self.getJobFromHistory('project-merge').result,
2268 'SUCCESS')
2269 self.assertEqual(self.getJobFromHistory('project-test1').result,
2270 'SUCCESS')
2271 self.assertEqual(self.getJobFromHistory('project-test2').result,
2272 'SUCCESS')
2273 self.assertEqual(A.data['status'], 'MERGED')
2274 self.assertEqual(A.reported, 2)
2275 self.assertEqual(r, True)
2276
2277 def test_client_enqueue_negative(self):
2278 "Test that the RPC client returns errors"
2279 client = zuul.rpcclient.RPCClient('127.0.0.1',
2280 self.gearman_server.port)
2281 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
2282 "Invalid project"):
2283 r = client.enqueue(pipeline='gate',
2284 project='project-does-not-exist',
2285 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08002286 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08002287 client.shutdown()
2288 self.assertEqual(r, False)
2289
2290 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
2291 "Invalid pipeline"):
2292 r = client.enqueue(pipeline='pipeline-does-not-exist',
2293 project='org/project',
2294 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08002295 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08002296 client.shutdown()
2297 self.assertEqual(r, False)
2298
2299 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
2300 "Invalid trigger"):
2301 r = client.enqueue(pipeline='gate',
2302 project='org/project',
2303 trigger='trigger-does-not-exist',
James E. Blair36658cf2013-12-06 17:53:48 -08002304 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08002305 client.shutdown()
2306 self.assertEqual(r, False)
2307
2308 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
2309 "Invalid change"):
2310 r = client.enqueue(pipeline='gate',
2311 project='org/project',
2312 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08002313 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08002314 client.shutdown()
2315 self.assertEqual(r, False)
2316
2317 self.waitUntilSettled()
2318 self.assertEqual(len(self.history), 0)
2319 self.assertEqual(len(self.builds), 0)
James E. Blair36658cf2013-12-06 17:53:48 -08002320
2321 def test_client_promote(self):
2322 "Test that the RPC client can promote a change"
2323 self.worker.hold_jobs_in_build = True
2324 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2325 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2326 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
2327 A.addApproval('CRVW', 2)
2328 B.addApproval('CRVW', 2)
2329 C.addApproval('CRVW', 2)
2330
2331 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2332 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2333 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2334
2335 self.waitUntilSettled()
2336
Sean Daguef39b9ca2014-01-10 21:34:35 -05002337 items = self.sched.layout.pipelines['gate'].getAllItems()
2338 enqueue_times = {}
2339 for item in items:
2340 enqueue_times[str(item.change)] = item.enqueue_time
2341
James E. Blair36658cf2013-12-06 17:53:48 -08002342 client = zuul.rpcclient.RPCClient('127.0.0.1',
2343 self.gearman_server.port)
2344 r = client.promote(pipeline='gate',
2345 change_ids=['2,1', '3,1'])
2346
Sean Daguef39b9ca2014-01-10 21:34:35 -05002347 # ensure that enqueue times are durable
2348 items = self.sched.layout.pipelines['gate'].getAllItems()
2349 for item in items:
2350 self.assertEqual(
2351 enqueue_times[str(item.change)], item.enqueue_time)
2352
James E. Blair78acec92014-02-06 07:11:32 -08002353 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08002354 self.worker.release('.*-merge')
2355 self.waitUntilSettled()
2356 self.worker.release('.*-merge')
2357 self.waitUntilSettled()
2358 self.worker.release('.*-merge')
2359 self.waitUntilSettled()
2360
2361 self.assertEqual(len(self.builds), 6)
2362 self.assertEqual(self.builds[0].name, 'project-test1')
2363 self.assertEqual(self.builds[1].name, 'project-test2')
2364 self.assertEqual(self.builds[2].name, 'project-test1')
2365 self.assertEqual(self.builds[3].name, 'project-test2')
2366 self.assertEqual(self.builds[4].name, 'project-test1')
2367 self.assertEqual(self.builds[5].name, 'project-test2')
2368
2369 self.assertTrue(self.job_has_changes(self.builds[0], B))
2370 self.assertFalse(self.job_has_changes(self.builds[0], A))
2371 self.assertFalse(self.job_has_changes(self.builds[0], C))
2372
2373 self.assertTrue(self.job_has_changes(self.builds[2], B))
2374 self.assertTrue(self.job_has_changes(self.builds[2], C))
2375 self.assertFalse(self.job_has_changes(self.builds[2], A))
2376
2377 self.assertTrue(self.job_has_changes(self.builds[4], B))
2378 self.assertTrue(self.job_has_changes(self.builds[4], C))
2379 self.assertTrue(self.job_has_changes(self.builds[4], A))
2380
2381 self.worker.release()
2382 self.waitUntilSettled()
2383
2384 self.assertEqual(A.data['status'], 'MERGED')
2385 self.assertEqual(A.reported, 2)
2386 self.assertEqual(B.data['status'], 'MERGED')
2387 self.assertEqual(B.reported, 2)
2388 self.assertEqual(C.data['status'], 'MERGED')
2389 self.assertEqual(C.reported, 2)
2390
2391 client.shutdown()
2392 self.assertEqual(r, True)
2393
2394 def test_client_promote_dependent(self):
2395 "Test that the RPC client can promote a dependent change"
2396 # C (depends on B) -> B -> A ; then promote C to get:
2397 # A -> C (depends on B) -> B
2398 self.worker.hold_jobs_in_build = True
2399 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2400 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2401 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
2402
2403 C.setDependsOn(B, 1)
2404
2405 A.addApproval('CRVW', 2)
2406 B.addApproval('CRVW', 2)
2407 C.addApproval('CRVW', 2)
2408
2409 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2410 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2411 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2412
2413 self.waitUntilSettled()
2414
2415 client = zuul.rpcclient.RPCClient('127.0.0.1',
2416 self.gearman_server.port)
2417 r = client.promote(pipeline='gate',
2418 change_ids=['3,1'])
2419
James E. Blair78acec92014-02-06 07:11:32 -08002420 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08002421 self.worker.release('.*-merge')
2422 self.waitUntilSettled()
2423 self.worker.release('.*-merge')
2424 self.waitUntilSettled()
2425 self.worker.release('.*-merge')
2426 self.waitUntilSettled()
2427
2428 self.assertEqual(len(self.builds), 6)
2429 self.assertEqual(self.builds[0].name, 'project-test1')
2430 self.assertEqual(self.builds[1].name, 'project-test2')
2431 self.assertEqual(self.builds[2].name, 'project-test1')
2432 self.assertEqual(self.builds[3].name, 'project-test2')
2433 self.assertEqual(self.builds[4].name, 'project-test1')
2434 self.assertEqual(self.builds[5].name, 'project-test2')
2435
2436 self.assertTrue(self.job_has_changes(self.builds[0], B))
2437 self.assertFalse(self.job_has_changes(self.builds[0], A))
2438 self.assertFalse(self.job_has_changes(self.builds[0], C))
2439
2440 self.assertTrue(self.job_has_changes(self.builds[2], B))
2441 self.assertTrue(self.job_has_changes(self.builds[2], C))
2442 self.assertFalse(self.job_has_changes(self.builds[2], A))
2443
2444 self.assertTrue(self.job_has_changes(self.builds[4], B))
2445 self.assertTrue(self.job_has_changes(self.builds[4], C))
2446 self.assertTrue(self.job_has_changes(self.builds[4], A))
2447
2448 self.worker.release()
2449 self.waitUntilSettled()
2450
2451 self.assertEqual(A.data['status'], 'MERGED')
2452 self.assertEqual(A.reported, 2)
2453 self.assertEqual(B.data['status'], 'MERGED')
2454 self.assertEqual(B.reported, 2)
2455 self.assertEqual(C.data['status'], 'MERGED')
2456 self.assertEqual(C.reported, 2)
2457
2458 client.shutdown()
2459 self.assertEqual(r, True)
2460
2461 def test_client_promote_negative(self):
2462 "Test that the RPC client returns errors for promotion"
2463 self.worker.hold_jobs_in_build = True
2464 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2465 A.addApproval('CRVW', 2)
2466 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2467 self.waitUntilSettled()
2468
2469 client = zuul.rpcclient.RPCClient('127.0.0.1',
2470 self.gearman_server.port)
2471
2472 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
2473 r = client.promote(pipeline='nonexistent',
2474 change_ids=['2,1', '3,1'])
2475 client.shutdown()
2476 self.assertEqual(r, False)
2477
2478 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
2479 r = client.promote(pipeline='gate',
2480 change_ids=['4,1'])
2481 client.shutdown()
2482 self.assertEqual(r, False)
2483
2484 self.worker.hold_jobs_in_build = False
2485 self.worker.release()
2486 self.waitUntilSettled()
Clark Boylan7603a372014-01-21 11:43:20 -08002487
2488 def test_queue_rate_limiting(self):
2489 "Test that DependentPipelines are rate limited with dep across window"
2490 self.config.set('zuul', 'layout_config',
2491 'tests/fixtures/layout-rate-limit.yaml')
2492 self.sched.reconfigure(self.config)
2493 self.worker.hold_jobs_in_build = True
2494 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2495 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2496 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
2497
2498 C.setDependsOn(B, 1)
2499 self.worker.addFailTest('project-test1', A)
2500
2501 A.addApproval('CRVW', 2)
2502 B.addApproval('CRVW', 2)
2503 C.addApproval('CRVW', 2)
2504
2505 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2506 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2507 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2508 self.waitUntilSettled()
2509
2510 # Only A and B will have their merge jobs queued because
2511 # window is 2.
2512 self.assertEqual(len(self.builds), 2)
2513 self.assertEqual(self.builds[0].name, 'project-merge')
2514 self.assertEqual(self.builds[1].name, 'project-merge')
2515
2516 self.worker.release('.*-merge')
2517 self.waitUntilSettled()
2518 self.worker.release('.*-merge')
2519 self.waitUntilSettled()
2520
2521 # Only A and B will have their test jobs queued because
2522 # window is 2.
2523 self.assertEqual(len(self.builds), 4)
2524 self.assertEqual(self.builds[0].name, 'project-test1')
2525 self.assertEqual(self.builds[1].name, 'project-test2')
2526 self.assertEqual(self.builds[2].name, 'project-test1')
2527 self.assertEqual(self.builds[3].name, 'project-test2')
2528
2529 self.worker.release('project-.*')
2530 self.waitUntilSettled()
2531
2532 queue = self.sched.layout.pipelines['gate'].queues[0]
2533 # A failed so window is reduced by 1 to 1.
2534 self.assertEqual(queue.window, 1)
2535 self.assertEqual(queue.window_floor, 1)
2536 self.assertEqual(A.data['status'], 'NEW')
2537
2538 # Gate is reset and only B's merge job is queued because
2539 # window shrunk to 1.
2540 self.assertEqual(len(self.builds), 1)
2541 self.assertEqual(self.builds[0].name, 'project-merge')
2542
2543 self.worker.release('.*-merge')
2544 self.waitUntilSettled()
2545
2546 # Only B's test jobs are queued because window is still 1.
2547 self.assertEqual(len(self.builds), 2)
2548 self.assertEqual(self.builds[0].name, 'project-test1')
2549 self.assertEqual(self.builds[1].name, 'project-test2')
2550
2551 self.worker.release('project-.*')
2552 self.waitUntilSettled()
2553
2554 # B was successfully merged so window is increased to 2.
2555 self.assertEqual(queue.window, 2)
2556 self.assertEqual(queue.window_floor, 1)
2557 self.assertEqual(B.data['status'], 'MERGED')
2558
2559 # Only C is left and its merge job is queued.
2560 self.assertEqual(len(self.builds), 1)
2561 self.assertEqual(self.builds[0].name, 'project-merge')
2562
2563 self.worker.release('.*-merge')
2564 self.waitUntilSettled()
2565
2566 # After successful merge job the test jobs for C are queued.
2567 self.assertEqual(len(self.builds), 2)
2568 self.assertEqual(self.builds[0].name, 'project-test1')
2569 self.assertEqual(self.builds[1].name, 'project-test2')
2570
2571 self.worker.release('project-.*')
2572 self.waitUntilSettled()
2573
2574 # C successfully merged so window is bumped to 3.
2575 self.assertEqual(queue.window, 3)
2576 self.assertEqual(queue.window_floor, 1)
2577 self.assertEqual(C.data['status'], 'MERGED')
2578
2579 def test_queue_rate_limiting_dependent(self):
2580 "Test that DependentPipelines are rate limited with dep in window"
2581 self.config.set('zuul', 'layout_config',
2582 'tests/fixtures/layout-rate-limit.yaml')
2583 self.sched.reconfigure(self.config)
2584 self.worker.hold_jobs_in_build = True
2585 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2586 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2587 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
2588
2589 B.setDependsOn(A, 1)
2590
2591 self.worker.addFailTest('project-test1', A)
2592
2593 A.addApproval('CRVW', 2)
2594 B.addApproval('CRVW', 2)
2595 C.addApproval('CRVW', 2)
2596
2597 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2598 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2599 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2600 self.waitUntilSettled()
2601
2602 # Only A and B will have their merge jobs queued because
2603 # window is 2.
2604 self.assertEqual(len(self.builds), 2)
2605 self.assertEqual(self.builds[0].name, 'project-merge')
2606 self.assertEqual(self.builds[1].name, 'project-merge')
2607
2608 self.worker.release('.*-merge')
2609 self.waitUntilSettled()
2610 self.worker.release('.*-merge')
2611 self.waitUntilSettled()
2612
2613 # Only A and B will have their test jobs queued because
2614 # window is 2.
2615 self.assertEqual(len(self.builds), 4)
2616 self.assertEqual(self.builds[0].name, 'project-test1')
2617 self.assertEqual(self.builds[1].name, 'project-test2')
2618 self.assertEqual(self.builds[2].name, 'project-test1')
2619 self.assertEqual(self.builds[3].name, 'project-test2')
2620
2621 self.worker.release('project-.*')
2622 self.waitUntilSettled()
2623
2624 queue = self.sched.layout.pipelines['gate'].queues[0]
2625 # A failed so window is reduced by 1 to 1.
2626 self.assertEqual(queue.window, 1)
2627 self.assertEqual(queue.window_floor, 1)
2628 self.assertEqual(A.data['status'], 'NEW')
2629 self.assertEqual(B.data['status'], 'NEW')
2630
2631 # Gate is reset and only C's merge job is queued because
2632 # window shrunk to 1 and A and B were dequeued.
2633 self.assertEqual(len(self.builds), 1)
2634 self.assertEqual(self.builds[0].name, 'project-merge')
2635
2636 self.worker.release('.*-merge')
2637 self.waitUntilSettled()
2638
2639 # Only C's test jobs are queued because window is still 1.
2640 self.assertEqual(len(self.builds), 2)
2641 self.assertEqual(self.builds[0].name, 'project-test1')
2642 self.assertEqual(self.builds[1].name, 'project-test2')
2643
2644 self.worker.release('project-.*')
2645 self.waitUntilSettled()
2646
2647 # C was successfully merged so window is increased to 2.
2648 self.assertEqual(queue.window, 2)
2649 self.assertEqual(queue.window_floor, 1)
2650 self.assertEqual(C.data['status'], 'MERGED')
Joshua Heskethba8776a2014-01-12 14:35:40 +08002651
2652 def test_worker_update_metadata(self):
2653 "Test if a worker can send back metadata about itself"
2654 self.worker.hold_jobs_in_build = True
2655
2656 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2657 A.addApproval('CRVW', 2)
2658 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2659 self.waitUntilSettled()
2660
2661 self.assertEqual(len(self.launcher.builds), 1)
2662
2663 self.log.debug('Current builds:')
2664 self.log.debug(self.launcher.builds)
2665
2666 start = time.time()
2667 while True:
2668 if time.time() - start > 10:
2669 raise Exception("Timeout waiting for gearman server to report "
2670 + "back to the client")
2671 build = self.launcher.builds.values()[0]
2672 if build.worker.name == "My Worker":
2673 break
2674 else:
2675 time.sleep(0)
2676
2677 self.log.debug(build)
2678 self.assertEqual("My Worker", build.worker.name)
2679 self.assertEqual("localhost", build.worker.hostname)
2680 self.assertEqual(['127.0.0.1', '192.168.1.1'], build.worker.ips)
2681 self.assertEqual("zuul.example.org", build.worker.fqdn)
2682 self.assertEqual("FakeBuilder", build.worker.program)
2683 self.assertEqual("v1.1", build.worker.version)
2684 self.assertEqual({'something': 'else'}, build.worker.extra)
2685
2686 self.worker.hold_jobs_in_build = False
2687 self.worker.release()
2688 self.waitUntilSettled()
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11002689
2690 def test_footer_message(self):
2691 "Test a pipeline's footer message is correctly added to the report."
2692 self.config.set('zuul', 'layout_config',
2693 'tests/fixtures/layout-footer-message.yaml')
2694 self.sched.reconfigure(self.config)
2695 self.registerJobs()
2696
2697 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2698 A.addApproval('CRVW', 2)
2699 self.worker.addFailTest('test1', A)
2700 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2701 self.waitUntilSettled()
2702
2703 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2704 B.addApproval('CRVW', 2)
2705 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2706 self.waitUntilSettled()
2707
2708 self.assertEqual(2, len(self.smtp_messages))
2709
2710 failure_body = """\
2711Build failed. For information on how to proceed, see \
2712http://wiki.example.org/Test_Failures
2713
2714- test1 http://logs.example.com/1/1/gate/test1/0 : FAILURE in 0s
2715- test2 http://logs.example.com/1/1/gate/test2/1 : SUCCESS in 0s
2716
2717For CI problems and help debugging, contact ci@example.org"""
2718
2719 success_body = """\
2720Build succeeded.
2721
2722- test1 http://logs.example.com/2/1/gate/test1/2 : SUCCESS in 0s
2723- test2 http://logs.example.com/2/1/gate/test2/3 : SUCCESS in 0s
2724
2725For CI problems and help debugging, contact ci@example.org"""
2726
2727 self.assertEqual(failure_body, self.smtp_messages[0]['body'])
2728 self.assertEqual(success_body, self.smtp_messages[1]['body'])
Joshua Heskethb7179772014-01-30 23:30:46 +11002729
2730 def test_merge_failure_reporters(self):
2731 """Check that the config is set up correctly"""
2732
2733 self.config.set('zuul', 'layout_config',
2734 'tests/fixtures/layout-merge-failure.yaml')
2735 self.sched.reconfigure(self.config)
2736 self.registerJobs()
2737
2738 self.assertEqual(
2739 "Merge Failed.\n\nThis change was unable to be automatically "
2740 "merged with the current state of the repository. Please rebase "
2741 "your change and upload a new patchset.",
2742 self.sched.layout.pipelines['check'].merge_failure_message)
2743 self.assertEqual(
2744 "The merge failed! For more information...",
2745 self.sched.layout.pipelines['gate'].merge_failure_message)
2746
2747 self.assertEqual(
2748 len(self.sched.layout.pipelines['check'].merge_failure_actions), 1)
2749 self.assertEqual(
2750 len(self.sched.layout.pipelines['gate'].merge_failure_actions), 2)
2751
2752 self.assertTrue(isinstance(
2753 self.sched.layout.pipelines['check'].merge_failure_actions[0].
2754 reporter, zuul.reporter.gerrit.Reporter))
2755
2756 self.assertTrue(
2757 (
2758 isinstance(self.sched.layout.pipelines['gate'].
2759 merge_failure_actions[0].reporter,
2760 zuul.reporter.smtp.Reporter) and
2761 isinstance(self.sched.layout.pipelines['gate'].
2762 merge_failure_actions[1].reporter,
2763 zuul.reporter.gerrit.Reporter)
2764 ) or (
2765 isinstance(self.sched.layout.pipelines['gate'].
2766 merge_failure_actions[0].reporter,
2767 zuul.reporter.gerrit.Reporter) and
2768 isinstance(self.sched.layout.pipelines['gate'].
2769 merge_failure_actions[1].reporter,
2770 zuul.reporter.smtp.Reporter)
2771 )
2772 )
2773
2774 def test_merge_failure_reports(self):
2775 """Check that when a change fails to merge the correct message is sent
2776 to the correct reporter"""
2777 self.config.set('zuul', 'layout_config',
2778 'tests/fixtures/layout-merge-failure.yaml')
2779 self.sched.reconfigure(self.config)
2780 self.registerJobs()
2781
2782 # Check a test failure isn't reported to SMTP
2783 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2784 A.addApproval('CRVW', 2)
2785 self.worker.addFailTest('project-test1', A)
2786 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2787 self.waitUntilSettled()
2788
2789 self.assertEqual(3, len(self.history)) # 3 jobs
2790 self.assertEqual(0, len(self.smtp_messages))
2791
2792 # Check a merge failure is reported to SMTP
2793 # B should be merged, but C will conflict with B
2794 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2795 B.addPatchset(['conflict'])
2796 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
2797 C.addPatchset(['conflict'])
2798 B.addApproval('CRVW', 2)
2799 C.addApproval('CRVW', 2)
2800 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2801 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2802 self.waitUntilSettled()
2803
2804 self.assertEqual(6, len(self.history)) # A and B jobs
2805 self.assertEqual(1, len(self.smtp_messages))
2806 self.assertEqual('The merge failed! For more information...',
2807 self.smtp_messages[0]['body'])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11002808
2809 def test_swift_instructions(self):
2810 "Test that the correct swift instructions are sent to the workers"
2811 self.config.set('zuul', 'layout_config',
2812 'tests/fixtures/layout-swift.yaml')
2813 self.sched.reconfigure(self.config)
2814 self.registerJobs()
2815
2816 self.worker.hold_jobs_in_build = True
2817 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2818
2819 A.addApproval('CRVW', 2)
2820 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2821 self.waitUntilSettled()
2822
2823 self.assertEqual(
2824 "https://storage.example.org/V1/AUTH_account/merge_logs/1/1/1/"
2825 "gate/test-merge/",
2826 self.builds[0].parameters['SWIFT_logs_URL'][:-32])
2827 self.assertEqual(5,
2828 len(self.builds[0].parameters['SWIFT_logs_HMAC_BODY'].
2829 split('\n')))
2830 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[0].parameters)
2831
2832 self.assertEqual(
2833 "https://storage.example.org/V1/AUTH_account/logs/1/1/1/"
2834 "gate/test-test/",
2835 self.builds[1].parameters['SWIFT_logs_URL'][:-32])
2836 self.assertEqual(5,
2837 len(self.builds[1].parameters['SWIFT_logs_HMAC_BODY'].
2838 split('\n')))
2839 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[1].parameters)
2840
2841 self.assertEqual(
2842 "https://storage.example.org/V1/AUTH_account/stash/1/1/1/"
2843 "gate/test-test/",
2844 self.builds[1].parameters['SWIFT_MOSTLY_URL'][:-32])
2845 self.assertEqual(5,
2846 len(self.builds[1].
2847 parameters['SWIFT_MOSTLY_HMAC_BODY'].split('\n')))
2848 self.assertIn('SWIFT_MOSTLY_SIGNATURE', self.builds[1].parameters)
2849
2850 self.worker.hold_jobs_in_build = False
2851 self.worker.release()
2852 self.waitUntilSettled()
Joshua Hesketh85af4e92014-02-21 08:28:58 -08002853
2854 def test_client_get_running_jobs(self):
2855 "Test that the RPC client can get a list of running jobs"
2856 self.worker.hold_jobs_in_build = True
2857 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2858 A.addApproval('CRVW', 2)
2859 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2860 self.waitUntilSettled()
2861
2862 client = zuul.rpcclient.RPCClient('127.0.0.1',
2863 self.gearman_server.port)
2864
2865 # Wait for gearman server to send the initial workData back to zuul
2866 start = time.time()
2867 while True:
2868 if time.time() - start > 10:
2869 raise Exception("Timeout waiting for gearman server to report "
2870 + "back to the client")
2871 build = self.launcher.builds.values()[0]
2872 if build.worker.name == "My Worker":
2873 break
2874 else:
2875 time.sleep(0)
2876
2877 running_items = client.get_running_jobs()
2878
2879 self.assertEqual(1, len(running_items))
2880 running_item = running_items[0]
2881 self.assertEqual([], running_item['failing_reasons'])
2882 self.assertEqual([], running_item['items_behind'])
2883 self.assertEqual('https://hostname/1', running_item['url'])
2884 self.assertEqual(None, running_item['item_ahead'])
2885 self.assertEqual('org/project', running_item['project'])
2886 self.assertEqual(None, running_item['remaining_time'])
2887 self.assertEqual(True, running_item['active'])
2888 self.assertEqual('1,1', running_item['id'])
2889
2890 self.assertEqual(3, len(running_item['jobs']))
2891 for job in running_item['jobs']:
2892 if job['name'] == 'project-merge':
2893 self.assertEqual('project-merge', job['name'])
2894 self.assertEqual('gate', job['pipeline'])
2895 self.assertEqual(False, job['retry'])
2896 self.assertEqual(13, len(job['parameters']))
2897 self.assertEqual('https://server/job/project-merge/0/',
2898 job['url'])
2899 self.assertEqual(7, len(job['worker']))
2900 self.assertEqual(False, job['canceled'])
2901 self.assertEqual(True, job['voting'])
2902 self.assertEqual(None, job['result'])
2903 self.assertEqual('gate', job['pipeline'])
2904 break
2905
2906 self.worker.hold_jobs_in_build = False
2907 self.worker.release()
2908 self.waitUntilSettled()
2909
2910 running_items = client.get_running_jobs()
2911 self.assertEqual(0, len(running_items))
James E. Blairbadc1ad2014-04-28 13:55:14 -07002912
2913 def test_nonvoting_pipeline(self):
2914 "Test that a nonvoting pipeline (experimental) can still report"
2915
Joshua Heskethcc017ea2014-04-30 19:55:25 +10002916 A = self.fake_gerrit.addFakeChange('org/experimental-project',
2917 'master', 'A')
James E. Blairbadc1ad2014-04-28 13:55:14 -07002918 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2919 self.waitUntilSettled()
Joshua Heskethcc017ea2014-04-30 19:55:25 +10002920 self.assertEqual(
2921 self.getJobFromHistory('experimental-project-test').result,
2922 'SUCCESS')
James E. Blairbadc1ad2014-04-28 13:55:14 -07002923 self.assertEqual(A.reported, 1)
Clark Boylana9702ad2014-05-08 17:17:24 -07002924
2925 def test_old_patchset_doesnt_trigger(self):
2926 "Test that jobs never run against old patchsets"
2927 self.config.set('zuul', 'layout_config',
2928 'tests/fixtures/layout-current-patchset.yaml')
2929 self.sched.reconfigure(self.config)
2930 self.registerJobs()
2931 # Create two patchsets and let their tests settle out. Then
2932 # comment on first patchset and check that no additional
2933 # jobs are run.
2934 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2935 # Added because the layout file really wants an approval but this
2936 # doesn't match anyways.
2937 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1))
2938 self.waitUntilSettled()
2939 A.addPatchset()
2940 self.fake_gerrit.addEvent(A.addApproval('CRVW', 1))
2941 self.waitUntilSettled()
2942
2943 old_history_count = len(self.history)
2944 self.assertEqual(old_history_count, 2) # one job for each ps
2945 self.fake_gerrit.addEvent(A.getChangeCommentEvent(1))
2946 self.waitUntilSettled()
2947
2948 # Assert no new jobs ran after event for old patchset.
2949 self.assertEqual(len(self.history), old_history_count)
2950
2951 # The last thing we did was add an event for a change then do
2952 # nothing with a pipeline, so it will be in the cache;
2953 # clean it up so it does not fail the test.
2954 for pipeline in self.sched.layout.pipelines.values():
2955 pipeline.trigger.maintainCache([])