blob: 764984316ece51e0060f0fc4dcaf7789c5197256 [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
Maru Newby3fe5f852015-01-13 04:22:14 +000023import yaml
James E. Blairec056492016-07-22 09:45:56 -070024from unittest import skip
Monty Taylorbc758832013-06-17 17:22:42 -040025
James E. Blair4886cc12012-07-18 15:39:41 -070026import git
Morgan Fainberg293f7f82016-05-30 14:01:22 -070027from six.moves import urllib
Monty Taylorbc758832013-06-17 17:22:42 -040028import testtools
James E. Blairb0fcae42012-07-17 11:12:10 -070029
Maru Newby3fe5f852015-01-13 04:22:14 +000030import zuul.change_matcher
James E. Blairb0fcae42012-07-17 11:12:10 -070031import zuul.scheduler
James E. Blairad28e912013-11-27 10:43:22 -080032import zuul.rpcclient
Joshua Hesketh1879cf72013-08-19 14:13:15 +100033import zuul.reporter.gerrit
Joshua Hesketh5fea8672013-08-19 17:32:01 +100034import zuul.reporter.smtp
James E. Blairb0fcae42012-07-17 11:12:10 -070035
Maru Newby3fe5f852015-01-13 04:22:14 +000036from tests.base import (
Maru Newby3fe5f852015-01-13 04:22:14 +000037 ZuulTestCase,
38 repack_repo,
39)
James E. Blairb0fcae42012-07-17 11:12:10 -070040
James E. Blair1f4c2bb2013-04-26 08:40:46 -070041logging.basicConfig(level=logging.DEBUG,
42 format='%(asctime)s %(name)-32s '
43 '%(levelname)-8s %(message)s')
James E. Blairb0fcae42012-07-17 11:12:10 -070044
45
Clark Boylanb640e052014-04-03 16:41:46 -070046class TestScheduler(ZuulTestCase):
Antoine Mussobd86a312014-01-08 14:51:33 +010047
James E. Blairec056492016-07-22 09:45:56 -070048 @skip("Disabled for early v3 development")
James E. Blairb0fcae42012-07-17 11:12:10 -070049 def test_jobs_launched(self):
50 "Test that jobs are launched and a change is merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -070051
James E. Blairb0fcae42012-07-17 11:12:10 -070052 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8c803f82012-07-31 16:25:42 -070053 A.addApproval('CRVW', 2)
James E. Blairb0fcae42012-07-17 11:12:10 -070054 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
55 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -040056 self.assertEqual(self.getJobFromHistory('project-merge').result,
57 'SUCCESS')
58 self.assertEqual(self.getJobFromHistory('project-test1').result,
59 'SUCCESS')
60 self.assertEqual(self.getJobFromHistory('project-test2').result,
61 'SUCCESS')
62 self.assertEqual(A.data['status'], 'MERGED')
63 self.assertEqual(A.reported, 2)
James E. Blairb0fcae42012-07-17 11:12:10 -070064
James E. Blair66eeebf2013-07-27 17:44:32 -070065 self.assertReportedStat('gerrit.event.comment-added', value='1|c')
66 self.assertReportedStat('zuul.pipeline.gate.current_changes',
67 value='1|g')
68 self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
69 kind='ms')
70 self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
71 value='1|c')
72 self.assertReportedStat('zuul.pipeline.gate.resident_time', kind='ms')
73 self.assertReportedStat('zuul.pipeline.gate.total_changes',
74 value='1|c')
James E. Blair412e5582013-04-22 15:50:12 -070075 self.assertReportedStat(
James E. Blair66eeebf2013-07-27 17:44:32 -070076 'zuul.pipeline.gate.org.project.resident_time', kind='ms')
James E. Blair412e5582013-04-22 15:50:12 -070077 self.assertReportedStat(
James E. Blair66eeebf2013-07-27 17:44:32 -070078 'zuul.pipeline.gate.org.project.total_changes', value='1|c')
James E. Blair412e5582013-04-22 15:50:12 -070079
James E. Blair5821bd92015-09-16 08:48:15 -070080 for build in self.builds:
81 self.assertEqual(build.parameters['ZUUL_VOTING'], '1')
82
James E. Blairec056492016-07-22 09:45:56 -070083 @skip("Disabled for early v3 development")
James E. Blair3cb10702013-08-24 08:56:03 -070084 def test_initial_pipeline_gauges(self):
85 "Test that each pipeline reported its length on start"
86 pipeline_names = self.sched.layout.pipelines.keys()
87 self.assertNotEqual(len(pipeline_names), 0)
88 for name in pipeline_names:
89 self.assertReportedStat('zuul.pipeline.%s.current_changes' % name,
90 value='0|g')
91
James E. Blairec056492016-07-22 09:45:56 -070092 @skip("Disabled for early v3 development")
James E. Blair42f74822013-05-14 15:18:03 -070093 def test_duplicate_pipelines(self):
94 "Test that a change matching multiple pipelines works"
James E. Blair1b4d9722013-05-21 10:32:04 -070095
James E. Blair42f74822013-05-14 15:18:03 -070096 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
97 self.fake_gerrit.addEvent(A.getChangeRestoredEvent())
98 self.waitUntilSettled()
James E. Blair42f74822013-05-14 15:18:03 -070099
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400100 self.assertEqual(len(self.history), 2)
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400101 self.history[0].name == 'project-test1'
102 self.history[1].name == 'project-test1'
James E. Blair42f74822013-05-14 15:18:03 -0700103
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400104 self.assertEqual(len(A.messages), 2)
James E. Blair42f74822013-05-14 15:18:03 -0700105 if 'dup1/project-test1' in A.messages[0]:
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400106 self.assertIn('dup1/project-test1', A.messages[0])
107 self.assertNotIn('dup2/project-test1', A.messages[0])
108 self.assertNotIn('dup1/project-test1', A.messages[1])
109 self.assertIn('dup2/project-test1', A.messages[1])
James E. Blair42f74822013-05-14 15:18:03 -0700110 else:
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400111 self.assertIn('dup1/project-test1', A.messages[1])
112 self.assertNotIn('dup2/project-test1', A.messages[1])
113 self.assertNotIn('dup1/project-test1', A.messages[0])
114 self.assertIn('dup2/project-test1', A.messages[0])
James E. Blair42f74822013-05-14 15:18:03 -0700115
James E. Blairec056492016-07-22 09:45:56 -0700116 @skip("Disabled for early v3 development")
James E. Blairb0fcae42012-07-17 11:12:10 -0700117 def test_parallel_changes(self):
118 "Test that changes are tested in parallel and merged in series"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700119
120 self.worker.hold_jobs_in_build = True
James E. Blairb0fcae42012-07-17 11:12:10 -0700121 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
122 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
123 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700124 A.addApproval('CRVW', 2)
125 B.addApproval('CRVW', 2)
126 C.addApproval('CRVW', 2)
James E. Blairb0fcae42012-07-17 11:12:10 -0700127
128 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
129 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
130 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
131
132 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400133 self.assertEqual(len(self.builds), 1)
134 self.assertEqual(self.builds[0].name, 'project-merge')
135 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700136
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700137 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700138 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400139 self.assertEqual(len(self.builds), 3)
140 self.assertEqual(self.builds[0].name, 'project-test1')
141 self.assertTrue(self.job_has_changes(self.builds[0], A))
142 self.assertEqual(self.builds[1].name, 'project-test2')
143 self.assertTrue(self.job_has_changes(self.builds[1], A))
144 self.assertEqual(self.builds[2].name, 'project-merge')
145 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700146
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700147 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700148 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400149 self.assertEqual(len(self.builds), 5)
150 self.assertEqual(self.builds[0].name, 'project-test1')
151 self.assertTrue(self.job_has_changes(self.builds[0], A))
152 self.assertEqual(self.builds[1].name, 'project-test2')
153 self.assertTrue(self.job_has_changes(self.builds[1], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700154
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400155 self.assertEqual(self.builds[2].name, 'project-test1')
156 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
157 self.assertEqual(self.builds[3].name, 'project-test2')
158 self.assertTrue(self.job_has_changes(self.builds[3], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700159
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400160 self.assertEqual(self.builds[4].name, 'project-merge')
161 self.assertTrue(self.job_has_changes(self.builds[4], A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700162
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700163 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700164 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400165 self.assertEqual(len(self.builds), 6)
166 self.assertEqual(self.builds[0].name, 'project-test1')
167 self.assertTrue(self.job_has_changes(self.builds[0], A))
168 self.assertEqual(self.builds[1].name, 'project-test2')
169 self.assertTrue(self.job_has_changes(self.builds[1], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700170
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400171 self.assertEqual(self.builds[2].name, 'project-test1')
172 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
173 self.assertEqual(self.builds[3].name, 'project-test2')
174 self.assertTrue(self.job_has_changes(self.builds[3], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700175
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400176 self.assertEqual(self.builds[4].name, 'project-test1')
177 self.assertTrue(self.job_has_changes(self.builds[4], A, B, C))
178 self.assertEqual(self.builds[5].name, 'project-test2')
179 self.assertTrue(self.job_has_changes(self.builds[5], A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700180
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700181 self.worker.hold_jobs_in_build = False
182 self.worker.release()
James E. Blairb0fcae42012-07-17 11:12:10 -0700183 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400184 self.assertEqual(len(self.builds), 0)
James E. Blairb0fcae42012-07-17 11:12:10 -0700185
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400186 self.assertEqual(len(self.history), 9)
187 self.assertEqual(A.data['status'], 'MERGED')
188 self.assertEqual(B.data['status'], 'MERGED')
189 self.assertEqual(C.data['status'], 'MERGED')
190 self.assertEqual(A.reported, 2)
191 self.assertEqual(B.reported, 2)
192 self.assertEqual(C.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700193
James E. Blairec056492016-07-22 09:45:56 -0700194 @skip("Disabled for early v3 development")
James E. Blairb02a3bb2012-07-30 17:49:55 -0700195 def test_failed_changes(self):
196 "Test that a change behind a failed change is retested"
James E. Blaire2819012013-06-28 17:17:26 -0400197 self.worker.hold_jobs_in_build = True
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700198
James E. Blairb02a3bb2012-07-30 17:49:55 -0700199 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
200 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8c803f82012-07-31 16:25:42 -0700201 A.addApproval('CRVW', 2)
202 B.addApproval('CRVW', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700203
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700204 self.worker.addFailTest('project-test1', A)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700205
James E. Blaire2819012013-06-28 17:17:26 -0400206 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
207 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700208 self.waitUntilSettled()
James E. Blaire2819012013-06-28 17:17:26 -0400209
210 self.worker.release('.*-merge')
211 self.waitUntilSettled()
212
213 self.worker.hold_jobs_in_build = False
214 self.worker.release()
215
216 self.waitUntilSettled()
217 # It's certain that the merge job for change 2 will run, but
218 # the test1 and test2 jobs may or may not run.
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400219 self.assertTrue(len(self.history) > 6)
220 self.assertEqual(A.data['status'], 'NEW')
221 self.assertEqual(B.data['status'], 'MERGED')
222 self.assertEqual(A.reported, 2)
223 self.assertEqual(B.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700224
James E. Blairec056492016-07-22 09:45:56 -0700225 @skip("Disabled for early v3 development")
James E. Blairb02a3bb2012-07-30 17:49:55 -0700226 def test_independent_queues(self):
227 "Test that changes end up in the right queues"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700228
229 self.worker.hold_jobs_in_build = True
Zhongyue Luo5d556072012-09-21 02:00:47 +0900230 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700231 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
232 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700233 A.addApproval('CRVW', 2)
234 B.addApproval('CRVW', 2)
235 C.addApproval('CRVW', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700236
237 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
238 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
239 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
240
James E. Blairb02a3bb2012-07-30 17:49:55 -0700241 self.waitUntilSettled()
242
243 # There should be one merge job at the head of each queue running
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400244 self.assertEqual(len(self.builds), 2)
245 self.assertEqual(self.builds[0].name, 'project-merge')
246 self.assertTrue(self.job_has_changes(self.builds[0], A))
247 self.assertEqual(self.builds[1].name, 'project1-merge')
248 self.assertTrue(self.job_has_changes(self.builds[1], B))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700249
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700250 # Release the current merge builds
251 self.worker.release('.*-merge')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700252 self.waitUntilSettled()
253 # Release the merge job for project2 which is behind project1
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700254 self.worker.release('.*-merge')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700255 self.waitUntilSettled()
256
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700257 # All the test builds should be running:
James E. Blairb02a3bb2012-07-30 17:49:55 -0700258 # project1 (3) + project2 (3) + project (2) = 8
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400259 self.assertEqual(len(self.builds), 8)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700260
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700261 self.worker.release()
James E. Blairb02a3bb2012-07-30 17:49:55 -0700262 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400263 self.assertEqual(len(self.builds), 0)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700264
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400265 self.assertEqual(len(self.history), 11)
266 self.assertEqual(A.data['status'], 'MERGED')
267 self.assertEqual(B.data['status'], 'MERGED')
268 self.assertEqual(C.data['status'], 'MERGED')
269 self.assertEqual(A.reported, 2)
270 self.assertEqual(B.reported, 2)
271 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700272
James E. Blairec056492016-07-22 09:45:56 -0700273 @skip("Disabled for early v3 development")
James E. Blaird466dc42012-07-31 10:42:56 -0700274 def test_failed_change_at_head(self):
275 "Test that if a change at the head fails, jobs behind it are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700276
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700277 self.worker.hold_jobs_in_build = True
James E. Blaird466dc42012-07-31 10:42:56 -0700278 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
279 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
280 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700281 A.addApproval('CRVW', 2)
282 B.addApproval('CRVW', 2)
283 C.addApproval('CRVW', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700284
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700285 self.worker.addFailTest('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700286
287 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
288 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
289 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
290
291 self.waitUntilSettled()
James E. Blaird466dc42012-07-31 10:42:56 -0700292
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400293 self.assertEqual(len(self.builds), 1)
294 self.assertEqual(self.builds[0].name, 'project-merge')
295 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blaird466dc42012-07-31 10:42:56 -0700296
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700297 self.worker.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700298 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700299 self.worker.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700300 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700301 self.worker.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700302 self.waitUntilSettled()
303
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400304 self.assertEqual(len(self.builds), 6)
305 self.assertEqual(self.builds[0].name, 'project-test1')
306 self.assertEqual(self.builds[1].name, 'project-test2')
307 self.assertEqual(self.builds[2].name, 'project-test1')
308 self.assertEqual(self.builds[3].name, 'project-test2')
309 self.assertEqual(self.builds[4].name, 'project-test1')
310 self.assertEqual(self.builds[5].name, 'project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700311
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400312 self.release(self.builds[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700313 self.waitUntilSettled()
314
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400315 # project-test2, project-merge for B
316 self.assertEqual(len(self.builds), 2)
317 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 4)
James E. Blaird466dc42012-07-31 10:42:56 -0700318
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700319 self.worker.hold_jobs_in_build = False
320 self.worker.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700321 self.waitUntilSettled()
322
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400323 self.assertEqual(len(self.builds), 0)
324 self.assertEqual(len(self.history), 15)
325 self.assertEqual(A.data['status'], 'NEW')
326 self.assertEqual(B.data['status'], 'MERGED')
327 self.assertEqual(C.data['status'], 'MERGED')
328 self.assertEqual(A.reported, 2)
329 self.assertEqual(B.reported, 2)
330 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700331
James E. Blairec056492016-07-22 09:45:56 -0700332 @skip("Disabled for early v3 development")
James E. Blair0aac4872013-08-23 14:02:38 -0700333 def test_failed_change_in_middle(self):
334 "Test a failed change in the middle of the queue"
335
336 self.worker.hold_jobs_in_build = True
337 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
338 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
339 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
340 A.addApproval('CRVW', 2)
341 B.addApproval('CRVW', 2)
342 C.addApproval('CRVW', 2)
343
344 self.worker.addFailTest('project-test1', B)
345
346 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
347 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
348 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
349
350 self.waitUntilSettled()
351
352 self.worker.release('.*-merge')
353 self.waitUntilSettled()
354 self.worker.release('.*-merge')
355 self.waitUntilSettled()
356 self.worker.release('.*-merge')
357 self.waitUntilSettled()
358
359 self.assertEqual(len(self.builds), 6)
360 self.assertEqual(self.builds[0].name, 'project-test1')
361 self.assertEqual(self.builds[1].name, 'project-test2')
362 self.assertEqual(self.builds[2].name, 'project-test1')
363 self.assertEqual(self.builds[3].name, 'project-test2')
364 self.assertEqual(self.builds[4].name, 'project-test1')
365 self.assertEqual(self.builds[5].name, 'project-test2')
366
367 self.release(self.builds[2])
368 self.waitUntilSettled()
369
James E. Blair972e3c72013-08-29 12:04:55 -0700370 # project-test1 and project-test2 for A
371 # project-test2 for B
372 # project-merge for C (without B)
373 self.assertEqual(len(self.builds), 4)
James E. Blair0aac4872013-08-23 14:02:38 -0700374 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 2)
375
James E. Blair972e3c72013-08-29 12:04:55 -0700376 self.worker.release('.*-merge')
377 self.waitUntilSettled()
378
379 # project-test1 and project-test2 for A
380 # project-test2 for B
381 # project-test1 and project-test2 for C
382 self.assertEqual(len(self.builds), 5)
383
James E. Blair0aac4872013-08-23 14:02:38 -0700384 items = self.sched.layout.pipelines['gate'].getAllItems()
385 builds = items[0].current_build_set.getBuilds()
386 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
387 self.assertEqual(self.countJobResults(builds, None), 2)
388 builds = items[1].current_build_set.getBuilds()
389 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
390 self.assertEqual(self.countJobResults(builds, 'FAILURE'), 1)
391 self.assertEqual(self.countJobResults(builds, None), 1)
392 builds = items[2].current_build_set.getBuilds()
393 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
James E. Blair972e3c72013-08-29 12:04:55 -0700394 self.assertEqual(self.countJobResults(builds, None), 2)
James E. Blair0aac4872013-08-23 14:02:38 -0700395
396 self.worker.hold_jobs_in_build = False
397 self.worker.release()
398 self.waitUntilSettled()
399
400 self.assertEqual(len(self.builds), 0)
401 self.assertEqual(len(self.history), 12)
402 self.assertEqual(A.data['status'], 'MERGED')
403 self.assertEqual(B.data['status'], 'NEW')
404 self.assertEqual(C.data['status'], 'MERGED')
405 self.assertEqual(A.reported, 2)
406 self.assertEqual(B.reported, 2)
407 self.assertEqual(C.reported, 2)
408
James E. Blairec056492016-07-22 09:45:56 -0700409 @skip("Disabled for early v3 development")
James E. Blaird466dc42012-07-31 10:42:56 -0700410 def test_failed_change_at_head_with_queue(self):
411 "Test that if a change at the head fails, queued jobs are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700412
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700413 self.gearman_server.hold_jobs_in_queue = True
James E. Blaird466dc42012-07-31 10:42:56 -0700414 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
415 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
416 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700417 A.addApproval('CRVW', 2)
418 B.addApproval('CRVW', 2)
419 C.addApproval('CRVW', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700420
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700421 self.worker.addFailTest('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700422
423 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
424 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
425 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
426
427 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700428 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400429 self.assertEqual(len(self.builds), 0)
430 self.assertEqual(len(queue), 1)
431 self.assertEqual(queue[0].name, 'build:project-merge')
432 self.assertTrue(self.job_has_changes(queue[0], A))
James E. Blaird466dc42012-07-31 10:42:56 -0700433
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700434 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700435 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700436 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700437 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700438 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700439 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700440 queue = self.gearman_server.getQueue()
James E. Blaird466dc42012-07-31 10:42:56 -0700441
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400442 self.assertEqual(len(self.builds), 0)
443 self.assertEqual(len(queue), 6)
444 self.assertEqual(queue[0].name, 'build:project-test1')
445 self.assertEqual(queue[1].name, 'build:project-test2')
446 self.assertEqual(queue[2].name, 'build:project-test1')
447 self.assertEqual(queue[3].name, 'build:project-test2')
448 self.assertEqual(queue[4].name, 'build:project-test1')
449 self.assertEqual(queue[5].name, 'build:project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700450
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700451 self.release(queue[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700452 self.waitUntilSettled()
453
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400454 self.assertEqual(len(self.builds), 0)
James E. Blair701c5b42013-06-06 09:34:59 -0700455 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400456 self.assertEqual(len(queue), 2) # project-test2, project-merge for B
457 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 0)
James E. Blaird466dc42012-07-31 10:42:56 -0700458
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700459 self.gearman_server.hold_jobs_in_queue = False
460 self.gearman_server.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700461 self.waitUntilSettled()
462
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400463 self.assertEqual(len(self.builds), 0)
464 self.assertEqual(len(self.history), 11)
465 self.assertEqual(A.data['status'], 'NEW')
466 self.assertEqual(B.data['status'], 'MERGED')
467 self.assertEqual(C.data['status'], 'MERGED')
468 self.assertEqual(A.reported, 2)
469 self.assertEqual(B.reported, 2)
470 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700471
James E. Blairec056492016-07-22 09:45:56 -0700472 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700473 def _test_time_database(self, iteration):
474 self.worker.hold_jobs_in_build = True
475 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
476 A.addApproval('CRVW', 2)
477 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
478 self.waitUntilSettled()
479 time.sleep(2)
480
481 data = json.loads(self.sched.formatStatusJSON())
482 found_job = None
483 for pipeline in data['pipelines']:
484 if pipeline['name'] != 'gate':
485 continue
486 for queue in pipeline['change_queues']:
487 for head in queue['heads']:
488 for item in head:
489 for job in item['jobs']:
490 if job['name'] == 'project-merge':
491 found_job = job
492 break
493
494 self.assertIsNotNone(found_job)
495 if iteration == 1:
496 self.assertIsNotNone(found_job['estimated_time'])
497 self.assertIsNone(found_job['remaining_time'])
498 else:
499 self.assertIsNotNone(found_job['estimated_time'])
500 self.assertTrue(found_job['estimated_time'] >= 2)
501 self.assertIsNotNone(found_job['remaining_time'])
502
503 self.worker.hold_jobs_in_build = False
504 self.worker.release()
505 self.waitUntilSettled()
506
James E. Blairec056492016-07-22 09:45:56 -0700507 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700508 def test_time_database(self):
509 "Test the time database"
510
511 self._test_time_database(1)
512 self._test_time_database(2)
513
James E. Blairec056492016-07-22 09:45:56 -0700514 @skip("Disabled for early v3 development")
James E. Blairfef71632013-09-23 11:15:47 -0700515 def test_two_failed_changes_at_head(self):
516 "Test that changes are reparented correctly if 2 fail at head"
517
518 self.worker.hold_jobs_in_build = True
519 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
520 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
521 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
522 A.addApproval('CRVW', 2)
523 B.addApproval('CRVW', 2)
524 C.addApproval('CRVW', 2)
525
526 self.worker.addFailTest('project-test1', A)
527 self.worker.addFailTest('project-test1', B)
528
529 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
530 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
531 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
532 self.waitUntilSettled()
533
534 self.worker.release('.*-merge')
535 self.waitUntilSettled()
536 self.worker.release('.*-merge')
537 self.waitUntilSettled()
538 self.worker.release('.*-merge')
539 self.waitUntilSettled()
540
541 self.assertEqual(len(self.builds), 6)
542 self.assertEqual(self.builds[0].name, 'project-test1')
543 self.assertEqual(self.builds[1].name, 'project-test2')
544 self.assertEqual(self.builds[2].name, 'project-test1')
545 self.assertEqual(self.builds[3].name, 'project-test2')
546 self.assertEqual(self.builds[4].name, 'project-test1')
547 self.assertEqual(self.builds[5].name, 'project-test2')
548
549 self.assertTrue(self.job_has_changes(self.builds[0], A))
550 self.assertTrue(self.job_has_changes(self.builds[2], A))
551 self.assertTrue(self.job_has_changes(self.builds[2], B))
552 self.assertTrue(self.job_has_changes(self.builds[4], A))
553 self.assertTrue(self.job_has_changes(self.builds[4], B))
554 self.assertTrue(self.job_has_changes(self.builds[4], C))
555
556 # Fail change B first
557 self.release(self.builds[2])
558 self.waitUntilSettled()
559
560 # restart of C after B failure
561 self.worker.release('.*-merge')
562 self.waitUntilSettled()
563
564 self.assertEqual(len(self.builds), 5)
565 self.assertEqual(self.builds[0].name, 'project-test1')
566 self.assertEqual(self.builds[1].name, 'project-test2')
567 self.assertEqual(self.builds[2].name, 'project-test2')
568 self.assertEqual(self.builds[3].name, 'project-test1')
569 self.assertEqual(self.builds[4].name, 'project-test2')
570
571 self.assertTrue(self.job_has_changes(self.builds[1], A))
572 self.assertTrue(self.job_has_changes(self.builds[2], A))
573 self.assertTrue(self.job_has_changes(self.builds[2], B))
574 self.assertTrue(self.job_has_changes(self.builds[4], A))
575 self.assertFalse(self.job_has_changes(self.builds[4], B))
576 self.assertTrue(self.job_has_changes(self.builds[4], C))
577
578 # Finish running all passing jobs for change A
579 self.release(self.builds[1])
580 self.waitUntilSettled()
581 # Fail and report change A
582 self.release(self.builds[0])
583 self.waitUntilSettled()
584
585 # restart of B,C after A failure
586 self.worker.release('.*-merge')
587 self.waitUntilSettled()
588 self.worker.release('.*-merge')
589 self.waitUntilSettled()
590
591 self.assertEqual(len(self.builds), 4)
592 self.assertEqual(self.builds[0].name, 'project-test1') # B
593 self.assertEqual(self.builds[1].name, 'project-test2') # B
594 self.assertEqual(self.builds[2].name, 'project-test1') # C
595 self.assertEqual(self.builds[3].name, 'project-test2') # C
596
597 self.assertFalse(self.job_has_changes(self.builds[1], A))
598 self.assertTrue(self.job_has_changes(self.builds[1], B))
599 self.assertFalse(self.job_has_changes(self.builds[1], C))
600
601 self.assertFalse(self.job_has_changes(self.builds[2], A))
602 # After A failed and B and C restarted, B should be back in
603 # C's tests because it has not failed yet.
604 self.assertTrue(self.job_has_changes(self.builds[2], B))
605 self.assertTrue(self.job_has_changes(self.builds[2], C))
606
607 self.worker.hold_jobs_in_build = False
608 self.worker.release()
609 self.waitUntilSettled()
610
611 self.assertEqual(len(self.builds), 0)
612 self.assertEqual(len(self.history), 21)
613 self.assertEqual(A.data['status'], 'NEW')
614 self.assertEqual(B.data['status'], 'NEW')
615 self.assertEqual(C.data['status'], 'MERGED')
616 self.assertEqual(A.reported, 2)
617 self.assertEqual(B.reported, 2)
618 self.assertEqual(C.reported, 2)
619
James E. Blairec056492016-07-22 09:45:56 -0700620 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700621 def test_parse_skip_if(self):
622 job_yaml = """
623jobs:
624 - name: job_name
625 skip-if:
626 - project: ^project_name$
627 branch: ^stable/icehouse$
628 all-files-match-any:
629 - ^filename$
630 - project: ^project2_name$
631 all-files-match-any:
632 - ^filename2$
633 """.strip()
634 data = yaml.load(job_yaml)
635 config_job = data.get('jobs')[0]
636 cm = zuul.change_matcher
637 expected = cm.MatchAny([
638 cm.MatchAll([
639 cm.ProjectMatcher('^project_name$'),
640 cm.BranchMatcher('^stable/icehouse$'),
641 cm.MatchAllFiles([cm.FileMatcher('^filename$')]),
642 ]),
643 cm.MatchAll([
644 cm.ProjectMatcher('^project2_name$'),
645 cm.MatchAllFiles([cm.FileMatcher('^filename2$')]),
646 ]),
647 ])
648 matcher = self.sched._parseSkipIf(config_job)
649 self.assertEqual(expected, matcher)
650
James E. Blairec056492016-07-22 09:45:56 -0700651 @skip("Disabled for early v3 development")
James E. Blair8c803f82012-07-31 16:25:42 -0700652 def test_patch_order(self):
653 "Test that dependent patches are tested in the right order"
654 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
655 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
656 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
657 A.addApproval('CRVW', 2)
658 B.addApproval('CRVW', 2)
659 C.addApproval('CRVW', 2)
660
661 M2 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M2')
662 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
663 M2.setMerged()
664 M1.setMerged()
665
666 # C -> B -> A -> M1 -> M2
667 # M2 is here to make sure it is never queried. If it is, it
668 # means zuul is walking down the entire history of merged
669 # changes.
670
671 C.setDependsOn(B, 1)
672 B.setDependsOn(A, 1)
673 A.setDependsOn(M1, 1)
674 M1.setDependsOn(M2, 1)
675
676 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
677
678 self.waitUntilSettled()
679
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400680 self.assertEqual(A.data['status'], 'NEW')
681 self.assertEqual(B.data['status'], 'NEW')
682 self.assertEqual(C.data['status'], 'NEW')
James E. Blair8c803f82012-07-31 16:25:42 -0700683
684 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
685 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
686
687 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400688 self.assertEqual(M2.queried, 0)
689 self.assertEqual(A.data['status'], 'MERGED')
690 self.assertEqual(B.data['status'], 'MERGED')
691 self.assertEqual(C.data['status'], 'MERGED')
692 self.assertEqual(A.reported, 2)
693 self.assertEqual(B.reported, 2)
694 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700695
James E. Blairec056492016-07-22 09:45:56 -0700696 @skip("Disabled for early v3 development")
James E. Blair063672f2015-01-29 13:09:12 -0800697 def test_needed_changes_enqueue(self):
698 "Test that a needed change is enqueued ahead"
699 # A Given a git tree like this, if we enqueue
700 # / \ change C, we should walk up and down the tree
701 # B G and enqueue changes in the order ABCDEFG.
702 # /|\ This is also the order that you would get if
703 # *C E F you enqueued changes in the order ABCDEFG, so
704 # / the ordering is stable across re-enqueue events.
705 # D
706
707 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
708 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
709 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
710 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
711 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
712 F = self.fake_gerrit.addFakeChange('org/project', 'master', 'F')
713 G = self.fake_gerrit.addFakeChange('org/project', 'master', 'G')
714 B.setDependsOn(A, 1)
715 C.setDependsOn(B, 1)
716 D.setDependsOn(C, 1)
717 E.setDependsOn(B, 1)
718 F.setDependsOn(B, 1)
719 G.setDependsOn(A, 1)
720
721 A.addApproval('CRVW', 2)
722 B.addApproval('CRVW', 2)
723 C.addApproval('CRVW', 2)
724 D.addApproval('CRVW', 2)
725 E.addApproval('CRVW', 2)
726 F.addApproval('CRVW', 2)
727 G.addApproval('CRVW', 2)
728 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
729
730 self.waitUntilSettled()
731
732 self.assertEqual(A.data['status'], 'NEW')
733 self.assertEqual(B.data['status'], 'NEW')
734 self.assertEqual(C.data['status'], 'NEW')
735 self.assertEqual(D.data['status'], 'NEW')
736 self.assertEqual(E.data['status'], 'NEW')
737 self.assertEqual(F.data['status'], 'NEW')
738 self.assertEqual(G.data['status'], 'NEW')
739
740 # We're about to add approvals to changes without adding the
741 # triggering events to Zuul, so that we can be sure that it is
742 # enqueing the changes based on dependencies, not because of
743 # triggering events. Since it will have the changes cached
744 # already (without approvals), we need to clear the cache
745 # first.
Joshua Hesketh4bd7da32016-02-17 20:58:47 +1100746 for connection in self.connections.values():
747 connection.maintainCache([])
James E. Blair063672f2015-01-29 13:09:12 -0800748
749 self.worker.hold_jobs_in_build = True
750 A.addApproval('APRV', 1)
751 B.addApproval('APRV', 1)
752 D.addApproval('APRV', 1)
753 E.addApproval('APRV', 1)
754 F.addApproval('APRV', 1)
755 G.addApproval('APRV', 1)
756 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
757
758 for x in range(8):
759 self.worker.release('.*-merge')
760 self.waitUntilSettled()
761 self.worker.hold_jobs_in_build = False
762 self.worker.release()
763 self.waitUntilSettled()
764
765 self.assertEqual(A.data['status'], 'MERGED')
766 self.assertEqual(B.data['status'], 'MERGED')
767 self.assertEqual(C.data['status'], 'MERGED')
768 self.assertEqual(D.data['status'], 'MERGED')
769 self.assertEqual(E.data['status'], 'MERGED')
770 self.assertEqual(F.data['status'], 'MERGED')
771 self.assertEqual(G.data['status'], 'MERGED')
772 self.assertEqual(A.reported, 2)
773 self.assertEqual(B.reported, 2)
774 self.assertEqual(C.reported, 2)
775 self.assertEqual(D.reported, 2)
776 self.assertEqual(E.reported, 2)
777 self.assertEqual(F.reported, 2)
778 self.assertEqual(G.reported, 2)
779 self.assertEqual(self.history[6].changes,
780 '1,1 2,1 3,1 4,1 5,1 6,1 7,1')
781
James E. Blairec056492016-07-22 09:45:56 -0700782 @skip("Disabled for early v3 development")
Joshua Hesketh850ccb62014-11-27 11:31:02 +1100783 def test_source_cache(self):
784 "Test that the source cache operates correctly"
James E. Blair0e933c52013-07-11 10:18:52 -0700785 self.worker.hold_jobs_in_build = True
786
787 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
788 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
789 X = self.fake_gerrit.addFakeChange('org/project', 'master', 'X')
790 A.addApproval('CRVW', 2)
791 B.addApproval('CRVW', 2)
792
793 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
794 M1.setMerged()
795
796 B.setDependsOn(A, 1)
797 A.setDependsOn(M1, 1)
798
799 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
800 self.fake_gerrit.addEvent(X.getPatchsetCreatedEvent(1))
801
802 self.waitUntilSettled()
803
804 for build in self.builds:
805 if build.parameters['ZUUL_PIPELINE'] == 'check':
806 build.release()
807 self.waitUntilSettled()
808 for build in self.builds:
809 if build.parameters['ZUUL_PIPELINE'] == 'check':
810 build.release()
811 self.waitUntilSettled()
812
813 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
814 self.waitUntilSettled()
815
Joshua Hesketh352264b2015-08-11 23:42:08 +1000816 self.log.debug("len %s" % self.fake_gerrit._change_cache.keys())
James E. Blair0e933c52013-07-11 10:18:52 -0700817 # there should still be changes in the cache
Joshua Hesketh352264b2015-08-11 23:42:08 +1000818 self.assertNotEqual(len(self.fake_gerrit._change_cache.keys()), 0)
James E. Blair0e933c52013-07-11 10:18:52 -0700819
820 self.worker.hold_jobs_in_build = False
821 self.worker.release()
822 self.waitUntilSettled()
823
824 self.assertEqual(A.data['status'], 'MERGED')
825 self.assertEqual(B.data['status'], 'MERGED')
826 self.assertEqual(A.queried, 2) # Initial and isMerged
827 self.assertEqual(B.queried, 3) # Initial A, refresh from B, isMerged
828
James E. Blairec056492016-07-22 09:45:56 -0700829 @skip("Disabled for early v3 development")
James E. Blair8c803f82012-07-31 16:25:42 -0700830 def test_can_merge(self):
James E. Blair4886cc12012-07-18 15:39:41 -0700831 "Test whether a change is ready to merge"
James E. Blair8c803f82012-07-31 16:25:42 -0700832 # TODO: move to test_gerrit (this is a unit test!)
833 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairc0dedf82014-08-06 09:37:52 -0700834 source = self.sched.layout.pipelines['gate'].source
835 a = source._getChange(1, 2)
James E. Blaireff88162013-07-01 12:44:14 -0400836 mgr = self.sched.layout.pipelines['gate'].manager
James E. Blairc0dedf82014-08-06 09:37:52 -0700837 self.assertFalse(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700838
839 A.addApproval('CRVW', 2)
James E. Blairc0dedf82014-08-06 09:37:52 -0700840 a = source._getChange(1, 2, refresh=True)
841 self.assertFalse(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700842
843 A.addApproval('APRV', 1)
James E. Blairc0dedf82014-08-06 09:37:52 -0700844 a = source._getChange(1, 2, refresh=True)
845 self.assertTrue(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair4886cc12012-07-18 15:39:41 -0700846
James E. Blairec056492016-07-22 09:45:56 -0700847 @skip("Disabled for early v3 development")
James E. Blair4886cc12012-07-18 15:39:41 -0700848 def test_build_configuration(self):
849 "Test that zuul merges the right commits for testing"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700850
851 self.gearman_server.hold_jobs_in_queue = True
James E. Blair4886cc12012-07-18 15:39:41 -0700852 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
853 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
854 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
855 A.addApproval('CRVW', 2)
856 B.addApproval('CRVW', 2)
857 C.addApproval('CRVW', 2)
858 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
859 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
860 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
861 self.waitUntilSettled()
862
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700863 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700864 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700865 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700866 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700867 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700868 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700869 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700870 ref = self.getParameter(queue[-1], 'ZUUL_REF')
871 self.gearman_server.hold_jobs_in_queue = False
872 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700873 self.waitUntilSettled()
James E. Blair4886cc12012-07-18 15:39:41 -0700874
Monty Taylorbc758832013-06-17 17:22:42 -0400875 path = os.path.join(self.git_root, "org/project")
James E. Blair4886cc12012-07-18 15:39:41 -0700876 repo = git.Repo(path)
877 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
878 repo_messages.reverse()
James E. Blair4886cc12012-07-18 15:39:41 -0700879 correct_messages = ['initial commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400880 self.assertEqual(repo_messages, correct_messages)
James E. Blair973721f2012-08-15 10:19:43 -0700881
James E. Blairec056492016-07-22 09:45:56 -0700882 @skip("Disabled for early v3 development")
James E. Blair973721f2012-08-15 10:19:43 -0700883 def test_build_configuration_conflict(self):
884 "Test that merge conflicts are handled"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700885
886 self.gearman_server.hold_jobs_in_queue = True
James E. Blair6736beb2013-07-11 15:18:15 -0700887 A = self.fake_gerrit.addFakeChange('org/conflict-project',
888 'master', 'A')
James E. Blair973721f2012-08-15 10:19:43 -0700889 A.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700890 B = self.fake_gerrit.addFakeChange('org/conflict-project',
891 'master', 'B')
James E. Blair973721f2012-08-15 10:19:43 -0700892 B.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700893 C = self.fake_gerrit.addFakeChange('org/conflict-project',
894 'master', 'C')
James E. Blair973721f2012-08-15 10:19:43 -0700895 A.addApproval('CRVW', 2)
896 B.addApproval('CRVW', 2)
897 C.addApproval('CRVW', 2)
898 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
899 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
900 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
901 self.waitUntilSettled()
902
James E. Blair6736beb2013-07-11 15:18:15 -0700903 self.assertEqual(A.reported, 1)
904 self.assertEqual(B.reported, 1)
905 self.assertEqual(C.reported, 1)
906
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700907 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700908 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700909 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700910 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700911 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700912 self.waitUntilSettled()
James E. Blair972e3c72013-08-29 12:04:55 -0700913
914 self.assertEqual(len(self.history), 2) # A and C merge jobs
915
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700916 self.gearman_server.hold_jobs_in_queue = False
917 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700918 self.waitUntilSettled()
919
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400920 self.assertEqual(A.data['status'], 'MERGED')
921 self.assertEqual(B.data['status'], 'NEW')
922 self.assertEqual(C.data['status'], 'MERGED')
923 self.assertEqual(A.reported, 2)
924 self.assertEqual(B.reported, 2)
925 self.assertEqual(C.reported, 2)
James E. Blair972e3c72013-08-29 12:04:55 -0700926 self.assertEqual(len(self.history), 6)
James E. Blair6736beb2013-07-11 15:18:15 -0700927
James E. Blairec056492016-07-22 09:45:56 -0700928 @skip("Disabled for early v3 development")
James E. Blairdaabed22012-08-15 15:38:57 -0700929 def test_post(self):
930 "Test that post jobs run"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700931
Zhongyue Luo5d556072012-09-21 02:00:47 +0900932 e = {
933 "type": "ref-updated",
934 "submitter": {
935 "name": "User Name",
936 },
937 "refUpdate": {
938 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
939 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
940 "refName": "master",
941 "project": "org/project",
942 }
943 }
James E. Blairdaabed22012-08-15 15:38:57 -0700944 self.fake_gerrit.addEvent(e)
945 self.waitUntilSettled()
946
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400947 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400948 self.assertEqual(len(self.history), 1)
949 self.assertIn('project-post', job_names)
James E. Blairc6294a52012-08-17 10:19:48 -0700950
James E. Blairec056492016-07-22 09:45:56 -0700951 @skip("Disabled for early v3 development")
K Jonathan Harkerf95e7232015-04-29 13:33:16 -0700952 def test_post_ignore_deletes(self):
953 "Test that deleting refs does not trigger post jobs"
954
955 e = {
956 "type": "ref-updated",
957 "submitter": {
958 "name": "User Name",
959 },
960 "refUpdate": {
961 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
962 "newRev": "0000000000000000000000000000000000000000",
963 "refName": "master",
964 "project": "org/project",
965 }
966 }
967 self.fake_gerrit.addEvent(e)
968 self.waitUntilSettled()
969
970 job_names = [x.name for x in self.history]
971 self.assertEqual(len(self.history), 0)
972 self.assertNotIn('project-post', job_names)
973
James E. Blairec056492016-07-22 09:45:56 -0700974 @skip("Disabled for early v3 development")
K Jonathan Harkerf95e7232015-04-29 13:33:16 -0700975 def test_post_ignore_deletes_negative(self):
976 "Test that deleting refs does trigger post jobs"
977
James E. Blairf84026c2015-12-08 16:11:46 -0800978 self.updateConfigLayout(
979 'tests/fixtures/layout-dont-ignore-deletes.yaml')
K Jonathan Harkerf95e7232015-04-29 13:33:16 -0700980 self.sched.reconfigure(self.config)
981
982 e = {
983 "type": "ref-updated",
984 "submitter": {
985 "name": "User Name",
986 },
987 "refUpdate": {
988 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
989 "newRev": "0000000000000000000000000000000000000000",
990 "refName": "master",
991 "project": "org/project",
992 }
993 }
994 self.fake_gerrit.addEvent(e)
995 self.waitUntilSettled()
996
997 job_names = [x.name for x in self.history]
998 self.assertEqual(len(self.history), 1)
999 self.assertIn('project-post', job_names)
1000
James E. Blairec056492016-07-22 09:45:56 -07001001 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001002 def test_build_configuration_branch(self):
1003 "Test that the right commits are on alternate branches"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001004
1005 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -07001006 A = self.fake_gerrit.addFakeChange('org/project', 'mp', 'A')
1007 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
1008 C = self.fake_gerrit.addFakeChange('org/project', 'mp', 'C')
1009 A.addApproval('CRVW', 2)
1010 B.addApproval('CRVW', 2)
1011 C.addApproval('CRVW', 2)
1012 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1013 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1014 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1015 self.waitUntilSettled()
1016
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001017 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001018 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001019 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001020 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001021 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001022 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001023 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001024 ref = self.getParameter(queue[-1], 'ZUUL_REF')
1025 self.gearman_server.hold_jobs_in_queue = False
1026 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -07001027 self.waitUntilSettled()
1028
Monty Taylorbc758832013-06-17 17:22:42 -04001029 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001030 repo = git.Repo(path)
1031 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
1032 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001033 correct_messages = ['initial commit', 'mp commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001034 self.assertEqual(repo_messages, correct_messages)
James E. Blairc6294a52012-08-17 10:19:48 -07001035
James E. Blairec056492016-07-22 09:45:56 -07001036 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001037 def test_build_configuration_branch_interaction(self):
1038 "Test that switching between branches works"
1039 self.test_build_configuration()
1040 self.test_build_configuration_branch()
1041 # C has been merged, undo that
Monty Taylorbc758832013-06-17 17:22:42 -04001042 path = os.path.join(self.upstream_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001043 repo = git.Repo(path)
1044 repo.heads.master.commit = repo.commit('init')
1045 self.test_build_configuration()
1046
James E. Blairec056492016-07-22 09:45:56 -07001047 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001048 def test_build_configuration_multi_branch(self):
1049 "Test that dependent changes on multiple branches are merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001050
1051 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -07001052 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1053 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
1054 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1055 A.addApproval('CRVW', 2)
1056 B.addApproval('CRVW', 2)
1057 C.addApproval('CRVW', 2)
1058 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1059 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1060 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1061 self.waitUntilSettled()
James E. Blairbb1fe502014-03-04 10:15:06 -08001062 queue = self.gearman_server.getQueue()
1063 job_A = None
1064 for job in queue:
1065 if 'project-merge' in job.name:
1066 job_A = job
1067 ref_A = self.getParameter(job_A, 'ZUUL_REF')
1068 commit_A = self.getParameter(job_A, 'ZUUL_COMMIT')
1069 self.log.debug("Got Zuul ref for change A: %s" % ref_A)
1070 self.log.debug("Got Zuul commit for change A: %s" % commit_A)
James E. Blairc6294a52012-08-17 10:19:48 -07001071
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001072 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001073 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001074 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -07001075 job_B = None
1076 for job in queue:
1077 if 'project-merge' in job.name:
1078 job_B = job
1079 ref_B = self.getParameter(job_B, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -08001080 commit_B = self.getParameter(job_B, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -07001081 self.log.debug("Got Zuul ref for change B: %s" % ref_B)
James E. Blairbb1fe502014-03-04 10:15:06 -08001082 self.log.debug("Got Zuul commit for change B: %s" % commit_B)
1083
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001084 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001085 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001086 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -07001087 for job in queue:
1088 if 'project-merge' in job.name:
1089 job_C = job
1090 ref_C = self.getParameter(job_C, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -08001091 commit_C = self.getParameter(job_C, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -07001092 self.log.debug("Got Zuul ref for change C: %s" % ref_C)
James E. Blairbb1fe502014-03-04 10:15:06 -08001093 self.log.debug("Got Zuul commit for change C: %s" % commit_C)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001094 self.gearman_server.hold_jobs_in_queue = False
1095 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -07001096 self.waitUntilSettled()
1097
Monty Taylorbc758832013-06-17 17:22:42 -04001098 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001099 repo = git.Repo(path)
1100
1101 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -07001102 for c in repo.iter_commits(ref_C)]
James E. Blairbb1fe502014-03-04 10:15:06 -08001103 repo_shas = [c.hexsha for c in repo.iter_commits(ref_C)]
James E. Blairc6294a52012-08-17 10:19:48 -07001104 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001105 correct_messages = ['initial commit', 'A-1', 'C-1']
James E. Blairbb1fe502014-03-04 10:15:06 -08001106 # Ensure the right commits are in the history for this ref
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001107 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -08001108 # Ensure ZUUL_REF -> ZUUL_COMMIT
1109 self.assertEqual(repo_shas[0], commit_C)
James E. Blairc6294a52012-08-17 10:19:48 -07001110
1111 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -07001112 for c in repo.iter_commits(ref_B)]
James E. Blairbb1fe502014-03-04 10:15:06 -08001113 repo_shas = [c.hexsha for c in repo.iter_commits(ref_B)]
James E. Blairc6294a52012-08-17 10:19:48 -07001114 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001115 correct_messages = ['initial commit', 'mp commit', 'B-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001116 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -08001117 self.assertEqual(repo_shas[0], commit_B)
1118
1119 repo_messages = [c.message.strip()
1120 for c in repo.iter_commits(ref_A)]
1121 repo_shas = [c.hexsha for c in repo.iter_commits(ref_A)]
1122 repo_messages.reverse()
1123 correct_messages = ['initial commit', 'A-1']
1124 self.assertEqual(repo_messages, correct_messages)
1125 self.assertEqual(repo_shas[0], commit_A)
1126
1127 self.assertNotEqual(ref_A, ref_B, ref_C)
1128 self.assertNotEqual(commit_A, commit_B, commit_C)
James E. Blair7f71c802012-08-22 13:04:32 -07001129
James E. Blairec056492016-07-22 09:45:56 -07001130 @skip("Disabled for early v3 development")
James E. Blair7f71c802012-08-22 13:04:32 -07001131 def test_one_job_project(self):
1132 "Test that queueing works with one job"
1133 A = self.fake_gerrit.addFakeChange('org/one-job-project',
1134 'master', 'A')
1135 B = self.fake_gerrit.addFakeChange('org/one-job-project',
1136 'master', 'B')
1137 A.addApproval('CRVW', 2)
1138 B.addApproval('CRVW', 2)
1139 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1140 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1141 self.waitUntilSettled()
1142
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001143 self.assertEqual(A.data['status'], 'MERGED')
1144 self.assertEqual(A.reported, 2)
1145 self.assertEqual(B.data['status'], 'MERGED')
1146 self.assertEqual(B.reported, 2)
James E. Blaircaec0c52012-08-22 14:52:22 -07001147
James E. Blairec056492016-07-22 09:45:56 -07001148 @skip("Disabled for early v3 development")
Antoine Musso80edd5a2013-02-13 15:37:53 +01001149 def test_job_from_templates_launched(self):
1150 "Test whether a job generated via a template can be launched"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001151
Antoine Musso80edd5a2013-02-13 15:37:53 +01001152 A = self.fake_gerrit.addFakeChange(
1153 'org/templated-project', 'master', 'A')
1154 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1155 self.waitUntilSettled()
Antoine Musso80edd5a2013-02-13 15:37:53 +01001156
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001157 self.assertEqual(self.getJobFromHistory('project-test1').result,
1158 'SUCCESS')
1159 self.assertEqual(self.getJobFromHistory('project-test2').result,
1160 'SUCCESS')
Antoine Musso80edd5a2013-02-13 15:37:53 +01001161
James E. Blairec056492016-07-22 09:45:56 -07001162 @skip("Disabled for early v3 development")
James E. Blair3e98c022013-12-16 15:25:38 -08001163 def test_layered_templates(self):
1164 "Test whether a job generated via a template can be launched"
1165
1166 A = self.fake_gerrit.addFakeChange(
1167 'org/layered-project', 'master', 'A')
1168 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1169 self.waitUntilSettled()
1170
1171 self.assertEqual(self.getJobFromHistory('project-test1').result,
1172 'SUCCESS')
1173 self.assertEqual(self.getJobFromHistory('project-test2').result,
1174 'SUCCESS')
James E. Blairaea6cf62013-12-16 15:38:12 -08001175 self.assertEqual(self.getJobFromHistory('layered-project-test3'
1176 ).result, 'SUCCESS')
1177 self.assertEqual(self.getJobFromHistory('layered-project-test4'
1178 ).result, 'SUCCESS')
James E. Blair12a92b12014-03-26 11:54:53 -07001179 self.assertEqual(self.getJobFromHistory('layered-project-foo-test5'
1180 ).result, 'SUCCESS')
James E. Blair3e98c022013-12-16 15:25:38 -08001181 self.assertEqual(self.getJobFromHistory('project-test6').result,
1182 'SUCCESS')
1183
James E. Blairec056492016-07-22 09:45:56 -07001184 @skip("Disabled for early v3 development")
James E. Blaircaec0c52012-08-22 14:52:22 -07001185 def test_dependent_changes_dequeue(self):
1186 "Test that dependent patches are not needlessly tested"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001187
James E. Blaircaec0c52012-08-22 14:52:22 -07001188 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1189 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1190 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1191 A.addApproval('CRVW', 2)
1192 B.addApproval('CRVW', 2)
1193 C.addApproval('CRVW', 2)
1194
1195 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
1196 M1.setMerged()
1197
1198 # C -> B -> A -> M1
1199
1200 C.setDependsOn(B, 1)
1201 B.setDependsOn(A, 1)
1202 A.setDependsOn(M1, 1)
1203
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001204 self.worker.addFailTest('project-merge', A)
James E. Blaircaec0c52012-08-22 14:52:22 -07001205
1206 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1207 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1208 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1209
1210 self.waitUntilSettled()
1211
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001212 self.assertEqual(A.data['status'], 'NEW')
1213 self.assertEqual(A.reported, 2)
1214 self.assertEqual(B.data['status'], 'NEW')
1215 self.assertEqual(B.reported, 2)
1216 self.assertEqual(C.data['status'], 'NEW')
1217 self.assertEqual(C.reported, 2)
1218 self.assertEqual(len(self.history), 1)
James E. Blairec590122012-08-22 15:19:31 -07001219
James E. Blairec056492016-07-22 09:45:56 -07001220 @skip("Disabled for early v3 development")
James E. Blair972e3c72013-08-29 12:04:55 -07001221 def test_failing_dependent_changes(self):
1222 "Test that failing dependent patches are taken out of stream"
1223 self.worker.hold_jobs_in_build = True
1224 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1225 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1226 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1227 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1228 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
1229 A.addApproval('CRVW', 2)
1230 B.addApproval('CRVW', 2)
1231 C.addApproval('CRVW', 2)
1232 D.addApproval('CRVW', 2)
1233 E.addApproval('CRVW', 2)
1234
1235 # E, D -> C -> B, A
1236
1237 D.setDependsOn(C, 1)
1238 C.setDependsOn(B, 1)
1239
1240 self.worker.addFailTest('project-test1', B)
1241
1242 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1243 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1244 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1245 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1246 self.fake_gerrit.addEvent(E.addApproval('APRV', 1))
1247
1248 self.waitUntilSettled()
1249 self.worker.release('.*-merge')
1250 self.waitUntilSettled()
1251 self.worker.release('.*-merge')
1252 self.waitUntilSettled()
1253 self.worker.release('.*-merge')
1254 self.waitUntilSettled()
1255 self.worker.release('.*-merge')
1256 self.waitUntilSettled()
1257 self.worker.release('.*-merge')
1258 self.waitUntilSettled()
1259
1260 self.worker.hold_jobs_in_build = False
1261 for build in self.builds:
1262 if build.parameters['ZUUL_CHANGE'] != '1':
1263 build.release()
1264 self.waitUntilSettled()
1265
1266 self.worker.release()
1267 self.waitUntilSettled()
1268
1269 self.assertEqual(A.data['status'], 'MERGED')
1270 self.assertEqual(A.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001271 self.assertIn('Build succeeded', A.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001272 self.assertEqual(B.data['status'], 'NEW')
1273 self.assertEqual(B.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001274 self.assertIn('Build failed', B.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001275 self.assertEqual(C.data['status'], 'NEW')
1276 self.assertEqual(C.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001277 self.assertIn('depends on a change', C.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001278 self.assertEqual(D.data['status'], 'NEW')
1279 self.assertEqual(D.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001280 self.assertIn('depends on a change', D.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001281 self.assertEqual(E.data['status'], 'MERGED')
1282 self.assertEqual(E.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001283 self.assertIn('Build succeeded', E.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001284 self.assertEqual(len(self.history), 18)
1285
James E. Blairec056492016-07-22 09:45:56 -07001286 @skip("Disabled for early v3 development")
James E. Blairec590122012-08-22 15:19:31 -07001287 def test_head_is_dequeued_once(self):
James E. Blair2fa50962013-01-30 21:50:41 -08001288 "Test that if a change at the head fails it is dequeued only once"
James E. Blairec590122012-08-22 15:19:31 -07001289 # If it's dequeued more than once, we should see extra
1290 # aborted jobs.
James E. Blairec590122012-08-22 15:19:31 -07001291
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001292 self.worker.hold_jobs_in_build = True
James E. Blairec590122012-08-22 15:19:31 -07001293 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1294 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1295 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
1296 A.addApproval('CRVW', 2)
1297 B.addApproval('CRVW', 2)
1298 C.addApproval('CRVW', 2)
1299
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001300 self.worker.addFailTest('project1-test1', A)
1301 self.worker.addFailTest('project1-test2', A)
1302 self.worker.addFailTest('project1-project2-integration', A)
James E. Blairec590122012-08-22 15:19:31 -07001303
1304 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1305 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1306 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1307
1308 self.waitUntilSettled()
James E. Blairec590122012-08-22 15:19:31 -07001309
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001310 self.assertEqual(len(self.builds), 1)
1311 self.assertEqual(self.builds[0].name, 'project1-merge')
1312 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blairec590122012-08-22 15:19:31 -07001313
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001314 self.worker.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001315 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001316 self.worker.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001317 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001318 self.worker.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001319 self.waitUntilSettled()
1320
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001321 self.assertEqual(len(self.builds), 9)
1322 self.assertEqual(self.builds[0].name, 'project1-test1')
1323 self.assertEqual(self.builds[1].name, 'project1-test2')
1324 self.assertEqual(self.builds[2].name, 'project1-project2-integration')
1325 self.assertEqual(self.builds[3].name, 'project1-test1')
1326 self.assertEqual(self.builds[4].name, 'project1-test2')
1327 self.assertEqual(self.builds[5].name, 'project1-project2-integration')
1328 self.assertEqual(self.builds[6].name, 'project1-test1')
1329 self.assertEqual(self.builds[7].name, 'project1-test2')
1330 self.assertEqual(self.builds[8].name, 'project1-project2-integration')
James E. Blairec590122012-08-22 15:19:31 -07001331
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001332 self.release(self.builds[0])
James E. Blairec590122012-08-22 15:19:31 -07001333 self.waitUntilSettled()
1334
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001335 self.assertEqual(len(self.builds), 3) # test2,integration, merge for B
1336 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 6)
James E. Blairec590122012-08-22 15:19:31 -07001337
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001338 self.worker.hold_jobs_in_build = False
1339 self.worker.release()
James E. Blairec590122012-08-22 15:19:31 -07001340 self.waitUntilSettled()
1341
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001342 self.assertEqual(len(self.builds), 0)
1343 self.assertEqual(len(self.history), 20)
James E. Blaircaec0c52012-08-22 14:52:22 -07001344
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001345 self.assertEqual(A.data['status'], 'NEW')
1346 self.assertEqual(B.data['status'], 'MERGED')
1347 self.assertEqual(C.data['status'], 'MERGED')
1348 self.assertEqual(A.reported, 2)
1349 self.assertEqual(B.reported, 2)
1350 self.assertEqual(C.reported, 2)
James E. Blair4ec821f2012-08-23 15:28:28 -07001351
James E. Blairec056492016-07-22 09:45:56 -07001352 @skip("Disabled for early v3 development")
James E. Blair4ec821f2012-08-23 15:28:28 -07001353 def test_nonvoting_job(self):
1354 "Test that non-voting jobs don't vote."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001355
James E. Blair4ec821f2012-08-23 15:28:28 -07001356 A = self.fake_gerrit.addFakeChange('org/nonvoting-project',
1357 'master', 'A')
1358 A.addApproval('CRVW', 2)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001359 self.worker.addFailTest('nonvoting-project-test2', A)
James E. Blair4ec821f2012-08-23 15:28:28 -07001360 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1361
1362 self.waitUntilSettled()
James E. Blair4ec821f2012-08-23 15:28:28 -07001363
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001364 self.assertEqual(A.data['status'], 'MERGED')
1365 self.assertEqual(A.reported, 2)
1366 self.assertEqual(
1367 self.getJobFromHistory('nonvoting-project-merge').result,
1368 'SUCCESS')
1369 self.assertEqual(
1370 self.getJobFromHistory('nonvoting-project-test1').result,
1371 'SUCCESS')
1372 self.assertEqual(
1373 self.getJobFromHistory('nonvoting-project-test2').result,
1374 'FAILURE')
James E. Blaire0487072012-08-29 17:38:31 -07001375
James E. Blair5821bd92015-09-16 08:48:15 -07001376 for build in self.builds:
1377 self.assertEqual(build.parameters['ZUUL_VOTING'], '0')
1378
James E. Blairec056492016-07-22 09:45:56 -07001379 @skip("Disabled for early v3 development")
James E. Blaire0487072012-08-29 17:38:31 -07001380 def test_check_queue_success(self):
1381 "Test successful check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001382
James E. Blaire0487072012-08-29 17:38:31 -07001383 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1384 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1385
1386 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001387
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001388 self.assertEqual(A.data['status'], 'NEW')
1389 self.assertEqual(A.reported, 1)
1390 self.assertEqual(self.getJobFromHistory('project-merge').result,
1391 'SUCCESS')
1392 self.assertEqual(self.getJobFromHistory('project-test1').result,
1393 'SUCCESS')
1394 self.assertEqual(self.getJobFromHistory('project-test2').result,
1395 'SUCCESS')
James E. Blaire0487072012-08-29 17:38:31 -07001396
James E. Blairec056492016-07-22 09:45:56 -07001397 @skip("Disabled for early v3 development")
James E. Blaire0487072012-08-29 17:38:31 -07001398 def test_check_queue_failure(self):
1399 "Test failed check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001400
James E. Blaire0487072012-08-29 17:38:31 -07001401 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001402 self.worker.addFailTest('project-test2', A)
James E. Blaire0487072012-08-29 17:38:31 -07001403 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1404
1405 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001406
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001407 self.assertEqual(A.data['status'], 'NEW')
1408 self.assertEqual(A.reported, 1)
1409 self.assertEqual(self.getJobFromHistory('project-merge').result,
James E. Blair78e31b32013-07-09 09:11:34 -07001410 'SUCCESS')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001411 self.assertEqual(self.getJobFromHistory('project-test1').result,
1412 'SUCCESS')
1413 self.assertEqual(self.getJobFromHistory('project-test2').result,
1414 'FAILURE')
James E. Blair127bc182012-08-28 15:55:15 -07001415
James E. Blairec056492016-07-22 09:45:56 -07001416 @skip("Disabled for early v3 development")
James E. Blair127bc182012-08-28 15:55:15 -07001417 def test_dependent_behind_dequeue(self):
1418 "test that dependent changes behind dequeued changes work"
1419 # This complicated test is a reproduction of a real life bug
1420 self.sched.reconfigure(self.config)
James E. Blair127bc182012-08-28 15:55:15 -07001421
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001422 self.worker.hold_jobs_in_build = True
James E. Blair127bc182012-08-28 15:55:15 -07001423 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1424 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1425 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
1426 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
1427 E = self.fake_gerrit.addFakeChange('org/project2', 'master', 'E')
1428 F = self.fake_gerrit.addFakeChange('org/project3', 'master', 'F')
1429 D.setDependsOn(C, 1)
1430 E.setDependsOn(D, 1)
1431 A.addApproval('CRVW', 2)
1432 B.addApproval('CRVW', 2)
1433 C.addApproval('CRVW', 2)
1434 D.addApproval('CRVW', 2)
1435 E.addApproval('CRVW', 2)
1436 F.addApproval('CRVW', 2)
1437
1438 A.fail_merge = True
James E. Blair127bc182012-08-28 15:55:15 -07001439
1440 # Change object re-use in the gerrit trigger is hidden if
1441 # changes are added in quick succession; waiting makes it more
1442 # like real life.
1443 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1444 self.waitUntilSettled()
1445 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1446 self.waitUntilSettled()
1447
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001448 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001449 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001450 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001451 self.waitUntilSettled()
1452
1453 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1454 self.waitUntilSettled()
1455 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1456 self.waitUntilSettled()
1457 self.fake_gerrit.addEvent(E.addApproval('APRV', 1))
1458 self.waitUntilSettled()
1459 self.fake_gerrit.addEvent(F.addApproval('APRV', 1))
1460 self.waitUntilSettled()
1461
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001462 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001463 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001464 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001465 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001466 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001467 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001468 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001469 self.waitUntilSettled()
1470
1471 # all jobs running
James E. Blaire955e062012-10-08 09:49:03 -07001472
1473 # Grab pointers to the jobs we want to release before
1474 # releasing any, because list indexes may change as
1475 # the jobs complete.
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001476 a, b, c = self.builds[:3]
James E. Blaire955e062012-10-08 09:49:03 -07001477 a.release()
1478 b.release()
1479 c.release()
James E. Blair127bc182012-08-28 15:55:15 -07001480 self.waitUntilSettled()
1481
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001482 self.worker.hold_jobs_in_build = False
1483 self.worker.release()
James E. Blair127bc182012-08-28 15:55:15 -07001484 self.waitUntilSettled()
1485
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001486 self.assertEqual(A.data['status'], 'NEW')
1487 self.assertEqual(B.data['status'], 'MERGED')
1488 self.assertEqual(C.data['status'], 'MERGED')
1489 self.assertEqual(D.data['status'], 'MERGED')
1490 self.assertEqual(E.data['status'], 'MERGED')
1491 self.assertEqual(F.data['status'], 'MERGED')
James E. Blair127bc182012-08-28 15:55:15 -07001492
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001493 self.assertEqual(A.reported, 2)
1494 self.assertEqual(B.reported, 2)
1495 self.assertEqual(C.reported, 2)
1496 self.assertEqual(D.reported, 2)
1497 self.assertEqual(E.reported, 2)
1498 self.assertEqual(F.reported, 2)
James E. Blair127bc182012-08-28 15:55:15 -07001499
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001500 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 15)
1501 self.assertEqual(len(self.history), 44)
James E. Blair05fed602012-09-07 12:45:24 -07001502
James E. Blairec056492016-07-22 09:45:56 -07001503 @skip("Disabled for early v3 development")
James E. Blair05fed602012-09-07 12:45:24 -07001504 def test_merger_repack(self):
1505 "Test that the merger works after a repack"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001506
James E. Blair05fed602012-09-07 12:45:24 -07001507 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1508 A.addApproval('CRVW', 2)
1509 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1510 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001511 self.assertEqual(self.getJobFromHistory('project-merge').result,
1512 'SUCCESS')
1513 self.assertEqual(self.getJobFromHistory('project-test1').result,
1514 'SUCCESS')
1515 self.assertEqual(self.getJobFromHistory('project-test2').result,
1516 'SUCCESS')
1517 self.assertEqual(A.data['status'], 'MERGED')
1518 self.assertEqual(A.reported, 2)
James E. Blair05fed602012-09-07 12:45:24 -07001519 self.assertEmptyQueues()
James E. Blair4ca985f2013-05-30 12:27:43 -07001520 self.worker.build_history = []
James E. Blair05fed602012-09-07 12:45:24 -07001521
Monty Taylorbc758832013-06-17 17:22:42 -04001522 path = os.path.join(self.git_root, "org/project")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001523 print(repack_repo(path))
James E. Blair05fed602012-09-07 12:45:24 -07001524
1525 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1526 A.addApproval('CRVW', 2)
1527 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1528 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001529 self.assertEqual(self.getJobFromHistory('project-merge').result,
1530 'SUCCESS')
1531 self.assertEqual(self.getJobFromHistory('project-test1').result,
1532 'SUCCESS')
1533 self.assertEqual(self.getJobFromHistory('project-test2').result,
1534 'SUCCESS')
1535 self.assertEqual(A.data['status'], 'MERGED')
1536 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001537
James E. Blairec056492016-07-22 09:45:56 -07001538 @skip("Disabled for early v3 development")
James E. Blair4886f282012-11-15 09:27:33 -08001539 def test_merger_repack_large_change(self):
1540 "Test that the merger works with large changes after a repack"
1541 # https://bugs.launchpad.net/zuul/+bug/1078946
James E. Blairac2c3242014-01-24 13:38:51 -08001542 # This test assumes the repo is already cloned; make sure it is
Joshua Hesketh352264b2015-08-11 23:42:08 +10001543 url = self.fake_gerrit.getGitUrl(
James E. Blairac2c3242014-01-24 13:38:51 -08001544 self.sched.layout.projects['org/project1'])
James E. Blair4076e2b2014-01-28 12:42:20 -08001545 self.merge_server.merger.addProject('org/project1', url)
James E. Blair4886f282012-11-15 09:27:33 -08001546 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1547 A.addPatchset(large=True)
Monty Taylorbc758832013-06-17 17:22:42 -04001548 path = os.path.join(self.upstream_root, "org/project1")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001549 print(repack_repo(path))
Monty Taylorbc758832013-06-17 17:22:42 -04001550 path = os.path.join(self.git_root, "org/project1")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001551 print(repack_repo(path))
James E. Blair4886f282012-11-15 09:27:33 -08001552
1553 A.addApproval('CRVW', 2)
1554 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1555 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001556 self.assertEqual(self.getJobFromHistory('project1-merge').result,
1557 'SUCCESS')
1558 self.assertEqual(self.getJobFromHistory('project1-test1').result,
1559 'SUCCESS')
1560 self.assertEqual(self.getJobFromHistory('project1-test2').result,
1561 'SUCCESS')
1562 self.assertEqual(A.data['status'], 'MERGED')
1563 self.assertEqual(A.reported, 2)
James E. Blair4886f282012-11-15 09:27:33 -08001564
James E. Blairec056492016-07-22 09:45:56 -07001565 @skip("Disabled for early v3 development")
James E. Blair7ee88a22012-09-12 18:59:31 +02001566 def test_nonexistent_job(self):
1567 "Test launching a job that doesn't exist"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001568 # Set to the state immediately after a restart
1569 self.resetGearmanServer()
1570 self.launcher.negative_function_cache_ttl = 0
James E. Blair7ee88a22012-09-12 18:59:31 +02001571
1572 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1573 A.addApproval('CRVW', 2)
1574 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1575 # There may be a thread about to report a lost change
1576 while A.reported < 2:
1577 self.waitUntilSettled()
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001578 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001579 self.assertFalse(job_names)
1580 self.assertEqual(A.data['status'], 'NEW')
1581 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001582 self.assertEmptyQueues()
1583
1584 # Make sure things still work:
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001585 self.registerJobs()
James E. Blair7ee88a22012-09-12 18:59:31 +02001586 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1587 A.addApproval('CRVW', 2)
1588 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1589 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001590 self.assertEqual(self.getJobFromHistory('project-merge').result,
1591 'SUCCESS')
1592 self.assertEqual(self.getJobFromHistory('project-test1').result,
1593 'SUCCESS')
1594 self.assertEqual(self.getJobFromHistory('project-test2').result,
1595 'SUCCESS')
1596 self.assertEqual(A.data['status'], 'MERGED')
1597 self.assertEqual(A.reported, 2)
James E. Blairf62d4282012-12-31 17:01:50 -08001598
James E. Blairec056492016-07-22 09:45:56 -07001599 @skip("Disabled for early v3 development")
James E. Blairf62d4282012-12-31 17:01:50 -08001600 def test_single_nonexistent_post_job(self):
1601 "Test launching a single post job that doesn't exist"
James E. Blairf62d4282012-12-31 17:01:50 -08001602 e = {
1603 "type": "ref-updated",
1604 "submitter": {
1605 "name": "User Name",
1606 },
1607 "refUpdate": {
1608 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
1609 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
1610 "refName": "master",
1611 "project": "org/project",
1612 }
1613 }
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001614 # Set to the state immediately after a restart
1615 self.resetGearmanServer()
1616 self.launcher.negative_function_cache_ttl = 0
1617
James E. Blairf62d4282012-12-31 17:01:50 -08001618 self.fake_gerrit.addEvent(e)
1619 self.waitUntilSettled()
1620
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001621 self.assertEqual(len(self.history), 0)
James E. Blair2fa50962013-01-30 21:50:41 -08001622
James E. Blairec056492016-07-22 09:45:56 -07001623 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001624 def test_new_patchset_dequeues_old(self):
1625 "Test that a new patchset causes the old to be dequeued"
1626 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001627 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001628 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1629 M.setMerged()
1630
1631 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1632 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1633 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1634 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1635 A.addApproval('CRVW', 2)
1636 B.addApproval('CRVW', 2)
1637 C.addApproval('CRVW', 2)
1638 D.addApproval('CRVW', 2)
1639
1640 C.setDependsOn(B, 1)
1641 B.setDependsOn(A, 1)
1642 A.setDependsOn(M, 1)
1643
1644 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1645 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1646 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1647 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1648 self.waitUntilSettled()
1649
1650 B.addPatchset()
1651 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1652 self.waitUntilSettled()
1653
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001654 self.worker.hold_jobs_in_build = False
1655 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001656 self.waitUntilSettled()
1657
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001658 self.assertEqual(A.data['status'], 'MERGED')
1659 self.assertEqual(A.reported, 2)
1660 self.assertEqual(B.data['status'], 'NEW')
1661 self.assertEqual(B.reported, 2)
1662 self.assertEqual(C.data['status'], 'NEW')
1663 self.assertEqual(C.reported, 2)
1664 self.assertEqual(D.data['status'], 'MERGED')
1665 self.assertEqual(D.reported, 2)
1666 self.assertEqual(len(self.history), 9) # 3 each for A, B, D.
James E. Blair2fa50962013-01-30 21:50:41 -08001667
James E. Blairec056492016-07-22 09:45:56 -07001668 @skip("Disabled for early v3 development")
James E. Blairba437362015-02-07 11:41:52 -08001669 def test_new_patchset_check(self):
1670 "Test a new patchset in check"
Antoine Mussobd86a312014-01-08 14:51:33 +01001671
1672 self.worker.hold_jobs_in_build = True
1673
1674 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairba437362015-02-07 11:41:52 -08001675 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1676 check_pipeline = self.sched.layout.pipelines['check']
1677
1678 # Add two git-dependent changes
1679 B.setDependsOn(A, 1)
1680 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1681 self.waitUntilSettled()
Antoine Mussobd86a312014-01-08 14:51:33 +01001682 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1683 self.waitUntilSettled()
James E. Blairba437362015-02-07 11:41:52 -08001684
1685 # A live item, and a non-live/live pair
1686 items = check_pipeline.getAllItems()
1687 self.assertEqual(len(items), 3)
1688
1689 self.assertEqual(items[0].change.number, '1')
1690 self.assertEqual(items[0].change.patchset, '1')
1691 self.assertFalse(items[0].live)
1692
1693 self.assertEqual(items[1].change.number, '2')
1694 self.assertEqual(items[1].change.patchset, '1')
1695 self.assertTrue(items[1].live)
1696
1697 self.assertEqual(items[2].change.number, '1')
1698 self.assertEqual(items[2].change.patchset, '1')
1699 self.assertTrue(items[2].live)
1700
1701 # Add a new patchset to A
1702 A.addPatchset()
1703 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1704 self.waitUntilSettled()
1705
1706 # The live copy of A,1 should be gone, but the non-live and B
1707 # should continue, and we should have a new A,2
1708 items = check_pipeline.getAllItems()
1709 self.assertEqual(len(items), 3)
1710
1711 self.assertEqual(items[0].change.number, '1')
1712 self.assertEqual(items[0].change.patchset, '1')
1713 self.assertFalse(items[0].live)
1714
1715 self.assertEqual(items[1].change.number, '2')
1716 self.assertEqual(items[1].change.patchset, '1')
1717 self.assertTrue(items[1].live)
1718
1719 self.assertEqual(items[2].change.number, '1')
1720 self.assertEqual(items[2].change.patchset, '2')
1721 self.assertTrue(items[2].live)
1722
1723 # Add a new patchset to B
1724 B.addPatchset()
1725 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1726 self.waitUntilSettled()
1727
1728 # The live copy of B,1 should be gone, and it's non-live copy of A,1
1729 # but we should have a new B,2 (still based on A,1)
1730 items = check_pipeline.getAllItems()
1731 self.assertEqual(len(items), 3)
1732
1733 self.assertEqual(items[0].change.number, '1')
1734 self.assertEqual(items[0].change.patchset, '2')
1735 self.assertTrue(items[0].live)
1736
1737 self.assertEqual(items[1].change.number, '1')
1738 self.assertEqual(items[1].change.patchset, '1')
1739 self.assertFalse(items[1].live)
1740
1741 self.assertEqual(items[2].change.number, '2')
1742 self.assertEqual(items[2].change.patchset, '2')
1743 self.assertTrue(items[2].live)
1744
1745 self.builds[0].release()
1746 self.waitUntilSettled()
1747 self.builds[0].release()
1748 self.waitUntilSettled()
1749 self.worker.hold_jobs_in_build = False
1750 self.worker.release()
1751 self.waitUntilSettled()
1752
1753 self.assertEqual(A.reported, 1)
1754 self.assertEqual(B.reported, 1)
1755 self.assertEqual(self.history[0].result, 'ABORTED')
1756 self.assertEqual(self.history[0].changes, '1,1')
1757 self.assertEqual(self.history[1].result, 'ABORTED')
1758 self.assertEqual(self.history[1].changes, '1,1 2,1')
1759 self.assertEqual(self.history[2].result, 'SUCCESS')
1760 self.assertEqual(self.history[2].changes, '1,2')
1761 self.assertEqual(self.history[3].result, 'SUCCESS')
1762 self.assertEqual(self.history[3].changes, '1,1 2,2')
1763
James E. Blairec056492016-07-22 09:45:56 -07001764 @skip("Disabled for early v3 development")
James E. Blairba437362015-02-07 11:41:52 -08001765 def test_abandoned_gate(self):
1766 "Test that an abandoned change is dequeued from gate"
1767
1768 self.worker.hold_jobs_in_build = True
1769
1770 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1771 A.addApproval('CRVW', 2)
1772 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1773 self.waitUntilSettled()
Antoine Mussobd86a312014-01-08 14:51:33 +01001774 self.assertEqual(len(self.builds), 1, "One job being built (on hold)")
1775 self.assertEqual(self.builds[0].name, 'project-merge')
1776
1777 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1778 self.waitUntilSettled()
1779
Antoine Mussobd86a312014-01-08 14:51:33 +01001780 self.worker.release('.*-merge')
1781 self.waitUntilSettled()
1782
1783 self.assertEqual(len(self.builds), 0, "No job running")
Antoine Mussobd86a312014-01-08 14:51:33 +01001784 self.assertEqual(len(self.history), 1, "Only one build in history")
1785 self.assertEqual(self.history[0].result, 'ABORTED',
James E. Blairba437362015-02-07 11:41:52 -08001786 "Build should have been aborted")
1787 self.assertEqual(A.reported, 1,
1788 "Abandoned gate change should report only start")
1789
James E. Blairec056492016-07-22 09:45:56 -07001790 @skip("Disabled for early v3 development")
James E. Blairba437362015-02-07 11:41:52 -08001791 def test_abandoned_check(self):
1792 "Test that an abandoned change is dequeued from check"
1793
1794 self.worker.hold_jobs_in_build = True
1795
1796 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1797 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1798 check_pipeline = self.sched.layout.pipelines['check']
1799
1800 # Add two git-dependent changes
1801 B.setDependsOn(A, 1)
1802 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1803 self.waitUntilSettled()
1804 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1805 self.waitUntilSettled()
1806 # A live item, and a non-live/live pair
1807 items = check_pipeline.getAllItems()
1808 self.assertEqual(len(items), 3)
1809
1810 self.assertEqual(items[0].change.number, '1')
1811 self.assertFalse(items[0].live)
1812
1813 self.assertEqual(items[1].change.number, '2')
1814 self.assertTrue(items[1].live)
1815
1816 self.assertEqual(items[2].change.number, '1')
1817 self.assertTrue(items[2].live)
1818
1819 # Abandon A
1820 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1821 self.waitUntilSettled()
1822
1823 # The live copy of A should be gone, but the non-live and B
1824 # should continue
1825 items = check_pipeline.getAllItems()
1826 self.assertEqual(len(items), 2)
1827
1828 self.assertEqual(items[0].change.number, '1')
1829 self.assertFalse(items[0].live)
1830
1831 self.assertEqual(items[1].change.number, '2')
1832 self.assertTrue(items[1].live)
1833
1834 self.worker.hold_jobs_in_build = False
1835 self.worker.release()
1836 self.waitUntilSettled()
1837
1838 self.assertEqual(len(self.history), 4)
1839 self.assertEqual(self.history[0].result, 'ABORTED',
Antoine Mussobd86a312014-01-08 14:51:33 +01001840 'Build should have been aborted')
1841 self.assertEqual(A.reported, 0, "Abandoned change should not report")
James E. Blairba437362015-02-07 11:41:52 -08001842 self.assertEqual(B.reported, 1, "Change should report")
Antoine Mussobd86a312014-01-08 14:51:33 +01001843
James E. Blairec056492016-07-22 09:45:56 -07001844 @skip("Disabled for early v3 development")
Steve Varnau7b78b312015-04-03 14:49:46 -07001845 def test_abandoned_not_timer(self):
1846 "Test that an abandoned change does not cancel timer jobs"
1847
1848 self.worker.hold_jobs_in_build = True
1849
1850 # Start timer trigger - also org/project
James E. Blairf84026c2015-12-08 16:11:46 -08001851 self.updateConfigLayout(
1852 'tests/fixtures/layout-idle.yaml')
Steve Varnau7b78b312015-04-03 14:49:46 -07001853 self.sched.reconfigure(self.config)
1854 self.registerJobs()
1855 # The pipeline triggers every second, so we should have seen
1856 # several by now.
1857 time.sleep(5)
1858 self.waitUntilSettled()
1859 # Stop queuing timer triggered jobs so that the assertions
1860 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08001861 self.updateConfigLayout(
1862 'tests/fixtures/layout-no-timer.yaml')
Steve Varnau7b78b312015-04-03 14:49:46 -07001863 self.sched.reconfigure(self.config)
1864 self.registerJobs()
1865 self.assertEqual(len(self.builds), 2, "Two timer jobs")
1866
1867 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1868 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1869 self.waitUntilSettled()
1870 self.assertEqual(len(self.builds), 3, "One change plus two timer jobs")
1871
1872 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1873 self.waitUntilSettled()
1874
1875 self.assertEqual(len(self.builds), 2, "Two timer jobs remain")
1876
1877 self.worker.release()
1878 self.waitUntilSettled()
1879
James E. Blairec056492016-07-22 09:45:56 -07001880 @skip("Disabled for early v3 development")
Arx Cruzb1b010d2013-10-28 19:49:59 -02001881 def test_zuul_url_return(self):
1882 "Test if ZUUL_URL is returning when zuul_url is set in zuul.conf"
James E. Blair4076e2b2014-01-28 12:42:20 -08001883 self.assertTrue(self.sched.config.has_option('merger', 'zuul_url'))
Arx Cruzb1b010d2013-10-28 19:49:59 -02001884 self.worker.hold_jobs_in_build = True
1885
1886 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1887 A.addApproval('CRVW', 2)
1888 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1889 self.waitUntilSettled()
1890
1891 self.assertEqual(len(self.builds), 1)
1892 for build in self.builds:
1893 self.assertTrue('ZUUL_URL' in build.parameters)
1894
1895 self.worker.hold_jobs_in_build = False
1896 self.worker.release()
1897 self.waitUntilSettled()
1898
James E. Blairec056492016-07-22 09:45:56 -07001899 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001900 def test_new_patchset_dequeues_old_on_head(self):
1901 "Test that a new patchset causes the old to be dequeued (at head)"
1902 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001903 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001904 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1905 M.setMerged()
1906 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1907 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1908 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1909 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1910 A.addApproval('CRVW', 2)
1911 B.addApproval('CRVW', 2)
1912 C.addApproval('CRVW', 2)
1913 D.addApproval('CRVW', 2)
1914
1915 C.setDependsOn(B, 1)
1916 B.setDependsOn(A, 1)
1917 A.setDependsOn(M, 1)
1918
1919 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1920 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1921 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1922 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1923 self.waitUntilSettled()
1924
1925 A.addPatchset()
1926 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1927 self.waitUntilSettled()
1928
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001929 self.worker.hold_jobs_in_build = False
1930 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001931 self.waitUntilSettled()
1932
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001933 self.assertEqual(A.data['status'], 'NEW')
1934 self.assertEqual(A.reported, 2)
1935 self.assertEqual(B.data['status'], 'NEW')
1936 self.assertEqual(B.reported, 2)
1937 self.assertEqual(C.data['status'], 'NEW')
1938 self.assertEqual(C.reported, 2)
1939 self.assertEqual(D.data['status'], 'MERGED')
1940 self.assertEqual(D.reported, 2)
1941 self.assertEqual(len(self.history), 7)
James E. Blair2fa50962013-01-30 21:50:41 -08001942
James E. Blairec056492016-07-22 09:45:56 -07001943 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001944 def test_new_patchset_dequeues_old_without_dependents(self):
1945 "Test that a new patchset causes only the old to be dequeued"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001946 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001947 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1948 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1949 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1950 A.addApproval('CRVW', 2)
1951 B.addApproval('CRVW', 2)
1952 C.addApproval('CRVW', 2)
1953
1954 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1955 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1956 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1957 self.waitUntilSettled()
1958
1959 B.addPatchset()
1960 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1961 self.waitUntilSettled()
1962
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001963 self.worker.hold_jobs_in_build = False
1964 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001965 self.waitUntilSettled()
1966
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001967 self.assertEqual(A.data['status'], 'MERGED')
1968 self.assertEqual(A.reported, 2)
1969 self.assertEqual(B.data['status'], 'NEW')
1970 self.assertEqual(B.reported, 2)
1971 self.assertEqual(C.data['status'], 'MERGED')
1972 self.assertEqual(C.reported, 2)
1973 self.assertEqual(len(self.history), 9)
James E. Blair2fa50962013-01-30 21:50:41 -08001974
James E. Blairec056492016-07-22 09:45:56 -07001975 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001976 def test_new_patchset_dequeues_old_independent_queue(self):
1977 "Test that a new patchset causes the old to be dequeued (independent)"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001978 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001979 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1980 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1981 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1982 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1983 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1984 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
1985 self.waitUntilSettled()
1986
1987 B.addPatchset()
1988 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1989 self.waitUntilSettled()
1990
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001991 self.worker.hold_jobs_in_build = False
1992 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001993 self.waitUntilSettled()
1994
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001995 self.assertEqual(A.data['status'], 'NEW')
1996 self.assertEqual(A.reported, 1)
1997 self.assertEqual(B.data['status'], 'NEW')
1998 self.assertEqual(B.reported, 1)
1999 self.assertEqual(C.data['status'], 'NEW')
2000 self.assertEqual(C.reported, 1)
2001 self.assertEqual(len(self.history), 10)
2002 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 1)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002003
James E. Blairec056492016-07-22 09:45:56 -07002004 @skip("Disabled for early v3 development")
James E. Blair18c64442014-03-18 10:14:45 -07002005 def test_noop_job(self):
2006 "Test that the internal noop job works"
2007 A = self.fake_gerrit.addFakeChange('org/noop-project', 'master', 'A')
2008 A.addApproval('CRVW', 2)
2009 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2010 self.waitUntilSettled()
2011
2012 self.assertEqual(len(self.gearman_server.getQueue()), 0)
2013 self.assertTrue(self.sched._areAllBuildsComplete())
2014 self.assertEqual(len(self.history), 0)
2015 self.assertEqual(A.data['status'], 'MERGED')
2016 self.assertEqual(A.reported, 2)
2017
James E. Blairec056492016-07-22 09:45:56 -07002018 @skip("Disabled for early v3 development")
Evgeny Antyshevd6e546c2015-06-11 15:13:57 +00002019 def test_no_job_project(self):
2020 "Test that reports with no jobs don't get sent"
2021 A = self.fake_gerrit.addFakeChange('org/no-jobs-project',
2022 'master', 'A')
2023 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2024 self.waitUntilSettled()
2025
2026 # Change wasn't reported to
2027 self.assertEqual(A.reported, False)
2028
2029 # Check queue is empty afterwards
2030 check_pipeline = self.sched.layout.pipelines['check']
2031 items = check_pipeline.getAllItems()
2032 self.assertEqual(len(items), 0)
2033
2034 self.assertEqual(len(self.history), 0)
2035
James E. Blairec056492016-07-22 09:45:56 -07002036 @skip("Disabled for early v3 development")
James E. Blair7d0dedc2013-02-21 17:26:09 -08002037 def test_zuul_refs(self):
2038 "Test that zuul refs exist and have the right changes"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002039 self.worker.hold_jobs_in_build = True
James E. Blair7d0dedc2013-02-21 17:26:09 -08002040 M1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'M1')
2041 M1.setMerged()
2042 M2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'M2')
2043 M2.setMerged()
2044
2045 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2046 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2047 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
2048 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
2049 A.addApproval('CRVW', 2)
2050 B.addApproval('CRVW', 2)
2051 C.addApproval('CRVW', 2)
2052 D.addApproval('CRVW', 2)
2053 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2054 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2055 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2056 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
2057
2058 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002059 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002060 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002061 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002062 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002063 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002064 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002065 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002066 self.waitUntilSettled()
2067
James E. Blair7d0dedc2013-02-21 17:26:09 -08002068 a_zref = b_zref = c_zref = d_zref = None
Monty Taylor6bef8ef2013-06-02 08:17:12 -04002069 for x in self.builds:
James E. Blair7d0dedc2013-02-21 17:26:09 -08002070 if x.parameters['ZUUL_CHANGE'] == '3':
2071 a_zref = x.parameters['ZUUL_REF']
2072 if x.parameters['ZUUL_CHANGE'] == '4':
2073 b_zref = x.parameters['ZUUL_REF']
2074 if x.parameters['ZUUL_CHANGE'] == '5':
2075 c_zref = x.parameters['ZUUL_REF']
2076 if x.parameters['ZUUL_CHANGE'] == '6':
2077 d_zref = x.parameters['ZUUL_REF']
2078
2079 # There are... four... refs.
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002080 self.assertIsNotNone(a_zref)
2081 self.assertIsNotNone(b_zref)
2082 self.assertIsNotNone(c_zref)
2083 self.assertIsNotNone(d_zref)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002084
2085 # And they should all be different
2086 refs = set([a_zref, b_zref, c_zref, d_zref])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002087 self.assertEqual(len(refs), 4)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002088
2089 # a ref should have a, not b, and should not be in project2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002090 self.assertTrue(self.ref_has_change(a_zref, A))
2091 self.assertFalse(self.ref_has_change(a_zref, B))
2092 self.assertFalse(self.ref_has_change(a_zref, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002093
2094 # b ref should have a and b, and should not be in project2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002095 self.assertTrue(self.ref_has_change(b_zref, A))
2096 self.assertTrue(self.ref_has_change(b_zref, B))
2097 self.assertFalse(self.ref_has_change(b_zref, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002098
2099 # c ref should have a and b in 1, c in 2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002100 self.assertTrue(self.ref_has_change(c_zref, A))
2101 self.assertTrue(self.ref_has_change(c_zref, B))
2102 self.assertTrue(self.ref_has_change(c_zref, C))
2103 self.assertFalse(self.ref_has_change(c_zref, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002104
2105 # d ref should have a and b in 1, c and d in 2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002106 self.assertTrue(self.ref_has_change(d_zref, A))
2107 self.assertTrue(self.ref_has_change(d_zref, B))
2108 self.assertTrue(self.ref_has_change(d_zref, C))
2109 self.assertTrue(self.ref_has_change(d_zref, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002110
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002111 self.worker.hold_jobs_in_build = False
2112 self.worker.release()
James E. Blair7d0dedc2013-02-21 17:26:09 -08002113 self.waitUntilSettled()
2114
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002115 self.assertEqual(A.data['status'], 'MERGED')
2116 self.assertEqual(A.reported, 2)
2117 self.assertEqual(B.data['status'], 'MERGED')
2118 self.assertEqual(B.reported, 2)
2119 self.assertEqual(C.data['status'], 'MERGED')
2120 self.assertEqual(C.reported, 2)
2121 self.assertEqual(D.data['status'], 'MERGED')
2122 self.assertEqual(D.reported, 2)
James E. Blair70c71582013-03-06 08:50:50 -08002123
James E. Blairec056492016-07-22 09:45:56 -07002124 @skip("Disabled for early v3 development")
James E. Blair4a28a882013-08-23 15:17:33 -07002125 def test_rerun_on_error(self):
2126 "Test that if a worker fails to run a job, it is run again"
2127 self.worker.hold_jobs_in_build = True
2128 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2129 A.addApproval('CRVW', 2)
2130 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2131 self.waitUntilSettled()
2132
2133 self.builds[0].run_error = True
2134 self.worker.hold_jobs_in_build = False
2135 self.worker.release()
2136 self.waitUntilSettled()
2137 self.assertEqual(self.countJobResults(self.history, 'RUN_ERROR'), 1)
2138 self.assertEqual(self.countJobResults(self.history, 'SUCCESS'), 3)
2139
James E. Blairec056492016-07-22 09:45:56 -07002140 @skip("Disabled for early v3 development")
James E. Blair412e5582013-04-22 15:50:12 -07002141 def test_statsd(self):
2142 "Test each of the statsd methods used in the scheduler"
2143 import extras
2144 statsd = extras.try_import('statsd.statsd')
2145 statsd.incr('test-incr')
2146 statsd.timing('test-timing', 3)
Alex Gaynor813d39b2014-05-17 16:17:16 -07002147 statsd.gauge('test-gauge', 12)
James E. Blair412e5582013-04-22 15:50:12 -07002148 self.assertReportedStat('test-incr', '1|c')
2149 self.assertReportedStat('test-timing', '3|ms')
Alex Gaynor813d39b2014-05-17 16:17:16 -07002150 self.assertReportedStat('test-gauge', '12|g')
James E. Blair412e5582013-04-22 15:50:12 -07002151
James E. Blairec056492016-07-22 09:45:56 -07002152 @skip("Disabled for early v3 development")
James E. Blairdad52252014-02-07 16:59:17 -08002153 def test_stuck_job_cleanup(self):
2154 "Test that pending jobs are cleaned up if removed from layout"
James E. Blair18c64442014-03-18 10:14:45 -07002155 # This job won't be registered at startup because it is not in
2156 # the standard layout, but we need it to already be registerd
2157 # for when we reconfigure, as that is when Zuul will attempt
2158 # to run the new job.
2159 self.worker.registerFunction('build:gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002160 self.gearman_server.hold_jobs_in_queue = True
2161 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2162 A.addApproval('CRVW', 2)
2163 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2164 self.waitUntilSettled()
2165 self.assertEqual(len(self.gearman_server.getQueue()), 1)
2166
James E. Blairf84026c2015-12-08 16:11:46 -08002167 self.updateConfigLayout(
2168 'tests/fixtures/layout-no-jobs.yaml')
James E. Blairdad52252014-02-07 16:59:17 -08002169 self.sched.reconfigure(self.config)
2170 self.waitUntilSettled()
2171
James E. Blair18c64442014-03-18 10:14:45 -07002172 self.gearman_server.release('gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002173 self.waitUntilSettled()
2174 self.assertEqual(len(self.gearman_server.getQueue()), 0)
2175 self.assertTrue(self.sched._areAllBuildsComplete())
2176
2177 self.assertEqual(len(self.history), 1)
James E. Blair18c64442014-03-18 10:14:45 -07002178 self.assertEqual(self.history[0].name, 'gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002179 self.assertEqual(self.history[0].result, 'SUCCESS')
2180
James E. Blairec056492016-07-22 09:45:56 -07002181 @skip("Disabled for early v3 development")
James E. Blair879dafb2015-07-17 14:04:49 -07002182 def test_file_head(self):
2183 # This is a regression test for an observed bug. A change
2184 # with a file named "HEAD" in the root directory of the repo
2185 # was processed by a merger. It then was unable to reset the
2186 # repo because of:
2187 # GitCommandError: 'git reset --hard HEAD' returned
2188 # with exit code 128
2189 # stderr: 'fatal: ambiguous argument 'HEAD': both revision
2190 # and filename
2191 # Use '--' to separate filenames from revisions'
2192
2193 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2194 A.addPatchset(['HEAD'])
2195 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2196
2197 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
2198 self.waitUntilSettled()
2199
2200 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2201 self.waitUntilSettled()
2202
2203 self.assertIn('Build succeeded', A.messages[0])
2204 self.assertIn('Build succeeded', B.messages[0])
2205
James E. Blairec056492016-07-22 09:45:56 -07002206 @skip("Disabled for early v3 development")
James E. Blair70c71582013-03-06 08:50:50 -08002207 def test_file_jobs(self):
2208 "Test that file jobs run only when appropriate"
2209 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2210 A.addPatchset(['pip-requires'])
2211 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2212 A.addApproval('CRVW', 2)
2213 B.addApproval('CRVW', 2)
2214 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2215 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2216 self.waitUntilSettled()
2217
Monty Taylor6bef8ef2013-06-02 08:17:12 -04002218 testfile_jobs = [x for x in self.history
James E. Blair70c71582013-03-06 08:50:50 -08002219 if x.name == 'project-testfile']
2220
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002221 self.assertEqual(len(testfile_jobs), 1)
2222 self.assertEqual(testfile_jobs[0].changes, '1,2')
2223 self.assertEqual(A.data['status'], 'MERGED')
2224 self.assertEqual(A.reported, 2)
2225 self.assertEqual(B.data['status'], 'MERGED')
2226 self.assertEqual(B.reported, 2)
James E. Blair3c5e5b52013-04-26 11:17:03 -07002227
James E. Blairec056492016-07-22 09:45:56 -07002228 @skip("Disabled for early v3 development")
Maru Newby3fe5f852015-01-13 04:22:14 +00002229 def _test_skip_if_jobs(self, branch, should_skip):
2230 "Test that jobs with a skip-if filter run only when appropriate"
James E. Blairf84026c2015-12-08 16:11:46 -08002231 self.updateConfigLayout(
2232 'tests/fixtures/layout-skip-if.yaml')
Maru Newby3fe5f852015-01-13 04:22:14 +00002233 self.sched.reconfigure(self.config)
2234 self.registerJobs()
2235
2236 change = self.fake_gerrit.addFakeChange('org/project',
2237 branch,
2238 'test skip-if')
2239 self.fake_gerrit.addEvent(change.getPatchsetCreatedEvent(1))
2240 self.waitUntilSettled()
2241
2242 tested_change_ids = [x.changes[0] for x in self.history
2243 if x.name == 'project-test-skip-if']
2244
2245 if should_skip:
2246 self.assertEqual([], tested_change_ids)
2247 else:
2248 self.assertIn(change.data['number'], tested_change_ids)
2249
James E. Blairec056492016-07-22 09:45:56 -07002250 @skip("Disabled for early v3 development")
Maru Newby3fe5f852015-01-13 04:22:14 +00002251 def test_skip_if_match_skips_job(self):
2252 self._test_skip_if_jobs(branch='master', should_skip=True)
2253
James E. Blairec056492016-07-22 09:45:56 -07002254 @skip("Disabled for early v3 development")
Maru Newby3fe5f852015-01-13 04:22:14 +00002255 def test_skip_if_no_match_runs_job(self):
2256 self._test_skip_if_jobs(branch='mp', should_skip=False)
2257
James E. Blairec056492016-07-22 09:45:56 -07002258 @skip("Disabled for early v3 development")
James E. Blair3c5e5b52013-04-26 11:17:03 -07002259 def test_test_config(self):
2260 "Test that we can test the config"
James E. Blairf84026c2015-12-08 16:11:46 -08002261 self.sched.testConfig(self.config.get('zuul', 'tenant_config'),
Joshua Hesketh352264b2015-08-11 23:42:08 +10002262 self.connections)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002263
James E. Blairec056492016-07-22 09:45:56 -07002264 @skip("Disabled for early v3 development")
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002265 def test_build_description(self):
2266 "Test that build descriptions update"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002267 self.worker.registerFunction('set_description:' +
2268 self.worker.worker_id)
2269
2270 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2271 A.addApproval('CRVW', 2)
2272 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2273 self.waitUntilSettled()
Monty Taylor6bef8ef2013-06-02 08:17:12 -04002274 desc = self.history[0].description
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002275 self.log.debug("Description: %s" % desc)
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002276 self.assertTrue(re.search("Branch.*master", desc))
2277 self.assertTrue(re.search("Pipeline.*gate", desc))
2278 self.assertTrue(re.search("project-merge.*SUCCESS", desc))
2279 self.assertTrue(re.search("project-test1.*SUCCESS", desc))
2280 self.assertTrue(re.search("project-test2.*SUCCESS", desc))
2281 self.assertTrue(re.search("Reported result.*SUCCESS", desc))
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002282
James E. Blairec056492016-07-22 09:45:56 -07002283 @skip("Disabled for early v3 development")
James E. Blairc8a1e052014-02-25 09:29:26 -08002284 def test_queue_names(self):
2285 "Test shared change queue names"
2286 project1 = self.sched.layout.projects['org/project1']
2287 project2 = self.sched.layout.projects['org/project2']
2288 q1 = self.sched.layout.pipelines['gate'].getQueue(project1)
2289 q2 = self.sched.layout.pipelines['gate'].getQueue(project2)
2290 self.assertEqual(q1.name, 'integration')
2291 self.assertEqual(q2.name, 'integration')
2292
James E. Blairf84026c2015-12-08 16:11:46 -08002293 self.updateConfigLayout(
2294 'tests/fixtures/layout-bad-queue.yaml')
James E. Blairc8a1e052014-02-25 09:29:26 -08002295 with testtools.ExpectedException(
2296 Exception, "More than one name assigned to change queue"):
2297 self.sched.reconfigure(self.config)
2298
James E. Blairec056492016-07-22 09:45:56 -07002299 @skip("Disabled for early v3 development")
James E. Blair64ed6f22013-07-10 14:07:23 -07002300 def test_queue_precedence(self):
2301 "Test that queue precedence works"
2302
2303 self.gearman_server.hold_jobs_in_queue = True
James E. Blair8de58bd2013-07-18 16:23:33 -07002304 self.worker.hold_jobs_in_build = True
James E. Blair64ed6f22013-07-10 14:07:23 -07002305 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2306 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2307 A.addApproval('CRVW', 2)
2308 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2309
2310 self.waitUntilSettled()
2311 self.gearman_server.hold_jobs_in_queue = False
2312 self.gearman_server.release()
2313 self.waitUntilSettled()
2314
James E. Blair8de58bd2013-07-18 16:23:33 -07002315 # Run one build at a time to ensure non-race order:
James E. Blairb8c16472015-05-05 14:55:26 -07002316 self.orderedRelease()
James E. Blair8de58bd2013-07-18 16:23:33 -07002317 self.worker.hold_jobs_in_build = False
2318 self.waitUntilSettled()
2319
James E. Blair64ed6f22013-07-10 14:07:23 -07002320 self.log.debug(self.history)
2321 self.assertEqual(self.history[0].pipeline, 'gate')
2322 self.assertEqual(self.history[1].pipeline, 'check')
2323 self.assertEqual(self.history[2].pipeline, 'gate')
2324 self.assertEqual(self.history[3].pipeline, 'gate')
2325 self.assertEqual(self.history[4].pipeline, 'check')
2326 self.assertEqual(self.history[5].pipeline, 'check')
2327
James E. Blairec056492016-07-22 09:45:56 -07002328 @skip("Disabled for early v3 development")
Clark Boylana5edbe42014-06-03 16:39:10 -07002329 def test_json_status(self):
James E. Blair1843a552013-07-03 14:19:52 -07002330 "Test that we can retrieve JSON status info"
2331 self.worker.hold_jobs_in_build = True
2332 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2333 A.addApproval('CRVW', 2)
2334 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2335 self.waitUntilSettled()
2336
James E. Blairb7273ef2016-04-19 08:58:51 -07002337 self.worker.release('project-merge')
2338 self.waitUntilSettled()
2339
James E. Blair1843a552013-07-03 14:19:52 -07002340 port = self.webapp.server.socket.getsockname()[1]
2341
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002342 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2343 f = urllib.request.urlopen(req)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002344 headers = f.info()
2345 self.assertIn('Content-Length', headers)
2346 self.assertIn('Content-Type', headers)
Sachi Kingdc963fc2016-03-23 16:00:33 +11002347 self.assertIsNotNone(re.match('^application/json(; charset=UTF-8)?$',
2348 headers['Content-Type']))
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002349 self.assertIn('Access-Control-Allow-Origin', headers)
2350 self.assertIn('Cache-Control', headers)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002351 self.assertIn('Last-Modified', headers)
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002352 self.assertIn('Expires', headers)
James E. Blair1843a552013-07-03 14:19:52 -07002353 data = f.read()
2354
2355 self.worker.hold_jobs_in_build = False
2356 self.worker.release()
2357 self.waitUntilSettled()
2358
2359 data = json.loads(data)
James E. Blairb7273ef2016-04-19 08:58:51 -07002360 status_jobs = []
James E. Blair1843a552013-07-03 14:19:52 -07002361 for p in data['pipelines']:
2362 for q in p['change_queues']:
James E. Blairbfb8e042014-12-30 17:01:44 -08002363 if p['name'] in ['gate', 'conflict']:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002364 self.assertEqual(q['window'], 20)
2365 else:
2366 self.assertEqual(q['window'], 0)
James E. Blair1843a552013-07-03 14:19:52 -07002367 for head in q['heads']:
2368 for change in head:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002369 self.assertTrue(change['active'])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002370 self.assertEqual(change['id'], '1,1')
James E. Blair1843a552013-07-03 14:19:52 -07002371 for job in change['jobs']:
James E. Blairb7273ef2016-04-19 08:58:51 -07002372 status_jobs.append(job)
2373 self.assertEqual('project-merge', status_jobs[0]['name'])
2374 self.assertEqual('https://server/job/project-merge/0/',
2375 status_jobs[0]['url'])
2376 self.assertEqual('http://logs.example.com/1/1/gate/project-merge/0',
2377 status_jobs[0]['report_url'])
2378
2379 self.assertEqual('project-test1', status_jobs[1]['name'])
2380 self.assertEqual('https://server/job/project-test1/1/',
2381 status_jobs[1]['url'])
2382 self.assertEqual('http://logs.example.com/1/1/gate/project-test1/1',
2383 status_jobs[1]['report_url'])
2384
2385 self.assertEqual('project-test2', status_jobs[2]['name'])
2386 self.assertEqual('https://server/job/project-test2/2/',
2387 status_jobs[2]['url'])
2388 self.assertEqual('http://logs.example.com/1/1/gate/project-test2/2',
2389 status_jobs[2]['report_url'])
James E. Blair1843a552013-07-03 14:19:52 -07002390
James E. Blairec056492016-07-22 09:45:56 -07002391 @skip("Disabled for early v3 development")
James E. Blairc3d428e2013-12-03 15:06:48 -08002392 def test_merging_queues(self):
2393 "Test that transitively-connected change queues are merged"
James E. Blairf84026c2015-12-08 16:11:46 -08002394 self.updateConfigLayout(
2395 'tests/fixtures/layout-merge-queues.yaml')
James E. Blairc3d428e2013-12-03 15:06:48 -08002396 self.sched.reconfigure(self.config)
2397 self.assertEqual(len(self.sched.layout.pipelines['gate'].queues), 1)
2398
James E. Blairec056492016-07-22 09:45:56 -07002399 @skip("Disabled for early v3 development")
James E. Blairaf17a972016-02-03 15:07:18 -08002400 def test_mutex(self):
2401 "Test job mutexes"
2402 self.config.set('zuul', 'layout_config',
2403 'tests/fixtures/layout-mutex.yaml')
2404 self.sched.reconfigure(self.config)
2405
2406 self.worker.hold_jobs_in_build = True
2407 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2408 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2409 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2410
2411 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2412 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2413 self.waitUntilSettled()
2414 self.assertEqual(len(self.builds), 3)
2415 self.assertEqual(self.builds[0].name, 'project-test1')
2416 self.assertEqual(self.builds[1].name, 'mutex-one')
2417 self.assertEqual(self.builds[2].name, 'project-test1')
2418
2419 self.worker.release('mutex-one')
2420 self.waitUntilSettled()
2421
2422 self.assertEqual(len(self.builds), 3)
2423 self.assertEqual(self.builds[0].name, 'project-test1')
2424 self.assertEqual(self.builds[1].name, 'project-test1')
2425 self.assertEqual(self.builds[2].name, 'mutex-two')
2426 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2427
2428 self.worker.release('mutex-two')
2429 self.waitUntilSettled()
2430
2431 self.assertEqual(len(self.builds), 3)
2432 self.assertEqual(self.builds[0].name, 'project-test1')
2433 self.assertEqual(self.builds[1].name, 'project-test1')
2434 self.assertEqual(self.builds[2].name, 'mutex-one')
2435 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2436
2437 self.worker.release('mutex-one')
2438 self.waitUntilSettled()
2439
2440 self.assertEqual(len(self.builds), 3)
2441 self.assertEqual(self.builds[0].name, 'project-test1')
2442 self.assertEqual(self.builds[1].name, 'project-test1')
2443 self.assertEqual(self.builds[2].name, 'mutex-two')
2444 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2445
2446 self.worker.release('mutex-two')
2447 self.waitUntilSettled()
2448
2449 self.assertEqual(len(self.builds), 2)
2450 self.assertEqual(self.builds[0].name, 'project-test1')
2451 self.assertEqual(self.builds[1].name, 'project-test1')
2452 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2453
2454 self.worker.hold_jobs_in_build = False
2455 self.worker.release()
2456
2457 self.waitUntilSettled()
2458 self.assertEqual(len(self.builds), 0)
2459
2460 self.assertEqual(A.reported, 1)
2461 self.assertEqual(B.reported, 1)
2462 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2463
James E. Blairec056492016-07-22 09:45:56 -07002464 @skip("Disabled for early v3 development")
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002465 def test_node_label(self):
2466 "Test that a job runs on a specific node label"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002467 self.worker.registerFunction('build:node-project-test1:debian')
2468
2469 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
2470 A.addApproval('CRVW', 2)
2471 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2472 self.waitUntilSettled()
James E. Blair4ca985f2013-05-30 12:27:43 -07002473
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002474 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2475 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2476 'debian')
2477 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
James E. Blaircdccd972013-07-01 12:10:22 -07002478
James E. Blairec056492016-07-22 09:45:56 -07002479 @skip("Disabled for early v3 development")
James E. Blaircdccd972013-07-01 12:10:22 -07002480 def test_live_reconfiguration(self):
2481 "Test that live reconfiguration works"
2482 self.worker.hold_jobs_in_build = True
2483 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2484 A.addApproval('CRVW', 2)
2485 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2486 self.waitUntilSettled()
2487
2488 self.sched.reconfigure(self.config)
2489
2490 self.worker.hold_jobs_in_build = False
2491 self.worker.release()
2492 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002493 self.assertEqual(self.getJobFromHistory('project-merge').result,
2494 'SUCCESS')
2495 self.assertEqual(self.getJobFromHistory('project-test1').result,
2496 'SUCCESS')
2497 self.assertEqual(self.getJobFromHistory('project-test2').result,
2498 'SUCCESS')
2499 self.assertEqual(A.data['status'], 'MERGED')
2500 self.assertEqual(A.reported, 2)
James E. Blair287c06d2013-07-24 10:39:30 -07002501
James E. Blairec056492016-07-22 09:45:56 -07002502 @skip("Disabled for early v3 development")
James E. Blair6bc782d2015-07-17 16:20:21 -07002503 def test_live_reconfiguration_merge_conflict(self):
2504 # A real-world bug: a change in a gate queue has a merge
2505 # conflict and a job is added to its project while it's
2506 # sitting in the queue. The job gets added to the change and
2507 # enqueued and the change gets stuck.
2508 self.worker.registerFunction('build:project-test3')
2509 self.worker.hold_jobs_in_build = True
2510
2511 # This change is fine. It's here to stop the queue long
2512 # enough for the next change to be subject to the
2513 # reconfiguration, as well as to provide a conflict for the
2514 # next change. This change will succeed and merge.
2515 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2516 A.addPatchset(['conflict'])
2517 A.addApproval('CRVW', 2)
James E. Blair6bc782d2015-07-17 16:20:21 -07002518
2519 # This change will be in merge conflict. During the
2520 # reconfiguration, we will add a job. We want to make sure
2521 # that doesn't cause it to get stuck.
2522 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2523 B.addPatchset(['conflict'])
2524 B.addApproval('CRVW', 2)
James E. Blair4eb21fa2015-07-27 14:56:47 -07002525
2526 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
James E. Blair6bc782d2015-07-17 16:20:21 -07002527 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2528
2529 self.waitUntilSettled()
2530
2531 # No jobs have run yet
2532 self.assertEqual(A.data['status'], 'NEW')
2533 self.assertEqual(A.reported, 1)
2534 self.assertEqual(B.data['status'], 'NEW')
2535 self.assertEqual(B.reported, 1)
2536 self.assertEqual(len(self.history), 0)
2537
2538 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002539 self.updateConfigLayout(
2540 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002541 self.sched.reconfigure(self.config)
2542 self.waitUntilSettled()
2543
2544 self.worker.hold_jobs_in_build = False
2545 self.worker.release()
2546 self.waitUntilSettled()
2547
2548 self.assertEqual(A.data['status'], 'MERGED')
2549 self.assertEqual(A.reported, 2)
2550 self.assertEqual(B.data['status'], 'NEW')
2551 self.assertEqual(B.reported, 2)
2552 self.assertEqual(self.getJobFromHistory('project-merge').result,
2553 'SUCCESS')
2554 self.assertEqual(self.getJobFromHistory('project-test1').result,
2555 'SUCCESS')
2556 self.assertEqual(self.getJobFromHistory('project-test2').result,
2557 'SUCCESS')
2558 self.assertEqual(self.getJobFromHistory('project-test3').result,
2559 'SUCCESS')
2560 self.assertEqual(len(self.history), 4)
2561
James E. Blairec056492016-07-22 09:45:56 -07002562 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002563 def test_live_reconfiguration_failed_root(self):
James E. Blair6bc782d2015-07-17 16:20:21 -07002564 # An extrapolation of test_live_reconfiguration_merge_conflict
2565 # that tests a job added to a job tree with a failed root does
2566 # not run.
2567 self.worker.registerFunction('build:project-test3')
2568 self.worker.hold_jobs_in_build = True
2569
2570 # This change is fine. It's here to stop the queue long
2571 # enough for the next change to be subject to the
2572 # reconfiguration. This change will succeed and merge.
2573 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2574 A.addPatchset(['conflict'])
2575 A.addApproval('CRVW', 2)
2576 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2577 self.waitUntilSettled()
2578 self.worker.release('.*-merge')
2579 self.waitUntilSettled()
2580
2581 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2582 self.worker.addFailTest('project-merge', B)
2583 B.addApproval('CRVW', 2)
2584 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2585 self.waitUntilSettled()
2586
2587 self.worker.release('.*-merge')
2588 self.waitUntilSettled()
2589
2590 # Both -merge jobs have run, but no others.
2591 self.assertEqual(A.data['status'], 'NEW')
2592 self.assertEqual(A.reported, 1)
2593 self.assertEqual(B.data['status'], 'NEW')
2594 self.assertEqual(B.reported, 1)
2595 self.assertEqual(self.history[0].result, 'SUCCESS')
2596 self.assertEqual(self.history[0].name, 'project-merge')
2597 self.assertEqual(self.history[1].result, 'FAILURE')
2598 self.assertEqual(self.history[1].name, 'project-merge')
2599 self.assertEqual(len(self.history), 2)
2600
2601 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002602 self.updateConfigLayout(
2603 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002604 self.sched.reconfigure(self.config)
2605 self.waitUntilSettled()
2606
2607 self.worker.hold_jobs_in_build = False
2608 self.worker.release()
2609 self.waitUntilSettled()
2610
2611 self.assertEqual(A.data['status'], 'MERGED')
2612 self.assertEqual(A.reported, 2)
2613 self.assertEqual(B.data['status'], 'NEW')
2614 self.assertEqual(B.reported, 2)
2615 self.assertEqual(self.history[0].result, 'SUCCESS')
2616 self.assertEqual(self.history[0].name, 'project-merge')
2617 self.assertEqual(self.history[1].result, 'FAILURE')
2618 self.assertEqual(self.history[1].name, 'project-merge')
2619 self.assertEqual(self.history[2].result, 'SUCCESS')
2620 self.assertEqual(self.history[3].result, 'SUCCESS')
2621 self.assertEqual(self.history[4].result, 'SUCCESS')
2622 self.assertEqual(len(self.history), 5)
2623
James E. Blairec056492016-07-22 09:45:56 -07002624 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002625 def test_live_reconfiguration_failed_job(self):
2626 # Test that a change with a removed failing job does not
2627 # disrupt reconfiguration. If a change has a failed job and
2628 # that job is removed during a reconfiguration, we observed a
2629 # bug where the code to re-set build statuses would run on
2630 # that build and raise an exception because the job no longer
2631 # existed.
2632 self.worker.hold_jobs_in_build = True
2633
2634 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2635
2636 # This change will fail and later be removed by the reconfiguration.
2637 self.worker.addFailTest('project-test1', A)
2638
2639 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2640 self.waitUntilSettled()
2641 self.worker.release('.*-merge')
2642 self.waitUntilSettled()
2643 self.worker.release('project-test1')
2644 self.waitUntilSettled()
2645
2646 self.assertEqual(A.data['status'], 'NEW')
2647 self.assertEqual(A.reported, 0)
2648
2649 self.assertEqual(self.getJobFromHistory('project-merge').result,
2650 'SUCCESS')
2651 self.assertEqual(self.getJobFromHistory('project-test1').result,
2652 'FAILURE')
2653 self.assertEqual(len(self.history), 2)
2654
2655 # Remove the test1 job.
James E. Blairf84026c2015-12-08 16:11:46 -08002656 self.updateConfigLayout(
2657 'tests/fixtures/layout-live-reconfiguration-failed-job.yaml')
James E. Blair400e8fd2015-07-30 17:44:45 -07002658 self.sched.reconfigure(self.config)
2659 self.waitUntilSettled()
2660
2661 self.worker.hold_jobs_in_build = False
2662 self.worker.release()
2663 self.waitUntilSettled()
2664
2665 self.assertEqual(self.getJobFromHistory('project-test2').result,
2666 'SUCCESS')
2667 self.assertEqual(self.getJobFromHistory('project-testfile').result,
2668 'SUCCESS')
2669 self.assertEqual(len(self.history), 4)
2670
2671 self.assertEqual(A.data['status'], 'NEW')
2672 self.assertEqual(A.reported, 1)
2673 self.assertIn('Build succeeded', A.messages[0])
2674 # Ensure the removed job was not included in the report.
2675 self.assertNotIn('project-test1', A.messages[0])
2676
James E. Blairec056492016-07-22 09:45:56 -07002677 @skip("Disabled for early v3 development")
James E. Blairfe707d12015-08-05 15:18:15 -07002678 def test_live_reconfiguration_shared_queue(self):
2679 # Test that a change with a failing job which was removed from
2680 # this project but otherwise still exists in the system does
2681 # not disrupt reconfiguration.
2682
2683 self.worker.hold_jobs_in_build = True
2684
2685 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2686
2687 self.worker.addFailTest('project1-project2-integration', A)
2688
2689 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2690 self.waitUntilSettled()
2691 self.worker.release('.*-merge')
2692 self.waitUntilSettled()
2693 self.worker.release('project1-project2-integration')
2694 self.waitUntilSettled()
2695
2696 self.assertEqual(A.data['status'], 'NEW')
2697 self.assertEqual(A.reported, 0)
2698
2699 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2700 'SUCCESS')
2701 self.assertEqual(self.getJobFromHistory(
2702 'project1-project2-integration').result, 'FAILURE')
2703 self.assertEqual(len(self.history), 2)
2704
2705 # Remove the integration job.
James E. Blairf84026c2015-12-08 16:11:46 -08002706 self.updateConfigLayout(
2707 'tests/fixtures/layout-live-reconfiguration-shared-queue.yaml')
James E. Blairfe707d12015-08-05 15:18:15 -07002708 self.sched.reconfigure(self.config)
2709 self.waitUntilSettled()
2710
2711 self.worker.hold_jobs_in_build = False
2712 self.worker.release()
2713 self.waitUntilSettled()
2714
2715 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2716 'SUCCESS')
2717 self.assertEqual(self.getJobFromHistory('project1-test1').result,
2718 'SUCCESS')
2719 self.assertEqual(self.getJobFromHistory('project1-test2').result,
2720 'SUCCESS')
2721 self.assertEqual(self.getJobFromHistory(
2722 'project1-project2-integration').result, 'FAILURE')
2723 self.assertEqual(len(self.history), 4)
2724
2725 self.assertEqual(A.data['status'], 'NEW')
2726 self.assertEqual(A.reported, 1)
2727 self.assertIn('Build succeeded', A.messages[0])
2728 # Ensure the removed job was not included in the report.
2729 self.assertNotIn('project1-project2-integration', A.messages[0])
2730
James E. Blairec056492016-07-22 09:45:56 -07002731 @skip("Disabled for early v3 development")
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002732 def test_double_live_reconfiguration_shared_queue(self):
2733 # This was a real-world regression. A change is added to
2734 # gate; a reconfigure happens, a second change which depends
2735 # on the first is added, and a second reconfiguration happens.
2736 # Ensure that both changes merge.
2737
2738 # A failure may indicate incorrect caching or cleaning up of
2739 # references during a reconfiguration.
2740 self.worker.hold_jobs_in_build = True
2741
2742 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2743 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2744 B.setDependsOn(A, 1)
2745 A.addApproval('CRVW', 2)
2746 B.addApproval('CRVW', 2)
2747
2748 # Add the parent change.
2749 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2750 self.waitUntilSettled()
2751 self.worker.release('.*-merge')
2752 self.waitUntilSettled()
2753
2754 # Reconfigure (with only one change in the pipeline).
2755 self.sched.reconfigure(self.config)
2756 self.waitUntilSettled()
2757
2758 # Add the child change.
2759 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2760 self.waitUntilSettled()
2761 self.worker.release('.*-merge')
2762 self.waitUntilSettled()
2763
2764 # Reconfigure (with both in the pipeline).
2765 self.sched.reconfigure(self.config)
2766 self.waitUntilSettled()
2767
2768 self.worker.hold_jobs_in_build = False
2769 self.worker.release()
2770 self.waitUntilSettled()
2771
2772 self.assertEqual(len(self.history), 8)
2773
2774 self.assertEqual(A.data['status'], 'MERGED')
2775 self.assertEqual(A.reported, 2)
2776 self.assertEqual(B.data['status'], 'MERGED')
2777 self.assertEqual(B.reported, 2)
2778
James E. Blairec056492016-07-22 09:45:56 -07002779 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002780 def test_live_reconfiguration_del_project(self):
2781 # Test project deletion from layout
2782 # while changes are enqueued
2783
2784 self.worker.hold_jobs_in_build = True
2785 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2786 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2787 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
2788
2789 # A Depends-On: B
2790 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
2791 A.subject, B.data['id'])
2792 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2793
2794 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2795 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
2796 self.waitUntilSettled()
2797 self.worker.release('.*-merge')
2798 self.waitUntilSettled()
2799 self.assertEqual(len(self.builds), 5)
2800
2801 # This layout defines only org/project, not org/project1
James E. Blairf84026c2015-12-08 16:11:46 -08002802 self.updateConfigLayout(
2803 'tests/fixtures/layout-live-reconfiguration-del-project.yaml')
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002804 self.sched.reconfigure(self.config)
2805 self.waitUntilSettled()
2806
2807 # Builds for C aborted, builds for A succeed,
2808 # and have change B applied ahead
2809 job_c = self.getJobFromHistory('project1-test1')
2810 self.assertEqual(job_c.changes, '3,1')
2811 self.assertEqual(job_c.result, 'ABORTED')
2812
2813 self.worker.hold_jobs_in_build = False
2814 self.worker.release()
2815 self.waitUntilSettled()
2816
2817 self.assertEqual(self.getJobFromHistory('project-test1').changes,
2818 '2,1 1,1')
2819
2820 self.assertEqual(A.data['status'], 'NEW')
2821 self.assertEqual(B.data['status'], 'NEW')
2822 self.assertEqual(C.data['status'], 'NEW')
2823 self.assertEqual(A.reported, 1)
2824 self.assertEqual(B.reported, 0)
2825 self.assertEqual(C.reported, 0)
2826
2827 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
2828 self.assertIn('Build succeeded', A.messages[0])
2829
James E. Blairec056492016-07-22 09:45:56 -07002830 @skip("Disabled for early v3 development")
James E. Blaire712d9f2013-07-31 11:40:11 -07002831 def test_live_reconfiguration_functions(self):
2832 "Test live reconfiguration with a custom function"
2833 self.worker.registerFunction('build:node-project-test1:debian')
2834 self.worker.registerFunction('build:node-project-test1:wheezy')
2835 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
2836 A.addApproval('CRVW', 2)
2837 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2838 self.waitUntilSettled()
2839
2840 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2841 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2842 'debian')
2843 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2844
James E. Blairf84026c2015-12-08 16:11:46 -08002845 self.updateConfigLayout(
2846 'tests/fixtures/layout-live-reconfiguration-functions.yaml')
James E. Blaire712d9f2013-07-31 11:40:11 -07002847 self.sched.reconfigure(self.config)
2848 self.worker.build_history = []
2849
2850 B = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'B')
2851 B.addApproval('CRVW', 2)
2852 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2853 self.waitUntilSettled()
2854
2855 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2856 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2857 'wheezy')
2858 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2859
James E. Blairec056492016-07-22 09:45:56 -07002860 @skip("Disabled for early v3 development")
James E. Blair287c06d2013-07-24 10:39:30 -07002861 def test_delayed_repo_init(self):
James E. Blairf84026c2015-12-08 16:11:46 -08002862 self.updateConfigLayout(
2863 'tests/fixtures/layout-delayed-repo-init.yaml')
James E. Blair287c06d2013-07-24 10:39:30 -07002864 self.sched.reconfigure(self.config)
2865
2866 self.init_repo("org/new-project")
2867 A = self.fake_gerrit.addFakeChange('org/new-project', 'master', 'A')
2868
2869 A.addApproval('CRVW', 2)
2870 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2871 self.waitUntilSettled()
2872 self.assertEqual(self.getJobFromHistory('project-merge').result,
2873 'SUCCESS')
2874 self.assertEqual(self.getJobFromHistory('project-test1').result,
2875 'SUCCESS')
2876 self.assertEqual(self.getJobFromHistory('project-test2').result,
2877 'SUCCESS')
2878 self.assertEqual(A.data['status'], 'MERGED')
2879 self.assertEqual(A.reported, 2)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002880
James E. Blairec056492016-07-22 09:45:56 -07002881 @skip("Disabled for early v3 development")
Clark Boylan6dbbc482013-10-18 10:57:31 -07002882 def test_repo_deleted(self):
James E. Blairf84026c2015-12-08 16:11:46 -08002883 self.updateConfigLayout(
2884 'tests/fixtures/layout-repo-deleted.yaml')
Clark Boylan6dbbc482013-10-18 10:57:31 -07002885 self.sched.reconfigure(self.config)
2886
2887 self.init_repo("org/delete-project")
2888 A = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'A')
2889
2890 A.addApproval('CRVW', 2)
2891 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2892 self.waitUntilSettled()
2893 self.assertEqual(self.getJobFromHistory('project-merge').result,
2894 'SUCCESS')
2895 self.assertEqual(self.getJobFromHistory('project-test1').result,
2896 'SUCCESS')
2897 self.assertEqual(self.getJobFromHistory('project-test2').result,
2898 'SUCCESS')
2899 self.assertEqual(A.data['status'], 'MERGED')
2900 self.assertEqual(A.reported, 2)
2901
2902 # Delete org/new-project zuul repo. Should be recloned.
2903 shutil.rmtree(os.path.join(self.git_root, "org/delete-project"))
2904
2905 B = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'B')
2906
2907 B.addApproval('CRVW', 2)
2908 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2909 self.waitUntilSettled()
2910 self.assertEqual(self.getJobFromHistory('project-merge').result,
2911 'SUCCESS')
2912 self.assertEqual(self.getJobFromHistory('project-test1').result,
2913 'SUCCESS')
2914 self.assertEqual(self.getJobFromHistory('project-test2').result,
2915 'SUCCESS')
2916 self.assertEqual(B.data['status'], 'MERGED')
2917 self.assertEqual(B.reported, 2)
2918
James E. Blairec056492016-07-22 09:45:56 -07002919 @skip("Disabled for early v3 development")
James E. Blair456f2fb2016-02-09 09:29:33 -08002920 def test_tags(self):
2921 "Test job tags"
2922 self.config.set('zuul', 'layout_config',
2923 'tests/fixtures/layout-tags.yaml')
2924 self.sched.reconfigure(self.config)
2925
2926 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2927 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
2928 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2929 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2930 self.waitUntilSettled()
2931
2932 results = {'project1-merge': 'extratag merge project1',
2933 'project2-merge': 'merge'}
2934
2935 for build in self.history:
2936 self.assertEqual(results.get(build.name, ''),
2937 build.parameters.get('BUILD_TAGS'))
2938
James E. Blairec056492016-07-22 09:45:56 -07002939 @skip("Disabled for early v3 development")
James E. Blair63bb0ef2013-07-29 17:14:51 -07002940 def test_timer(self):
2941 "Test that a periodic job is triggered"
2942 self.worker.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08002943 self.updateConfigLayout(
2944 'tests/fixtures/layout-timer.yaml')
James E. Blair63bb0ef2013-07-29 17:14:51 -07002945 self.sched.reconfigure(self.config)
2946 self.registerJobs()
2947
Clark Boylan3ee090a2014-04-03 20:55:09 -07002948 # The pipeline triggers every second, so we should have seen
2949 # several by now.
2950 time.sleep(5)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002951 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002952
2953 self.assertEqual(len(self.builds), 2)
2954
James E. Blair63bb0ef2013-07-29 17:14:51 -07002955 port = self.webapp.server.socket.getsockname()[1]
2956
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002957 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2958 f = urllib.request.urlopen(req)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002959 data = f.read()
2960
2961 self.worker.hold_jobs_in_build = False
Clark Boylan3ee090a2014-04-03 20:55:09 -07002962 # Stop queuing timer triggered jobs so that the assertions
2963 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08002964 self.updateConfigLayout(
2965 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002966 self.sched.reconfigure(self.config)
2967 self.registerJobs()
James E. Blair63bb0ef2013-07-29 17:14:51 -07002968 self.worker.release()
2969 self.waitUntilSettled()
2970
2971 self.assertEqual(self.getJobFromHistory(
2972 'project-bitrot-stable-old').result, 'SUCCESS')
2973 self.assertEqual(self.getJobFromHistory(
2974 'project-bitrot-stable-older').result, 'SUCCESS')
2975
2976 data = json.loads(data)
2977 status_jobs = set()
2978 for p in data['pipelines']:
2979 for q in p['change_queues']:
2980 for head in q['heads']:
2981 for change in head:
Alex Gaynorddb9ef32013-09-16 21:04:58 -07002982 self.assertEqual(change['id'], None)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002983 for job in change['jobs']:
2984 status_jobs.add(job['name'])
2985 self.assertIn('project-bitrot-stable-old', status_jobs)
2986 self.assertIn('project-bitrot-stable-older', status_jobs)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002987
James E. Blairec056492016-07-22 09:45:56 -07002988 @skip("Disabled for early v3 development")
James E. Blair4f6033c2014-03-27 15:49:09 -07002989 def test_idle(self):
2990 "Test that frequent periodic jobs work"
2991 self.worker.hold_jobs_in_build = True
James E. Blair4f6033c2014-03-27 15:49:09 -07002992
Clark Boylan3ee090a2014-04-03 20:55:09 -07002993 for x in range(1, 3):
2994 # Test that timer triggers periodic jobs even across
2995 # layout config reloads.
2996 # Start timer trigger
James E. Blairf84026c2015-12-08 16:11:46 -08002997 self.updateConfigLayout(
2998 'tests/fixtures/layout-idle.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002999 self.sched.reconfigure(self.config)
3000 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08003001 self.waitUntilSettled()
James E. Blair4f6033c2014-03-27 15:49:09 -07003002
Clark Boylan3ee090a2014-04-03 20:55:09 -07003003 # The pipeline triggers every second, so we should have seen
3004 # several by now.
3005 time.sleep(5)
Clark Boylan3ee090a2014-04-03 20:55:09 -07003006
3007 # Stop queuing timer triggered jobs so that the assertions
3008 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08003009 self.updateConfigLayout(
3010 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07003011 self.sched.reconfigure(self.config)
3012 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08003013 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07003014
3015 self.assertEqual(len(self.builds), 2)
3016 self.worker.release('.*')
3017 self.waitUntilSettled()
3018 self.assertEqual(len(self.builds), 0)
3019 self.assertEqual(len(self.history), x * 2)
James E. Blair4f6033c2014-03-27 15:49:09 -07003020
James E. Blairec056492016-07-22 09:45:56 -07003021 @skip("Disabled for early v3 development")
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003022 def test_check_smtp_pool(self):
James E. Blairf84026c2015-12-08 16:11:46 -08003023 self.updateConfigLayout(
3024 'tests/fixtures/layout-smtp.yaml')
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003025 self.sched.reconfigure(self.config)
3026
3027 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3028 self.waitUntilSettled()
3029
3030 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
3031 self.waitUntilSettled()
3032
James E. Blairff80a2f2013-12-27 13:24:06 -08003033 self.assertEqual(len(self.smtp_messages), 2)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003034
3035 # A.messages only holds what FakeGerrit places in it. Thus we
3036 # work on the knowledge of what the first message should be as
3037 # it is only configured to go to SMTP.
3038
3039 self.assertEqual('zuul@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003040 self.smtp_messages[0]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003041 self.assertEqual(['you@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003042 self.smtp_messages[0]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003043 self.assertEqual('Starting check jobs.',
James E. Blairff80a2f2013-12-27 13:24:06 -08003044 self.smtp_messages[0]['body'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003045
3046 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003047 self.smtp_messages[1]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003048 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003049 self.smtp_messages[1]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003050 self.assertEqual(A.messages[0],
James E. Blairff80a2f2013-12-27 13:24:06 -08003051 self.smtp_messages[1]['body'])
James E. Blairad28e912013-11-27 10:43:22 -08003052
James E. Blairec056492016-07-22 09:45:56 -07003053 @skip("Disabled for early v3 development")
James E. Blaire5910202013-12-27 09:50:31 -08003054 def test_timer_smtp(self):
3055 "Test that a periodic job is triggered"
Clark Boylan3ee090a2014-04-03 20:55:09 -07003056 self.worker.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08003057 self.updateConfigLayout(
3058 'tests/fixtures/layout-timer-smtp.yaml')
James E. Blaire5910202013-12-27 09:50:31 -08003059 self.sched.reconfigure(self.config)
3060 self.registerJobs()
3061
Clark Boylan3ee090a2014-04-03 20:55:09 -07003062 # The pipeline triggers every second, so we should have seen
3063 # several by now.
3064 time.sleep(5)
James E. Blaire5910202013-12-27 09:50:31 -08003065 self.waitUntilSettled()
3066
Clark Boylan3ee090a2014-04-03 20:55:09 -07003067 self.assertEqual(len(self.builds), 2)
3068 self.worker.release('.*')
3069 self.waitUntilSettled()
3070 self.assertEqual(len(self.history), 2)
3071
James E. Blaire5910202013-12-27 09:50:31 -08003072 self.assertEqual(self.getJobFromHistory(
3073 'project-bitrot-stable-old').result, 'SUCCESS')
3074 self.assertEqual(self.getJobFromHistory(
3075 'project-bitrot-stable-older').result, 'SUCCESS')
3076
James E. Blairff80a2f2013-12-27 13:24:06 -08003077 self.assertEqual(len(self.smtp_messages), 1)
James E. Blaire5910202013-12-27 09:50:31 -08003078
3079 # A.messages only holds what FakeGerrit places in it. Thus we
3080 # work on the knowledge of what the first message should be as
3081 # it is only configured to go to SMTP.
3082
3083 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003084 self.smtp_messages[0]['from_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003085 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003086 self.smtp_messages[0]['to_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003087 self.assertIn('Subject: Periodic check for org/project succeeded',
James E. Blairff80a2f2013-12-27 13:24:06 -08003088 self.smtp_messages[0]['headers'])
James E. Blaire5910202013-12-27 09:50:31 -08003089
Clark Boylan3ee090a2014-04-03 20:55:09 -07003090 # Stop queuing timer triggered jobs and let any that may have
3091 # queued through so that end of test assertions pass.
James E. Blairf84026c2015-12-08 16:11:46 -08003092 self.updateConfigLayout(
3093 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07003094 self.sched.reconfigure(self.config)
3095 self.registerJobs()
James E. Blairf8058972014-08-15 16:09:16 -07003096 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07003097 self.worker.release('.*')
3098 self.waitUntilSettled()
3099
James E. Blairec056492016-07-22 09:45:56 -07003100 @skip("Disabled for early v3 development")
James E. Blair91e34592015-07-31 16:45:59 -07003101 def test_client_enqueue_change(self):
James E. Blairad28e912013-11-27 10:43:22 -08003102 "Test that the RPC client can enqueue a change"
3103 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3104 A.addApproval('CRVW', 2)
3105 A.addApproval('APRV', 1)
3106
3107 client = zuul.rpcclient.RPCClient('127.0.0.1',
3108 self.gearman_server.port)
3109 r = client.enqueue(pipeline='gate',
3110 project='org/project',
3111 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003112 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003113 self.waitUntilSettled()
3114 self.assertEqual(self.getJobFromHistory('project-merge').result,
3115 'SUCCESS')
3116 self.assertEqual(self.getJobFromHistory('project-test1').result,
3117 'SUCCESS')
3118 self.assertEqual(self.getJobFromHistory('project-test2').result,
3119 'SUCCESS')
3120 self.assertEqual(A.data['status'], 'MERGED')
3121 self.assertEqual(A.reported, 2)
3122 self.assertEqual(r, True)
3123
James E. Blairec056492016-07-22 09:45:56 -07003124 @skip("Disabled for early v3 development")
James E. Blair91e34592015-07-31 16:45:59 -07003125 def test_client_enqueue_ref(self):
3126 "Test that the RPC client can enqueue a ref"
3127
3128 client = zuul.rpcclient.RPCClient('127.0.0.1',
3129 self.gearman_server.port)
3130 r = client.enqueue_ref(
3131 pipeline='post',
3132 project='org/project',
3133 trigger='gerrit',
3134 ref='master',
3135 oldrev='90f173846e3af9154517b88543ffbd1691f31366',
3136 newrev='d479a0bfcb34da57a31adb2a595c0cf687812543')
3137 self.waitUntilSettled()
3138 job_names = [x.name for x in self.history]
3139 self.assertEqual(len(self.history), 1)
3140 self.assertIn('project-post', job_names)
3141 self.assertEqual(r, True)
3142
James E. Blairec056492016-07-22 09:45:56 -07003143 @skip("Disabled for early v3 development")
James E. Blairad28e912013-11-27 10:43:22 -08003144 def test_client_enqueue_negative(self):
3145 "Test that the RPC client returns errors"
3146 client = zuul.rpcclient.RPCClient('127.0.0.1',
3147 self.gearman_server.port)
3148 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3149 "Invalid project"):
3150 r = client.enqueue(pipeline='gate',
3151 project='project-does-not-exist',
3152 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003153 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003154 client.shutdown()
3155 self.assertEqual(r, False)
3156
3157 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3158 "Invalid pipeline"):
3159 r = client.enqueue(pipeline='pipeline-does-not-exist',
3160 project='org/project',
3161 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003162 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003163 client.shutdown()
3164 self.assertEqual(r, False)
3165
3166 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3167 "Invalid trigger"):
3168 r = client.enqueue(pipeline='gate',
3169 project='org/project',
3170 trigger='trigger-does-not-exist',
James E. Blair36658cf2013-12-06 17:53:48 -08003171 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003172 client.shutdown()
3173 self.assertEqual(r, False)
3174
3175 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3176 "Invalid change"):
3177 r = client.enqueue(pipeline='gate',
3178 project='org/project',
3179 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003180 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003181 client.shutdown()
3182 self.assertEqual(r, False)
3183
3184 self.waitUntilSettled()
3185 self.assertEqual(len(self.history), 0)
3186 self.assertEqual(len(self.builds), 0)
James E. Blair36658cf2013-12-06 17:53:48 -08003187
James E. Blairec056492016-07-22 09:45:56 -07003188 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003189 def test_client_promote(self):
3190 "Test that the RPC client can promote a change"
3191 self.worker.hold_jobs_in_build = True
3192 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3193 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3194 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3195 A.addApproval('CRVW', 2)
3196 B.addApproval('CRVW', 2)
3197 C.addApproval('CRVW', 2)
3198
3199 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3200 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3201 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3202
3203 self.waitUntilSettled()
3204
Sean Daguef39b9ca2014-01-10 21:34:35 -05003205 items = self.sched.layout.pipelines['gate'].getAllItems()
3206 enqueue_times = {}
3207 for item in items:
3208 enqueue_times[str(item.change)] = item.enqueue_time
3209
James E. Blair36658cf2013-12-06 17:53:48 -08003210 client = zuul.rpcclient.RPCClient('127.0.0.1',
3211 self.gearman_server.port)
3212 r = client.promote(pipeline='gate',
3213 change_ids=['2,1', '3,1'])
3214
Sean Daguef39b9ca2014-01-10 21:34:35 -05003215 # ensure that enqueue times are durable
3216 items = self.sched.layout.pipelines['gate'].getAllItems()
3217 for item in items:
3218 self.assertEqual(
3219 enqueue_times[str(item.change)], item.enqueue_time)
3220
James E. Blair78acec92014-02-06 07:11:32 -08003221 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08003222 self.worker.release('.*-merge')
3223 self.waitUntilSettled()
3224 self.worker.release('.*-merge')
3225 self.waitUntilSettled()
3226 self.worker.release('.*-merge')
3227 self.waitUntilSettled()
3228
3229 self.assertEqual(len(self.builds), 6)
3230 self.assertEqual(self.builds[0].name, 'project-test1')
3231 self.assertEqual(self.builds[1].name, 'project-test2')
3232 self.assertEqual(self.builds[2].name, 'project-test1')
3233 self.assertEqual(self.builds[3].name, 'project-test2')
3234 self.assertEqual(self.builds[4].name, 'project-test1')
3235 self.assertEqual(self.builds[5].name, 'project-test2')
3236
3237 self.assertTrue(self.job_has_changes(self.builds[0], B))
3238 self.assertFalse(self.job_has_changes(self.builds[0], A))
3239 self.assertFalse(self.job_has_changes(self.builds[0], C))
3240
3241 self.assertTrue(self.job_has_changes(self.builds[2], B))
3242 self.assertTrue(self.job_has_changes(self.builds[2], C))
3243 self.assertFalse(self.job_has_changes(self.builds[2], A))
3244
3245 self.assertTrue(self.job_has_changes(self.builds[4], B))
3246 self.assertTrue(self.job_has_changes(self.builds[4], C))
3247 self.assertTrue(self.job_has_changes(self.builds[4], A))
3248
3249 self.worker.release()
3250 self.waitUntilSettled()
3251
3252 self.assertEqual(A.data['status'], 'MERGED')
3253 self.assertEqual(A.reported, 2)
3254 self.assertEqual(B.data['status'], 'MERGED')
3255 self.assertEqual(B.reported, 2)
3256 self.assertEqual(C.data['status'], 'MERGED')
3257 self.assertEqual(C.reported, 2)
3258
3259 client.shutdown()
3260 self.assertEqual(r, True)
3261
James E. Blairec056492016-07-22 09:45:56 -07003262 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003263 def test_client_promote_dependent(self):
3264 "Test that the RPC client can promote a dependent change"
3265 # C (depends on B) -> B -> A ; then promote C to get:
3266 # A -> C (depends on B) -> B
3267 self.worker.hold_jobs_in_build = True
3268 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3269 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3270 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3271
3272 C.setDependsOn(B, 1)
3273
3274 A.addApproval('CRVW', 2)
3275 B.addApproval('CRVW', 2)
3276 C.addApproval('CRVW', 2)
3277
3278 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3279 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3280 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3281
3282 self.waitUntilSettled()
3283
3284 client = zuul.rpcclient.RPCClient('127.0.0.1',
3285 self.gearman_server.port)
3286 r = client.promote(pipeline='gate',
3287 change_ids=['3,1'])
3288
James E. Blair78acec92014-02-06 07:11:32 -08003289 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08003290 self.worker.release('.*-merge')
3291 self.waitUntilSettled()
3292 self.worker.release('.*-merge')
3293 self.waitUntilSettled()
3294 self.worker.release('.*-merge')
3295 self.waitUntilSettled()
3296
3297 self.assertEqual(len(self.builds), 6)
3298 self.assertEqual(self.builds[0].name, 'project-test1')
3299 self.assertEqual(self.builds[1].name, 'project-test2')
3300 self.assertEqual(self.builds[2].name, 'project-test1')
3301 self.assertEqual(self.builds[3].name, 'project-test2')
3302 self.assertEqual(self.builds[4].name, 'project-test1')
3303 self.assertEqual(self.builds[5].name, 'project-test2')
3304
3305 self.assertTrue(self.job_has_changes(self.builds[0], B))
3306 self.assertFalse(self.job_has_changes(self.builds[0], A))
3307 self.assertFalse(self.job_has_changes(self.builds[0], C))
3308
3309 self.assertTrue(self.job_has_changes(self.builds[2], B))
3310 self.assertTrue(self.job_has_changes(self.builds[2], C))
3311 self.assertFalse(self.job_has_changes(self.builds[2], A))
3312
3313 self.assertTrue(self.job_has_changes(self.builds[4], B))
3314 self.assertTrue(self.job_has_changes(self.builds[4], C))
3315 self.assertTrue(self.job_has_changes(self.builds[4], A))
3316
3317 self.worker.release()
3318 self.waitUntilSettled()
3319
3320 self.assertEqual(A.data['status'], 'MERGED')
3321 self.assertEqual(A.reported, 2)
3322 self.assertEqual(B.data['status'], 'MERGED')
3323 self.assertEqual(B.reported, 2)
3324 self.assertEqual(C.data['status'], 'MERGED')
3325 self.assertEqual(C.reported, 2)
3326
3327 client.shutdown()
3328 self.assertEqual(r, True)
3329
James E. Blairec056492016-07-22 09:45:56 -07003330 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003331 def test_client_promote_negative(self):
3332 "Test that the RPC client returns errors for promotion"
3333 self.worker.hold_jobs_in_build = True
3334 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3335 A.addApproval('CRVW', 2)
3336 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3337 self.waitUntilSettled()
3338
3339 client = zuul.rpcclient.RPCClient('127.0.0.1',
3340 self.gearman_server.port)
3341
3342 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
3343 r = client.promote(pipeline='nonexistent',
3344 change_ids=['2,1', '3,1'])
3345 client.shutdown()
3346 self.assertEqual(r, False)
3347
3348 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
3349 r = client.promote(pipeline='gate',
3350 change_ids=['4,1'])
3351 client.shutdown()
3352 self.assertEqual(r, False)
3353
3354 self.worker.hold_jobs_in_build = False
3355 self.worker.release()
3356 self.waitUntilSettled()
Clark Boylan7603a372014-01-21 11:43:20 -08003357
James E. Blairec056492016-07-22 09:45:56 -07003358 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003359 def test_queue_rate_limiting(self):
3360 "Test that DependentPipelines are rate limited with dep across window"
James E. Blairf84026c2015-12-08 16:11:46 -08003361 self.updateConfigLayout(
3362 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003363 self.sched.reconfigure(self.config)
3364 self.worker.hold_jobs_in_build = True
3365 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3366 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3367 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3368
3369 C.setDependsOn(B, 1)
3370 self.worker.addFailTest('project-test1', A)
3371
3372 A.addApproval('CRVW', 2)
3373 B.addApproval('CRVW', 2)
3374 C.addApproval('CRVW', 2)
3375
3376 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3377 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3378 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3379 self.waitUntilSettled()
3380
3381 # Only A and B will have their merge jobs queued because
3382 # window is 2.
3383 self.assertEqual(len(self.builds), 2)
3384 self.assertEqual(self.builds[0].name, 'project-merge')
3385 self.assertEqual(self.builds[1].name, 'project-merge')
3386
3387 self.worker.release('.*-merge')
3388 self.waitUntilSettled()
3389 self.worker.release('.*-merge')
3390 self.waitUntilSettled()
3391
3392 # Only A and B will have their test jobs queued because
3393 # window is 2.
3394 self.assertEqual(len(self.builds), 4)
3395 self.assertEqual(self.builds[0].name, 'project-test1')
3396 self.assertEqual(self.builds[1].name, 'project-test2')
3397 self.assertEqual(self.builds[2].name, 'project-test1')
3398 self.assertEqual(self.builds[3].name, 'project-test2')
3399
3400 self.worker.release('project-.*')
3401 self.waitUntilSettled()
3402
3403 queue = self.sched.layout.pipelines['gate'].queues[0]
3404 # A failed so window is reduced by 1 to 1.
3405 self.assertEqual(queue.window, 1)
3406 self.assertEqual(queue.window_floor, 1)
3407 self.assertEqual(A.data['status'], 'NEW')
3408
3409 # Gate is reset and only B's merge job is queued because
3410 # window shrunk to 1.
3411 self.assertEqual(len(self.builds), 1)
3412 self.assertEqual(self.builds[0].name, 'project-merge')
3413
3414 self.worker.release('.*-merge')
3415 self.waitUntilSettled()
3416
3417 # Only B's test jobs are queued because window is still 1.
3418 self.assertEqual(len(self.builds), 2)
3419 self.assertEqual(self.builds[0].name, 'project-test1')
3420 self.assertEqual(self.builds[1].name, 'project-test2')
3421
3422 self.worker.release('project-.*')
3423 self.waitUntilSettled()
3424
3425 # B was successfully merged so window is increased to 2.
3426 self.assertEqual(queue.window, 2)
3427 self.assertEqual(queue.window_floor, 1)
3428 self.assertEqual(B.data['status'], 'MERGED')
3429
3430 # Only C is left and its merge job is queued.
3431 self.assertEqual(len(self.builds), 1)
3432 self.assertEqual(self.builds[0].name, 'project-merge')
3433
3434 self.worker.release('.*-merge')
3435 self.waitUntilSettled()
3436
3437 # After successful merge job the test jobs for C are queued.
3438 self.assertEqual(len(self.builds), 2)
3439 self.assertEqual(self.builds[0].name, 'project-test1')
3440 self.assertEqual(self.builds[1].name, 'project-test2')
3441
3442 self.worker.release('project-.*')
3443 self.waitUntilSettled()
3444
3445 # C successfully merged so window is bumped to 3.
3446 self.assertEqual(queue.window, 3)
3447 self.assertEqual(queue.window_floor, 1)
3448 self.assertEqual(C.data['status'], 'MERGED')
3449
James E. Blairec056492016-07-22 09:45:56 -07003450 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003451 def test_queue_rate_limiting_dependent(self):
3452 "Test that DependentPipelines are rate limited with dep in window"
James E. Blairf84026c2015-12-08 16:11:46 -08003453 self.updateConfigLayout(
3454 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003455 self.sched.reconfigure(self.config)
3456 self.worker.hold_jobs_in_build = True
3457 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3458 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3459 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3460
3461 B.setDependsOn(A, 1)
3462
3463 self.worker.addFailTest('project-test1', A)
3464
3465 A.addApproval('CRVW', 2)
3466 B.addApproval('CRVW', 2)
3467 C.addApproval('CRVW', 2)
3468
3469 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3470 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3471 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3472 self.waitUntilSettled()
3473
3474 # Only A and B will have their merge jobs queued because
3475 # window is 2.
3476 self.assertEqual(len(self.builds), 2)
3477 self.assertEqual(self.builds[0].name, 'project-merge')
3478 self.assertEqual(self.builds[1].name, 'project-merge')
3479
3480 self.worker.release('.*-merge')
3481 self.waitUntilSettled()
3482 self.worker.release('.*-merge')
3483 self.waitUntilSettled()
3484
3485 # Only A and B will have their test jobs queued because
3486 # window is 2.
3487 self.assertEqual(len(self.builds), 4)
3488 self.assertEqual(self.builds[0].name, 'project-test1')
3489 self.assertEqual(self.builds[1].name, 'project-test2')
3490 self.assertEqual(self.builds[2].name, 'project-test1')
3491 self.assertEqual(self.builds[3].name, 'project-test2')
3492
3493 self.worker.release('project-.*')
3494 self.waitUntilSettled()
3495
3496 queue = self.sched.layout.pipelines['gate'].queues[0]
3497 # A failed so window is reduced by 1 to 1.
3498 self.assertEqual(queue.window, 1)
3499 self.assertEqual(queue.window_floor, 1)
3500 self.assertEqual(A.data['status'], 'NEW')
3501 self.assertEqual(B.data['status'], 'NEW')
3502
3503 # Gate is reset and only C's merge job is queued because
3504 # window shrunk to 1 and A and B were dequeued.
3505 self.assertEqual(len(self.builds), 1)
3506 self.assertEqual(self.builds[0].name, 'project-merge')
3507
3508 self.worker.release('.*-merge')
3509 self.waitUntilSettled()
3510
3511 # Only C's test jobs are queued because window is still 1.
3512 self.assertEqual(len(self.builds), 2)
3513 self.assertEqual(self.builds[0].name, 'project-test1')
3514 self.assertEqual(self.builds[1].name, 'project-test2')
3515
3516 self.worker.release('project-.*')
3517 self.waitUntilSettled()
3518
3519 # C was successfully merged so window is increased to 2.
3520 self.assertEqual(queue.window, 2)
3521 self.assertEqual(queue.window_floor, 1)
3522 self.assertEqual(C.data['status'], 'MERGED')
Joshua Heskethba8776a2014-01-12 14:35:40 +08003523
James E. Blairec056492016-07-22 09:45:56 -07003524 @skip("Disabled for early v3 development")
Joshua Heskethba8776a2014-01-12 14:35:40 +08003525 def test_worker_update_metadata(self):
3526 "Test if a worker can send back metadata about itself"
3527 self.worker.hold_jobs_in_build = True
3528
3529 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3530 A.addApproval('CRVW', 2)
3531 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3532 self.waitUntilSettled()
3533
3534 self.assertEqual(len(self.launcher.builds), 1)
3535
3536 self.log.debug('Current builds:')
3537 self.log.debug(self.launcher.builds)
3538
3539 start = time.time()
3540 while True:
3541 if time.time() - start > 10:
3542 raise Exception("Timeout waiting for gearman server to report "
3543 + "back to the client")
3544 build = self.launcher.builds.values()[0]
3545 if build.worker.name == "My Worker":
3546 break
3547 else:
3548 time.sleep(0)
3549
3550 self.log.debug(build)
3551 self.assertEqual("My Worker", build.worker.name)
3552 self.assertEqual("localhost", build.worker.hostname)
3553 self.assertEqual(['127.0.0.1', '192.168.1.1'], build.worker.ips)
3554 self.assertEqual("zuul.example.org", build.worker.fqdn)
3555 self.assertEqual("FakeBuilder", build.worker.program)
3556 self.assertEqual("v1.1", build.worker.version)
3557 self.assertEqual({'something': 'else'}, build.worker.extra)
3558
3559 self.worker.hold_jobs_in_build = False
3560 self.worker.release()
3561 self.waitUntilSettled()
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003562
James E. Blairec056492016-07-22 09:45:56 -07003563 @skip("Disabled for early v3 development")
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003564 def test_footer_message(self):
3565 "Test a pipeline's footer message is correctly added to the report."
James E. Blairf84026c2015-12-08 16:11:46 -08003566 self.updateConfigLayout(
3567 'tests/fixtures/layout-footer-message.yaml')
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003568 self.sched.reconfigure(self.config)
3569 self.registerJobs()
3570
3571 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3572 A.addApproval('CRVW', 2)
3573 self.worker.addFailTest('test1', A)
3574 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3575 self.waitUntilSettled()
3576
3577 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3578 B.addApproval('CRVW', 2)
3579 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3580 self.waitUntilSettled()
3581
3582 self.assertEqual(2, len(self.smtp_messages))
3583
3584 failure_body = """\
3585Build failed. For information on how to proceed, see \
3586http://wiki.example.org/Test_Failures
3587
3588- test1 http://logs.example.com/1/1/gate/test1/0 : FAILURE in 0s
3589- test2 http://logs.example.com/1/1/gate/test2/1 : SUCCESS in 0s
3590
3591For CI problems and help debugging, contact ci@example.org"""
3592
3593 success_body = """\
3594Build succeeded.
3595
3596- test1 http://logs.example.com/2/1/gate/test1/2 : SUCCESS in 0s
3597- test2 http://logs.example.com/2/1/gate/test2/3 : SUCCESS in 0s
3598
3599For CI problems and help debugging, contact ci@example.org"""
3600
3601 self.assertEqual(failure_body, self.smtp_messages[0]['body'])
3602 self.assertEqual(success_body, self.smtp_messages[1]['body'])
Joshua Heskethb7179772014-01-30 23:30:46 +11003603
James E. Blairec056492016-07-22 09:45:56 -07003604 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003605 def test_merge_failure_reporters(self):
3606 """Check that the config is set up correctly"""
3607
James E. Blairf84026c2015-12-08 16:11:46 -08003608 self.updateConfigLayout(
3609 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003610 self.sched.reconfigure(self.config)
3611 self.registerJobs()
3612
3613 self.assertEqual(
Jeremy Stanley1c2c3c22015-06-15 21:23:19 +00003614 "Merge Failed.\n\nThis change or one of its cross-repo "
3615 "dependencies was unable to be automatically merged with the "
3616 "current state of its repository. Please rebase the change and "
3617 "upload a new patchset.",
Joshua Heskethb7179772014-01-30 23:30:46 +11003618 self.sched.layout.pipelines['check'].merge_failure_message)
3619 self.assertEqual(
3620 "The merge failed! For more information...",
3621 self.sched.layout.pipelines['gate'].merge_failure_message)
3622
3623 self.assertEqual(
3624 len(self.sched.layout.pipelines['check'].merge_failure_actions), 1)
3625 self.assertEqual(
3626 len(self.sched.layout.pipelines['gate'].merge_failure_actions), 2)
3627
3628 self.assertTrue(isinstance(
Joshua Heskethde958652015-11-10 19:19:50 +11003629 self.sched.layout.pipelines['check'].merge_failure_actions[0],
3630 zuul.reporter.gerrit.GerritReporter))
Joshua Heskethb7179772014-01-30 23:30:46 +11003631
3632 self.assertTrue(
3633 (
3634 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003635 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003636 zuul.reporter.smtp.SMTPReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003637 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003638 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003639 zuul.reporter.gerrit.GerritReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003640 ) or (
3641 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003642 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003643 zuul.reporter.gerrit.GerritReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003644 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003645 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003646 zuul.reporter.smtp.SMTPReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003647 )
3648 )
3649
James E. Blairec056492016-07-22 09:45:56 -07003650 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003651 def test_merge_failure_reports(self):
3652 """Check that when a change fails to merge the correct message is sent
3653 to the correct reporter"""
James E. Blairf84026c2015-12-08 16:11:46 -08003654 self.updateConfigLayout(
3655 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003656 self.sched.reconfigure(self.config)
3657 self.registerJobs()
3658
3659 # Check a test failure isn't reported to SMTP
3660 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3661 A.addApproval('CRVW', 2)
3662 self.worker.addFailTest('project-test1', A)
3663 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3664 self.waitUntilSettled()
3665
3666 self.assertEqual(3, len(self.history)) # 3 jobs
3667 self.assertEqual(0, len(self.smtp_messages))
3668
3669 # Check a merge failure is reported to SMTP
3670 # B should be merged, but C will conflict with B
3671 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3672 B.addPatchset(['conflict'])
3673 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3674 C.addPatchset(['conflict'])
3675 B.addApproval('CRVW', 2)
3676 C.addApproval('CRVW', 2)
3677 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3678 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3679 self.waitUntilSettled()
3680
3681 self.assertEqual(6, len(self.history)) # A and B jobs
3682 self.assertEqual(1, len(self.smtp_messages))
3683 self.assertEqual('The merge failed! For more information...',
3684 self.smtp_messages[0]['body'])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003685
James E. Blairec056492016-07-22 09:45:56 -07003686 @skip("Disabled for early v3 development")
James E. Blairf760f0e2016-02-09 08:44:52 -08003687 def test_default_merge_failure_reports(self):
3688 """Check that the default merge failure reports are correct."""
3689
3690 # A should report success, B should report merge failure.
3691 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3692 A.addPatchset(['conflict'])
3693 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3694 B.addPatchset(['conflict'])
3695 A.addApproval('CRVW', 2)
3696 B.addApproval('CRVW', 2)
3697 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3698 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3699 self.waitUntilSettled()
3700
3701 self.assertEqual(3, len(self.history)) # A jobs
3702 self.assertEqual(A.reported, 2)
3703 self.assertEqual(B.reported, 2)
3704 self.assertEqual(A.data['status'], 'MERGED')
3705 self.assertEqual(B.data['status'], 'NEW')
3706 self.assertIn('Build succeeded', A.messages[1])
3707 self.assertIn('Merge Failed', B.messages[1])
3708 self.assertIn('automatically merged', B.messages[1])
3709 self.assertNotIn('logs.example.com', B.messages[1])
3710 self.assertNotIn('SKIPPED', B.messages[1])
3711
James E. Blairec056492016-07-22 09:45:56 -07003712 @skip("Disabled for early v3 development")
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003713 def test_swift_instructions(self):
3714 "Test that the correct swift instructions are sent to the workers"
James E. Blairf84026c2015-12-08 16:11:46 -08003715 self.updateConfigLayout(
3716 'tests/fixtures/layout-swift.yaml')
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003717 self.sched.reconfigure(self.config)
3718 self.registerJobs()
3719
3720 self.worker.hold_jobs_in_build = True
3721 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3722
3723 A.addApproval('CRVW', 2)
3724 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3725 self.waitUntilSettled()
3726
3727 self.assertEqual(
3728 "https://storage.example.org/V1/AUTH_account/merge_logs/1/1/1/"
3729 "gate/test-merge/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003730 self.builds[0].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003731 self.assertEqual(5,
3732 len(self.builds[0].parameters['SWIFT_logs_HMAC_BODY'].
3733 split('\n')))
3734 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[0].parameters)
3735
3736 self.assertEqual(
3737 "https://storage.example.org/V1/AUTH_account/logs/1/1/1/"
3738 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003739 self.builds[1].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003740 self.assertEqual(5,
3741 len(self.builds[1].parameters['SWIFT_logs_HMAC_BODY'].
3742 split('\n')))
3743 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[1].parameters)
3744
3745 self.assertEqual(
3746 "https://storage.example.org/V1/AUTH_account/stash/1/1/1/"
3747 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003748 self.builds[1].parameters['SWIFT_MOSTLY_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003749 self.assertEqual(5,
3750 len(self.builds[1].
3751 parameters['SWIFT_MOSTLY_HMAC_BODY'].split('\n')))
3752 self.assertIn('SWIFT_MOSTLY_SIGNATURE', self.builds[1].parameters)
3753
3754 self.worker.hold_jobs_in_build = False
3755 self.worker.release()
3756 self.waitUntilSettled()
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003757
James E. Blairec056492016-07-22 09:45:56 -07003758 @skip("Disabled for early v3 development")
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003759 def test_client_get_running_jobs(self):
3760 "Test that the RPC client can get a list of running jobs"
3761 self.worker.hold_jobs_in_build = True
3762 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3763 A.addApproval('CRVW', 2)
3764 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3765 self.waitUntilSettled()
3766
3767 client = zuul.rpcclient.RPCClient('127.0.0.1',
3768 self.gearman_server.port)
3769
3770 # Wait for gearman server to send the initial workData back to zuul
3771 start = time.time()
3772 while True:
3773 if time.time() - start > 10:
3774 raise Exception("Timeout waiting for gearman server to report "
3775 + "back to the client")
3776 build = self.launcher.builds.values()[0]
3777 if build.worker.name == "My Worker":
3778 break
3779 else:
3780 time.sleep(0)
3781
3782 running_items = client.get_running_jobs()
3783
3784 self.assertEqual(1, len(running_items))
3785 running_item = running_items[0]
3786 self.assertEqual([], running_item['failing_reasons'])
3787 self.assertEqual([], running_item['items_behind'])
3788 self.assertEqual('https://hostname/1', running_item['url'])
3789 self.assertEqual(None, running_item['item_ahead'])
3790 self.assertEqual('org/project', running_item['project'])
3791 self.assertEqual(None, running_item['remaining_time'])
3792 self.assertEqual(True, running_item['active'])
3793 self.assertEqual('1,1', running_item['id'])
3794
3795 self.assertEqual(3, len(running_item['jobs']))
3796 for job in running_item['jobs']:
3797 if job['name'] == 'project-merge':
3798 self.assertEqual('project-merge', job['name'])
3799 self.assertEqual('gate', job['pipeline'])
3800 self.assertEqual(False, job['retry'])
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003801 self.assertEqual('https://server/job/project-merge/0/',
3802 job['url'])
3803 self.assertEqual(7, len(job['worker']))
3804 self.assertEqual(False, job['canceled'])
3805 self.assertEqual(True, job['voting'])
3806 self.assertEqual(None, job['result'])
3807 self.assertEqual('gate', job['pipeline'])
3808 break
3809
3810 self.worker.hold_jobs_in_build = False
3811 self.worker.release()
3812 self.waitUntilSettled()
3813
3814 running_items = client.get_running_jobs()
3815 self.assertEqual(0, len(running_items))
James E. Blairbadc1ad2014-04-28 13:55:14 -07003816
James E. Blairec056492016-07-22 09:45:56 -07003817 @skip("Disabled for early v3 development")
James E. Blairbadc1ad2014-04-28 13:55:14 -07003818 def test_nonvoting_pipeline(self):
3819 "Test that a nonvoting pipeline (experimental) can still report"
3820
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003821 A = self.fake_gerrit.addFakeChange('org/experimental-project',
3822 'master', 'A')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003823 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
3824 self.waitUntilSettled()
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003825 self.assertEqual(
3826 self.getJobFromHistory('experimental-project-test').result,
3827 'SUCCESS')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003828 self.assertEqual(A.reported, 1)
James E. Blair5ee24252014-12-30 10:12:29 -08003829
James E. Blairec056492016-07-22 09:45:56 -07003830 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08003831 def test_crd_gate(self):
3832 "Test cross-repo dependencies"
3833 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3834 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3835 A.addApproval('CRVW', 2)
3836 B.addApproval('CRVW', 2)
3837
3838 AM2 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM2')
3839 AM1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM1')
3840 AM2.setMerged()
3841 AM1.setMerged()
3842
3843 BM2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM2')
3844 BM1 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM1')
3845 BM2.setMerged()
3846 BM1.setMerged()
3847
3848 # A -> AM1 -> AM2
3849 # B -> BM1 -> BM2
3850 # A Depends-On: B
3851 # M2 is here to make sure it is never queried. If it is, it
3852 # means zuul is walking down the entire history of merged
3853 # changes.
3854
3855 B.setDependsOn(BM1, 1)
3856 BM1.setDependsOn(BM2, 1)
3857
3858 A.setDependsOn(AM1, 1)
3859 AM1.setDependsOn(AM2, 1)
3860
3861 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3862 A.subject, B.data['id'])
3863
3864 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3865 self.waitUntilSettled()
3866
3867 self.assertEqual(A.data['status'], 'NEW')
3868 self.assertEqual(B.data['status'], 'NEW')
3869
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11003870 for connection in self.connections.values():
3871 connection.maintainCache([])
James E. Blair5ee24252014-12-30 10:12:29 -08003872
3873 self.worker.hold_jobs_in_build = True
3874 B.addApproval('APRV', 1)
3875 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3876 self.waitUntilSettled()
3877
3878 self.worker.release('.*-merge')
3879 self.waitUntilSettled()
3880 self.worker.release('.*-merge')
3881 self.waitUntilSettled()
3882 self.worker.hold_jobs_in_build = False
3883 self.worker.release()
3884 self.waitUntilSettled()
3885
3886 self.assertEqual(AM2.queried, 0)
3887 self.assertEqual(BM2.queried, 0)
3888 self.assertEqual(A.data['status'], 'MERGED')
3889 self.assertEqual(B.data['status'], 'MERGED')
3890 self.assertEqual(A.reported, 2)
3891 self.assertEqual(B.reported, 2)
3892
James E. Blair8f78d882015-02-05 08:51:37 -08003893 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3894 '2,1 1,1')
3895
James E. Blairec056492016-07-22 09:45:56 -07003896 @skip("Disabled for early v3 development")
James E. Blair8f78d882015-02-05 08:51:37 -08003897 def test_crd_branch(self):
3898 "Test cross-repo dependencies in multiple branches"
3899 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3900 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3901 C = self.fake_gerrit.addFakeChange('org/project2', 'mp', 'C')
3902 C.data['id'] = B.data['id']
3903 A.addApproval('CRVW', 2)
3904 B.addApproval('CRVW', 2)
3905 C.addApproval('CRVW', 2)
3906
3907 # A Depends-On: B+C
3908 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3909 A.subject, B.data['id'])
3910
3911 self.worker.hold_jobs_in_build = True
3912 B.addApproval('APRV', 1)
3913 C.addApproval('APRV', 1)
3914 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3915 self.waitUntilSettled()
3916
3917 self.worker.release('.*-merge')
3918 self.waitUntilSettled()
3919 self.worker.release('.*-merge')
3920 self.waitUntilSettled()
3921 self.worker.release('.*-merge')
3922 self.waitUntilSettled()
3923 self.worker.hold_jobs_in_build = False
3924 self.worker.release()
3925 self.waitUntilSettled()
3926
3927 self.assertEqual(A.data['status'], 'MERGED')
3928 self.assertEqual(B.data['status'], 'MERGED')
3929 self.assertEqual(C.data['status'], 'MERGED')
3930 self.assertEqual(A.reported, 2)
3931 self.assertEqual(B.reported, 2)
3932 self.assertEqual(C.reported, 2)
3933
3934 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3935 '2,1 3,1 1,1')
3936
James E. Blairec056492016-07-22 09:45:56 -07003937 @skip("Disabled for early v3 development")
James E. Blair8f78d882015-02-05 08:51:37 -08003938 def test_crd_multiline(self):
3939 "Test multiple depends-on lines in commit"
3940 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3941 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3942 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
3943 A.addApproval('CRVW', 2)
3944 B.addApproval('CRVW', 2)
3945 C.addApproval('CRVW', 2)
3946
3947 # A Depends-On: B+C
3948 A.data['commitMessage'] = '%s\n\nDepends-On: %s\nDepends-On: %s\n' % (
3949 A.subject, B.data['id'], C.data['id'])
3950
3951 self.worker.hold_jobs_in_build = True
3952 B.addApproval('APRV', 1)
3953 C.addApproval('APRV', 1)
3954 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3955 self.waitUntilSettled()
3956
3957 self.worker.release('.*-merge')
3958 self.waitUntilSettled()
3959 self.worker.release('.*-merge')
3960 self.waitUntilSettled()
3961 self.worker.release('.*-merge')
3962 self.waitUntilSettled()
3963 self.worker.hold_jobs_in_build = False
3964 self.worker.release()
3965 self.waitUntilSettled()
3966
3967 self.assertEqual(A.data['status'], 'MERGED')
3968 self.assertEqual(B.data['status'], 'MERGED')
3969 self.assertEqual(C.data['status'], 'MERGED')
3970 self.assertEqual(A.reported, 2)
3971 self.assertEqual(B.reported, 2)
3972 self.assertEqual(C.reported, 2)
3973
3974 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3975 '2,1 3,1 1,1')
James E. Blair5ee24252014-12-30 10:12:29 -08003976
James E. Blairec056492016-07-22 09:45:56 -07003977 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08003978 def test_crd_unshared_gate(self):
3979 "Test cross-repo dependencies in unshared gate queues"
3980 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3981 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3982 A.addApproval('CRVW', 2)
3983 B.addApproval('CRVW', 2)
3984
3985 # A Depends-On: B
3986 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3987 A.subject, B.data['id'])
3988
3989 # A and B do not share a queue, make sure that A is unable to
3990 # enqueue B (and therefore, A is unable to be enqueued).
3991 B.addApproval('APRV', 1)
3992 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3993 self.waitUntilSettled()
3994
3995 self.assertEqual(A.data['status'], 'NEW')
3996 self.assertEqual(B.data['status'], 'NEW')
3997 self.assertEqual(A.reported, 0)
3998 self.assertEqual(B.reported, 0)
3999 self.assertEqual(len(self.history), 0)
4000
4001 # Enqueue and merge B alone.
4002 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
4003 self.waitUntilSettled()
4004
4005 self.assertEqual(B.data['status'], 'MERGED')
4006 self.assertEqual(B.reported, 2)
4007
4008 # Now that B is merged, A should be able to be enqueued and
4009 # merged.
4010 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4011 self.waitUntilSettled()
4012
4013 self.assertEqual(A.data['status'], 'MERGED')
4014 self.assertEqual(A.reported, 2)
4015
James E. Blairec056492016-07-22 09:45:56 -07004016 @skip("Disabled for early v3 development")
James E. Blair96698e22015-04-02 07:48:21 -07004017 def test_crd_gate_reverse(self):
4018 "Test reverse cross-repo dependencies"
4019 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4020 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4021 A.addApproval('CRVW', 2)
4022 B.addApproval('CRVW', 2)
4023
4024 # A Depends-On: B
4025
4026 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4027 A.subject, B.data['id'])
4028
4029 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4030 self.waitUntilSettled()
4031
4032 self.assertEqual(A.data['status'], 'NEW')
4033 self.assertEqual(B.data['status'], 'NEW')
4034
4035 self.worker.hold_jobs_in_build = True
4036 A.addApproval('APRV', 1)
4037 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
4038 self.waitUntilSettled()
4039
4040 self.worker.release('.*-merge')
4041 self.waitUntilSettled()
4042 self.worker.release('.*-merge')
4043 self.waitUntilSettled()
4044 self.worker.hold_jobs_in_build = False
4045 self.worker.release()
4046 self.waitUntilSettled()
4047
4048 self.assertEqual(A.data['status'], 'MERGED')
4049 self.assertEqual(B.data['status'], 'MERGED')
4050 self.assertEqual(A.reported, 2)
4051 self.assertEqual(B.reported, 2)
4052
4053 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
4054 '2,1 1,1')
4055
James E. Blairec056492016-07-22 09:45:56 -07004056 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08004057 def test_crd_cycle(self):
4058 "Test cross-repo dependency cycles"
4059 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4060 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4061 A.addApproval('CRVW', 2)
4062 B.addApproval('CRVW', 2)
4063
4064 # A -> B -> A (via commit-depends)
4065
4066 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4067 A.subject, B.data['id'])
4068 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4069 B.subject, A.data['id'])
4070
4071 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4072 self.waitUntilSettled()
4073
4074 self.assertEqual(A.reported, 0)
4075 self.assertEqual(B.reported, 0)
4076 self.assertEqual(A.data['status'], 'NEW')
4077 self.assertEqual(B.data['status'], 'NEW')
James E. Blairbfb8e042014-12-30 17:01:44 -08004078
James E. Blairec056492016-07-22 09:45:56 -07004079 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004080 def test_crd_gate_unknown(self):
4081 "Test unknown projects in dependent pipeline"
4082 self.init_repo("org/unknown")
4083 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4084 B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'B')
4085 A.addApproval('CRVW', 2)
4086 B.addApproval('CRVW', 2)
4087
4088 # A Depends-On: B
4089 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4090 A.subject, B.data['id'])
4091
4092 B.addApproval('APRV', 1)
4093 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4094 self.waitUntilSettled()
4095
4096 # Unknown projects cannot share a queue with any other
4097 # since they don't have common jobs with any other (they have no jobs).
4098 # Changes which depend on unknown project changes
4099 # should not be processed in dependent pipeline
4100 self.assertEqual(A.data['status'], 'NEW')
4101 self.assertEqual(B.data['status'], 'NEW')
4102 self.assertEqual(A.reported, 0)
4103 self.assertEqual(B.reported, 0)
4104 self.assertEqual(len(self.history), 0)
4105
4106 # Simulate change B being gated outside this layout
4107 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
4108 B.setMerged()
4109 self.waitUntilSettled()
4110 self.assertEqual(len(self.history), 0)
4111
4112 # Now that B is merged, A should be able to be enqueued and
4113 # merged.
4114 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4115 self.waitUntilSettled()
4116
4117 self.assertEqual(A.data['status'], 'MERGED')
4118 self.assertEqual(A.reported, 2)
4119 self.assertEqual(B.data['status'], 'MERGED')
4120 self.assertEqual(B.reported, 0)
4121
James E. Blairec056492016-07-22 09:45:56 -07004122 @skip("Disabled for early v3 development")
James E. Blairbfb8e042014-12-30 17:01:44 -08004123 def test_crd_check(self):
4124 "Test cross-repo dependencies in independent pipelines"
4125
4126 self.gearman_server.hold_jobs_in_queue = True
4127 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4128 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4129
4130 # A Depends-On: B
4131 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4132 A.subject, B.data['id'])
4133
4134 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4135 self.waitUntilSettled()
4136
4137 queue = self.gearman_server.getQueue()
4138 ref = self.getParameter(queue[-1], 'ZUUL_REF')
4139 self.gearman_server.hold_jobs_in_queue = False
4140 self.gearman_server.release()
4141 self.waitUntilSettled()
4142
4143 path = os.path.join(self.git_root, "org/project1")
4144 repo = git.Repo(path)
4145 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4146 repo_messages.reverse()
4147 correct_messages = ['initial commit', 'A-1']
4148 self.assertEqual(repo_messages, correct_messages)
4149
4150 path = os.path.join(self.git_root, "org/project2")
4151 repo = git.Repo(path)
4152 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4153 repo_messages.reverse()
4154 correct_messages = ['initial commit', 'B-1']
4155 self.assertEqual(repo_messages, correct_messages)
4156
4157 self.assertEqual(A.data['status'], 'NEW')
4158 self.assertEqual(B.data['status'], 'NEW')
4159 self.assertEqual(A.reported, 1)
4160 self.assertEqual(B.reported, 0)
4161
4162 self.assertEqual(self.history[0].changes, '2,1 1,1')
4163 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
James E. Blair8f78d882015-02-05 08:51:37 -08004164
James E. Blairec056492016-07-22 09:45:56 -07004165 @skip("Disabled for early v3 development")
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004166 def test_crd_check_git_depends(self):
4167 "Test single-repo dependencies in independent pipelines"
James E. Blairb8c16472015-05-05 14:55:26 -07004168 self.gearman_server.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004169 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4170 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4171
4172 # Add two git-dependent changes and make sure they both report
4173 # success.
4174 B.setDependsOn(A, 1)
4175 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4176 self.waitUntilSettled()
4177 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4178 self.waitUntilSettled()
4179
James E. Blairb8c16472015-05-05 14:55:26 -07004180 self.orderedRelease()
4181 self.gearman_server.hold_jobs_in_build = False
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004182 self.waitUntilSettled()
4183
4184 self.assertEqual(A.data['status'], 'NEW')
4185 self.assertEqual(B.data['status'], 'NEW')
4186 self.assertEqual(A.reported, 1)
4187 self.assertEqual(B.reported, 1)
4188
4189 self.assertEqual(self.history[0].changes, '1,1')
4190 self.assertEqual(self.history[-1].changes, '1,1 2,1')
4191 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
4192
4193 self.assertIn('Build succeeded', A.messages[0])
4194 self.assertIn('Build succeeded', B.messages[0])
4195
James E. Blairec056492016-07-22 09:45:56 -07004196 @skip("Disabled for early v3 development")
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004197 def test_crd_check_duplicate(self):
4198 "Test duplicate check in independent pipelines"
James E. Blair1e263032015-05-07 14:35:34 -07004199 self.worker.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004200 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4201 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4202 check_pipeline = self.sched.layout.pipelines['check']
4203
4204 # Add two git-dependent changes...
4205 B.setDependsOn(A, 1)
4206 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4207 self.waitUntilSettled()
4208 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4209
4210 # ...make sure the live one is not duplicated...
4211 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4212 self.waitUntilSettled()
4213 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4214
4215 # ...but the non-live one is able to be.
4216 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4217 self.waitUntilSettled()
4218 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4219
Clark Boylandd849822015-03-02 12:38:14 -08004220 # Release jobs in order to avoid races with change A jobs
4221 # finishing before change B jobs.
James E. Blaird7650852015-05-07 15:47:37 -07004222 self.orderedRelease()
James E. Blair1e263032015-05-07 14:35:34 -07004223 self.worker.hold_jobs_in_build = False
4224 self.worker.release()
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004225 self.waitUntilSettled()
4226
4227 self.assertEqual(A.data['status'], 'NEW')
4228 self.assertEqual(B.data['status'], 'NEW')
4229 self.assertEqual(A.reported, 1)
4230 self.assertEqual(B.reported, 1)
4231
4232 self.assertEqual(self.history[0].changes, '1,1 2,1')
4233 self.assertEqual(self.history[1].changes, '1,1')
4234 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
4235
4236 self.assertIn('Build succeeded', A.messages[0])
4237 self.assertIn('Build succeeded', B.messages[0])
4238
James E. Blairec056492016-07-22 09:45:56 -07004239 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004240 def _test_crd_check_reconfiguration(self, project1, project2):
James E. Blair8f78d882015-02-05 08:51:37 -08004241 "Test cross-repo dependencies re-enqueued in independent pipelines"
4242
4243 self.gearman_server.hold_jobs_in_queue = True
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004244 A = self.fake_gerrit.addFakeChange(project1, 'master', 'A')
4245 B = self.fake_gerrit.addFakeChange(project2, 'master', 'B')
James E. Blair8f78d882015-02-05 08:51:37 -08004246
4247 # A Depends-On: B
4248 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4249 A.subject, B.data['id'])
4250
4251 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4252 self.waitUntilSettled()
4253
4254 self.sched.reconfigure(self.config)
4255
4256 # Make sure the items still share a change queue, and the
4257 # first one is not live.
4258 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 1)
4259 queue = self.sched.layout.pipelines['check'].queues[0]
4260 first_item = queue.queue[0]
4261 for item in queue.queue:
4262 self.assertEqual(item.queue, first_item.queue)
4263 self.assertFalse(first_item.live)
4264 self.assertTrue(queue.queue[1].live)
4265
4266 self.gearman_server.hold_jobs_in_queue = False
4267 self.gearman_server.release()
4268 self.waitUntilSettled()
4269
4270 self.assertEqual(A.data['status'], 'NEW')
4271 self.assertEqual(B.data['status'], 'NEW')
4272 self.assertEqual(A.reported, 1)
4273 self.assertEqual(B.reported, 0)
4274
4275 self.assertEqual(self.history[0].changes, '2,1 1,1')
4276 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
James E. Blair17dd6772015-02-09 14:45:18 -08004277
James E. Blairec056492016-07-22 09:45:56 -07004278 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004279 def test_crd_check_reconfiguration(self):
4280 self._test_crd_check_reconfiguration('org/project1', 'org/project2')
4281
James E. Blairec056492016-07-22 09:45:56 -07004282 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004283 def test_crd_undefined_project(self):
4284 """Test that undefined projects in dependencies are handled for
4285 independent pipelines"""
4286 # It's a hack for fake gerrit,
4287 # as it implies repo creation upon the creation of any change
4288 self.init_repo("org/unknown")
4289 self._test_crd_check_reconfiguration('org/project1', 'org/unknown')
4290
James E. Blairec056492016-07-22 09:45:56 -07004291 @skip("Disabled for early v3 development")
James E. Blair17dd6772015-02-09 14:45:18 -08004292 def test_crd_check_ignore_dependencies(self):
4293 "Test cross-repo dependencies can be ignored"
James E. Blairf84026c2015-12-08 16:11:46 -08004294 self.updateConfigLayout(
4295 'tests/fixtures/layout-ignore-dependencies.yaml')
James E. Blair17dd6772015-02-09 14:45:18 -08004296 self.sched.reconfigure(self.config)
4297 self.registerJobs()
4298
4299 self.gearman_server.hold_jobs_in_queue = True
4300 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4301 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4302 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
4303
4304 # A Depends-On: B
4305 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4306 A.subject, B.data['id'])
4307 # C git-depends on B
4308 C.setDependsOn(B, 1)
4309 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4310 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4311 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4312 self.waitUntilSettled()
4313
4314 # Make sure none of the items share a change queue, and all
4315 # are live.
4316 check_pipeline = self.sched.layout.pipelines['check']
4317 self.assertEqual(len(check_pipeline.queues), 3)
4318 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4319 for item in check_pipeline.getAllItems():
4320 self.assertTrue(item.live)
4321
4322 self.gearman_server.hold_jobs_in_queue = False
4323 self.gearman_server.release()
4324 self.waitUntilSettled()
4325
4326 self.assertEqual(A.data['status'], 'NEW')
4327 self.assertEqual(B.data['status'], 'NEW')
4328 self.assertEqual(C.data['status'], 'NEW')
4329 self.assertEqual(A.reported, 1)
4330 self.assertEqual(B.reported, 1)
4331 self.assertEqual(C.reported, 1)
4332
4333 # Each job should have tested exactly one change
4334 for job in self.history:
4335 self.assertEqual(len(job.changes.split()), 1)
James E. Blair96698e22015-04-02 07:48:21 -07004336
James E. Blairec056492016-07-22 09:45:56 -07004337 @skip("Disabled for early v3 development")
James E. Blair96698e22015-04-02 07:48:21 -07004338 def test_crd_check_transitive(self):
4339 "Test transitive cross-repo dependencies"
4340 # Specifically, if A -> B -> C, and C gets a new patchset and
4341 # A gets a new patchset, ensure the test of A,2 includes B,1
4342 # and C,2 (not C,1 which would indicate stale data in the
4343 # cache for B).
4344 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4345 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4346 C = self.fake_gerrit.addFakeChange('org/project3', 'master', 'C')
4347
4348 # A Depends-On: B
4349 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4350 A.subject, B.data['id'])
4351
4352 # B Depends-On: C
4353 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4354 B.subject, C.data['id'])
4355
4356 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4357 self.waitUntilSettled()
4358 self.assertEqual(self.history[-1].changes, '3,1 2,1 1,1')
4359
4360 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4361 self.waitUntilSettled()
4362 self.assertEqual(self.history[-1].changes, '3,1 2,1')
4363
4364 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4365 self.waitUntilSettled()
4366 self.assertEqual(self.history[-1].changes, '3,1')
4367
4368 C.addPatchset()
4369 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(2))
4370 self.waitUntilSettled()
4371 self.assertEqual(self.history[-1].changes, '3,2')
4372
4373 A.addPatchset()
4374 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
4375 self.waitUntilSettled()
4376 self.assertEqual(self.history[-1].changes, '3,2 2,1 1,2')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004377
James E. Blairec056492016-07-22 09:45:56 -07004378 @skip("Disabled for early v3 development")
James E. Blair92464a22016-04-05 10:21:26 -07004379 def test_crd_cycle_join(self):
4380 "Test an updated change creates a cycle"
4381 A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A')
4382
4383 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4384 self.waitUntilSettled()
4385
4386 # Create B->A
4387 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4388 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4389 B.subject, A.data['id'])
4390 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4391 self.waitUntilSettled()
4392
4393 # Update A to add A->B (a cycle).
4394 A.addPatchset()
4395 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4396 A.subject, B.data['id'])
4397 # Normally we would submit the patchset-created event for
4398 # processing here, however, we have no way of noting whether
4399 # the dependency cycle detection correctly raised an
4400 # exception, so instead, we reach into the source driver and
4401 # call the method that would ultimately be called by the event
4402 # processing.
4403
4404 source = self.sched.layout.pipelines['gate'].source
4405 with testtools.ExpectedException(
4406 Exception, "Dependency cycle detected"):
4407 source._getChange(u'1', u'2', True)
4408 self.log.debug("Got expected dependency cycle exception")
4409
4410 # Now if we update B to remove the depends-on, everything
4411 # should be okay. B; A->B
4412
4413 B.addPatchset()
4414 B.data['commitMessage'] = '%s\n' % (B.subject,)
4415 source._getChange(u'1', u'2', True)
4416 source._getChange(u'2', u'2', True)
4417
James E. Blairec056492016-07-22 09:45:56 -07004418 @skip("Disabled for early v3 development")
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004419 def test_disable_at(self):
4420 "Test a pipeline will only report to the disabled trigger when failing"
4421
James E. Blairf84026c2015-12-08 16:11:46 -08004422 self.updateConfigLayout(
4423 'tests/fixtures/layout-disable-at.yaml')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004424 self.sched.reconfigure(self.config)
4425
4426 self.assertEqual(3, self.sched.layout.pipelines['check'].disable_at)
4427 self.assertEqual(
4428 0, self.sched.layout.pipelines['check']._consecutive_failures)
4429 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4430
4431 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4432 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
4433 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
4434 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
4435 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
4436 F = self.fake_gerrit.addFakeChange('org/project', 'master', 'F')
4437 G = self.fake_gerrit.addFakeChange('org/project', 'master', 'G')
4438 H = self.fake_gerrit.addFakeChange('org/project', 'master', 'H')
4439 I = self.fake_gerrit.addFakeChange('org/project', 'master', 'I')
4440 J = self.fake_gerrit.addFakeChange('org/project', 'master', 'J')
4441 K = self.fake_gerrit.addFakeChange('org/project', 'master', 'K')
4442
4443 self.worker.addFailTest('project-test1', A)
4444 self.worker.addFailTest('project-test1', B)
4445 # Let C pass, resetting the counter
4446 self.worker.addFailTest('project-test1', D)
4447 self.worker.addFailTest('project-test1', E)
4448 self.worker.addFailTest('project-test1', F)
4449 self.worker.addFailTest('project-test1', G)
4450 self.worker.addFailTest('project-test1', H)
4451 # I also passes but should only report to the disabled reporters
4452 self.worker.addFailTest('project-test1', J)
4453 self.worker.addFailTest('project-test1', K)
4454
4455 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4456 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4457 self.waitUntilSettled()
4458
4459 self.assertEqual(
4460 2, self.sched.layout.pipelines['check']._consecutive_failures)
4461 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4462
4463 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4464 self.waitUntilSettled()
4465
4466 self.assertEqual(
4467 0, self.sched.layout.pipelines['check']._consecutive_failures)
4468 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4469
4470 self.fake_gerrit.addEvent(D.getPatchsetCreatedEvent(1))
4471 self.fake_gerrit.addEvent(E.getPatchsetCreatedEvent(1))
4472 self.fake_gerrit.addEvent(F.getPatchsetCreatedEvent(1))
4473 self.waitUntilSettled()
4474
4475 # We should be disabled now
4476 self.assertEqual(
4477 3, self.sched.layout.pipelines['check']._consecutive_failures)
4478 self.assertTrue(self.sched.layout.pipelines['check']._disabled)
4479
4480 # We need to wait between each of these patches to make sure the
4481 # smtp messages come back in an expected order
4482 self.fake_gerrit.addEvent(G.getPatchsetCreatedEvent(1))
4483 self.waitUntilSettled()
4484 self.fake_gerrit.addEvent(H.getPatchsetCreatedEvent(1))
4485 self.waitUntilSettled()
4486 self.fake_gerrit.addEvent(I.getPatchsetCreatedEvent(1))
4487 self.waitUntilSettled()
4488
4489 # The first 6 (ABCDEF) jobs should have reported back to gerrt thus
4490 # leaving a message on each change
4491 self.assertEqual(1, len(A.messages))
4492 self.assertIn('Build failed.', A.messages[0])
4493 self.assertEqual(1, len(B.messages))
4494 self.assertIn('Build failed.', B.messages[0])
4495 self.assertEqual(1, len(C.messages))
4496 self.assertIn('Build succeeded.', C.messages[0])
4497 self.assertEqual(1, len(D.messages))
4498 self.assertIn('Build failed.', D.messages[0])
4499 self.assertEqual(1, len(E.messages))
4500 self.assertIn('Build failed.', E.messages[0])
4501 self.assertEqual(1, len(F.messages))
4502 self.assertIn('Build failed.', F.messages[0])
4503
4504 # The last 3 (GHI) would have only reported via smtp.
4505 self.assertEqual(3, len(self.smtp_messages))
4506 self.assertEqual(0, len(G.messages))
4507 self.assertIn('Build failed.', self.smtp_messages[0]['body'])
4508 self.assertIn('/7/1/check', self.smtp_messages[0]['body'])
4509 self.assertEqual(0, len(H.messages))
4510 self.assertIn('Build failed.', self.smtp_messages[1]['body'])
4511 self.assertIn('/8/1/check', self.smtp_messages[1]['body'])
4512 self.assertEqual(0, len(I.messages))
4513 self.assertIn('Build succeeded.', self.smtp_messages[2]['body'])
4514 self.assertIn('/9/1/check', self.smtp_messages[2]['body'])
4515
4516 # Now reload the configuration (simulate a HUP) to check the pipeline
4517 # comes out of disabled
4518 self.sched.reconfigure(self.config)
4519
4520 self.assertEqual(3, self.sched.layout.pipelines['check'].disable_at)
4521 self.assertEqual(
4522 0, self.sched.layout.pipelines['check']._consecutive_failures)
4523 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4524
4525 self.fake_gerrit.addEvent(J.getPatchsetCreatedEvent(1))
4526 self.fake_gerrit.addEvent(K.getPatchsetCreatedEvent(1))
4527 self.waitUntilSettled()
4528
4529 self.assertEqual(
4530 2, self.sched.layout.pipelines['check']._consecutive_failures)
4531 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4532
4533 # J and K went back to gerrit
4534 self.assertEqual(1, len(J.messages))
4535 self.assertIn('Build failed.', J.messages[0])
4536 self.assertEqual(1, len(K.messages))
4537 self.assertIn('Build failed.', K.messages[0])
4538 # No more messages reported via smtp
4539 self.assertEqual(3, len(self.smtp_messages))
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004540
James E. Blairec056492016-07-22 09:45:56 -07004541 @skip("Disabled for early v3 development")
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004542 def test_success_pattern(self):
4543 "Ensure bad build params are ignored"
4544
4545 # Use SMTP reporter to grab the result message easier
4546 self.init_repo("org/docs")
4547 self.config.set('zuul', 'layout_config',
4548 'tests/fixtures/layout-success-pattern.yaml')
4549 self.sched.reconfigure(self.config)
4550 self.worker.hold_jobs_in_build = True
4551 self.registerJobs()
4552
4553 A = self.fake_gerrit.addFakeChange('org/docs', 'master', 'A')
4554 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4555 self.waitUntilSettled()
4556
4557 # Grab build id
4558 self.assertEqual(len(self.builds), 1)
4559 uuid = self.builds[0].unique[:7]
4560
4561 self.worker.hold_jobs_in_build = False
4562 self.worker.release()
4563 self.waitUntilSettled()
4564
4565 self.assertEqual(len(self.smtp_messages), 1)
4566 body = self.smtp_messages[0]['body'].splitlines()
4567 self.assertEqual('Build succeeded.', body[0])
4568
4569 self.assertIn(
4570 '- docs-draft-test http://docs-draft.example.org/1/1/1/check/'
4571 'docs-draft-test/%s/publish-docs/' % uuid,
4572 body[2])
4573 self.assertIn(
4574 '- docs-draft-test2 https://server/job/docs-draft-test2/1/',
4575 body[3])