blob: b32f368344339c9eecbbad3f055efddfc037e628 [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. Blairc8a1e052014-02-25 09:29:26 -08002265 def test_queue_names(self):
2266 "Test shared change queue names"
2267 project1 = self.sched.layout.projects['org/project1']
2268 project2 = self.sched.layout.projects['org/project2']
2269 q1 = self.sched.layout.pipelines['gate'].getQueue(project1)
2270 q2 = self.sched.layout.pipelines['gate'].getQueue(project2)
2271 self.assertEqual(q1.name, 'integration')
2272 self.assertEqual(q2.name, 'integration')
2273
James E. Blairf84026c2015-12-08 16:11:46 -08002274 self.updateConfigLayout(
2275 'tests/fixtures/layout-bad-queue.yaml')
James E. Blairc8a1e052014-02-25 09:29:26 -08002276 with testtools.ExpectedException(
2277 Exception, "More than one name assigned to change queue"):
2278 self.sched.reconfigure(self.config)
2279
James E. Blairec056492016-07-22 09:45:56 -07002280 @skip("Disabled for early v3 development")
James E. Blair64ed6f22013-07-10 14:07:23 -07002281 def test_queue_precedence(self):
2282 "Test that queue precedence works"
2283
2284 self.gearman_server.hold_jobs_in_queue = True
James E. Blair8de58bd2013-07-18 16:23:33 -07002285 self.worker.hold_jobs_in_build = True
James E. Blair64ed6f22013-07-10 14:07:23 -07002286 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2287 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2288 A.addApproval('CRVW', 2)
2289 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2290
2291 self.waitUntilSettled()
2292 self.gearman_server.hold_jobs_in_queue = False
2293 self.gearman_server.release()
2294 self.waitUntilSettled()
2295
James E. Blair8de58bd2013-07-18 16:23:33 -07002296 # Run one build at a time to ensure non-race order:
James E. Blairb8c16472015-05-05 14:55:26 -07002297 self.orderedRelease()
James E. Blair8de58bd2013-07-18 16:23:33 -07002298 self.worker.hold_jobs_in_build = False
2299 self.waitUntilSettled()
2300
James E. Blair64ed6f22013-07-10 14:07:23 -07002301 self.log.debug(self.history)
2302 self.assertEqual(self.history[0].pipeline, 'gate')
2303 self.assertEqual(self.history[1].pipeline, 'check')
2304 self.assertEqual(self.history[2].pipeline, 'gate')
2305 self.assertEqual(self.history[3].pipeline, 'gate')
2306 self.assertEqual(self.history[4].pipeline, 'check')
2307 self.assertEqual(self.history[5].pipeline, 'check')
2308
James E. Blairec056492016-07-22 09:45:56 -07002309 @skip("Disabled for early v3 development")
Clark Boylana5edbe42014-06-03 16:39:10 -07002310 def test_json_status(self):
James E. Blair1843a552013-07-03 14:19:52 -07002311 "Test that we can retrieve JSON status info"
2312 self.worker.hold_jobs_in_build = True
2313 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2314 A.addApproval('CRVW', 2)
2315 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2316 self.waitUntilSettled()
2317
James E. Blairb7273ef2016-04-19 08:58:51 -07002318 self.worker.release('project-merge')
2319 self.waitUntilSettled()
2320
James E. Blair1843a552013-07-03 14:19:52 -07002321 port = self.webapp.server.socket.getsockname()[1]
2322
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002323 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2324 f = urllib.request.urlopen(req)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002325 headers = f.info()
2326 self.assertIn('Content-Length', headers)
2327 self.assertIn('Content-Type', headers)
Sachi Kingdc963fc2016-03-23 16:00:33 +11002328 self.assertIsNotNone(re.match('^application/json(; charset=UTF-8)?$',
2329 headers['Content-Type']))
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002330 self.assertIn('Access-Control-Allow-Origin', headers)
2331 self.assertIn('Cache-Control', headers)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002332 self.assertIn('Last-Modified', headers)
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002333 self.assertIn('Expires', headers)
James E. Blair1843a552013-07-03 14:19:52 -07002334 data = f.read()
2335
2336 self.worker.hold_jobs_in_build = False
2337 self.worker.release()
2338 self.waitUntilSettled()
2339
2340 data = json.loads(data)
James E. Blairb7273ef2016-04-19 08:58:51 -07002341 status_jobs = []
James E. Blair1843a552013-07-03 14:19:52 -07002342 for p in data['pipelines']:
2343 for q in p['change_queues']:
James E. Blairbfb8e042014-12-30 17:01:44 -08002344 if p['name'] in ['gate', 'conflict']:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002345 self.assertEqual(q['window'], 20)
2346 else:
2347 self.assertEqual(q['window'], 0)
James E. Blair1843a552013-07-03 14:19:52 -07002348 for head in q['heads']:
2349 for change in head:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002350 self.assertTrue(change['active'])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002351 self.assertEqual(change['id'], '1,1')
James E. Blair1843a552013-07-03 14:19:52 -07002352 for job in change['jobs']:
James E. Blairb7273ef2016-04-19 08:58:51 -07002353 status_jobs.append(job)
2354 self.assertEqual('project-merge', status_jobs[0]['name'])
2355 self.assertEqual('https://server/job/project-merge/0/',
2356 status_jobs[0]['url'])
2357 self.assertEqual('http://logs.example.com/1/1/gate/project-merge/0',
2358 status_jobs[0]['report_url'])
2359
2360 self.assertEqual('project-test1', status_jobs[1]['name'])
2361 self.assertEqual('https://server/job/project-test1/1/',
2362 status_jobs[1]['url'])
2363 self.assertEqual('http://logs.example.com/1/1/gate/project-test1/1',
2364 status_jobs[1]['report_url'])
2365
2366 self.assertEqual('project-test2', status_jobs[2]['name'])
2367 self.assertEqual('https://server/job/project-test2/2/',
2368 status_jobs[2]['url'])
2369 self.assertEqual('http://logs.example.com/1/1/gate/project-test2/2',
2370 status_jobs[2]['report_url'])
James E. Blair1843a552013-07-03 14:19:52 -07002371
James E. Blairec056492016-07-22 09:45:56 -07002372 @skip("Disabled for early v3 development")
James E. Blairc3d428e2013-12-03 15:06:48 -08002373 def test_merging_queues(self):
2374 "Test that transitively-connected change queues are merged"
James E. Blairf84026c2015-12-08 16:11:46 -08002375 self.updateConfigLayout(
2376 'tests/fixtures/layout-merge-queues.yaml')
James E. Blairc3d428e2013-12-03 15:06:48 -08002377 self.sched.reconfigure(self.config)
2378 self.assertEqual(len(self.sched.layout.pipelines['gate'].queues), 1)
2379
James E. Blairec056492016-07-22 09:45:56 -07002380 @skip("Disabled for early v3 development")
James E. Blairaf17a972016-02-03 15:07:18 -08002381 def test_mutex(self):
2382 "Test job mutexes"
2383 self.config.set('zuul', 'layout_config',
2384 'tests/fixtures/layout-mutex.yaml')
2385 self.sched.reconfigure(self.config)
2386
2387 self.worker.hold_jobs_in_build = True
2388 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2389 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2390 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2391
2392 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2393 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2394 self.waitUntilSettled()
2395 self.assertEqual(len(self.builds), 3)
2396 self.assertEqual(self.builds[0].name, 'project-test1')
2397 self.assertEqual(self.builds[1].name, 'mutex-one')
2398 self.assertEqual(self.builds[2].name, 'project-test1')
2399
2400 self.worker.release('mutex-one')
2401 self.waitUntilSettled()
2402
2403 self.assertEqual(len(self.builds), 3)
2404 self.assertEqual(self.builds[0].name, 'project-test1')
2405 self.assertEqual(self.builds[1].name, 'project-test1')
2406 self.assertEqual(self.builds[2].name, 'mutex-two')
2407 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2408
2409 self.worker.release('mutex-two')
2410 self.waitUntilSettled()
2411
2412 self.assertEqual(len(self.builds), 3)
2413 self.assertEqual(self.builds[0].name, 'project-test1')
2414 self.assertEqual(self.builds[1].name, 'project-test1')
2415 self.assertEqual(self.builds[2].name, 'mutex-one')
2416 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2417
2418 self.worker.release('mutex-one')
2419 self.waitUntilSettled()
2420
2421 self.assertEqual(len(self.builds), 3)
2422 self.assertEqual(self.builds[0].name, 'project-test1')
2423 self.assertEqual(self.builds[1].name, 'project-test1')
2424 self.assertEqual(self.builds[2].name, 'mutex-two')
2425 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2426
2427 self.worker.release('mutex-two')
2428 self.waitUntilSettled()
2429
2430 self.assertEqual(len(self.builds), 2)
2431 self.assertEqual(self.builds[0].name, 'project-test1')
2432 self.assertEqual(self.builds[1].name, 'project-test1')
2433 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2434
2435 self.worker.hold_jobs_in_build = False
2436 self.worker.release()
2437
2438 self.waitUntilSettled()
2439 self.assertEqual(len(self.builds), 0)
2440
2441 self.assertEqual(A.reported, 1)
2442 self.assertEqual(B.reported, 1)
2443 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2444
James E. Blairec056492016-07-22 09:45:56 -07002445 @skip("Disabled for early v3 development")
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002446 def test_node_label(self):
2447 "Test that a job runs on a specific node label"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002448 self.worker.registerFunction('build:node-project-test1:debian')
2449
2450 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
2451 A.addApproval('CRVW', 2)
2452 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2453 self.waitUntilSettled()
James E. Blair4ca985f2013-05-30 12:27:43 -07002454
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002455 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2456 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2457 'debian')
2458 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
James E. Blaircdccd972013-07-01 12:10:22 -07002459
James E. Blairec056492016-07-22 09:45:56 -07002460 @skip("Disabled for early v3 development")
James E. Blaircdccd972013-07-01 12:10:22 -07002461 def test_live_reconfiguration(self):
2462 "Test that live reconfiguration works"
2463 self.worker.hold_jobs_in_build = True
2464 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2465 A.addApproval('CRVW', 2)
2466 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2467 self.waitUntilSettled()
2468
2469 self.sched.reconfigure(self.config)
2470
2471 self.worker.hold_jobs_in_build = False
2472 self.worker.release()
2473 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002474 self.assertEqual(self.getJobFromHistory('project-merge').result,
2475 'SUCCESS')
2476 self.assertEqual(self.getJobFromHistory('project-test1').result,
2477 'SUCCESS')
2478 self.assertEqual(self.getJobFromHistory('project-test2').result,
2479 'SUCCESS')
2480 self.assertEqual(A.data['status'], 'MERGED')
2481 self.assertEqual(A.reported, 2)
James E. Blair287c06d2013-07-24 10:39:30 -07002482
James E. Blairec056492016-07-22 09:45:56 -07002483 @skip("Disabled for early v3 development")
James E. Blair6bc782d2015-07-17 16:20:21 -07002484 def test_live_reconfiguration_merge_conflict(self):
2485 # A real-world bug: a change in a gate queue has a merge
2486 # conflict and a job is added to its project while it's
2487 # sitting in the queue. The job gets added to the change and
2488 # enqueued and the change gets stuck.
2489 self.worker.registerFunction('build:project-test3')
2490 self.worker.hold_jobs_in_build = True
2491
2492 # This change is fine. It's here to stop the queue long
2493 # enough for the next change to be subject to the
2494 # reconfiguration, as well as to provide a conflict for the
2495 # next change. This change will succeed and merge.
2496 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2497 A.addPatchset(['conflict'])
2498 A.addApproval('CRVW', 2)
James E. Blair6bc782d2015-07-17 16:20:21 -07002499
2500 # This change will be in merge conflict. During the
2501 # reconfiguration, we will add a job. We want to make sure
2502 # that doesn't cause it to get stuck.
2503 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2504 B.addPatchset(['conflict'])
2505 B.addApproval('CRVW', 2)
James E. Blair4eb21fa2015-07-27 14:56:47 -07002506
2507 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
James E. Blair6bc782d2015-07-17 16:20:21 -07002508 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2509
2510 self.waitUntilSettled()
2511
2512 # No jobs have run yet
2513 self.assertEqual(A.data['status'], 'NEW')
2514 self.assertEqual(A.reported, 1)
2515 self.assertEqual(B.data['status'], 'NEW')
2516 self.assertEqual(B.reported, 1)
2517 self.assertEqual(len(self.history), 0)
2518
2519 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002520 self.updateConfigLayout(
2521 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002522 self.sched.reconfigure(self.config)
2523 self.waitUntilSettled()
2524
2525 self.worker.hold_jobs_in_build = False
2526 self.worker.release()
2527 self.waitUntilSettled()
2528
2529 self.assertEqual(A.data['status'], 'MERGED')
2530 self.assertEqual(A.reported, 2)
2531 self.assertEqual(B.data['status'], 'NEW')
2532 self.assertEqual(B.reported, 2)
2533 self.assertEqual(self.getJobFromHistory('project-merge').result,
2534 'SUCCESS')
2535 self.assertEqual(self.getJobFromHistory('project-test1').result,
2536 'SUCCESS')
2537 self.assertEqual(self.getJobFromHistory('project-test2').result,
2538 'SUCCESS')
2539 self.assertEqual(self.getJobFromHistory('project-test3').result,
2540 'SUCCESS')
2541 self.assertEqual(len(self.history), 4)
2542
James E. Blairec056492016-07-22 09:45:56 -07002543 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002544 def test_live_reconfiguration_failed_root(self):
James E. Blair6bc782d2015-07-17 16:20:21 -07002545 # An extrapolation of test_live_reconfiguration_merge_conflict
2546 # that tests a job added to a job tree with a failed root does
2547 # not run.
2548 self.worker.registerFunction('build:project-test3')
2549 self.worker.hold_jobs_in_build = True
2550
2551 # This change is fine. It's here to stop the queue long
2552 # enough for the next change to be subject to the
2553 # reconfiguration. This change will succeed and merge.
2554 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2555 A.addPatchset(['conflict'])
2556 A.addApproval('CRVW', 2)
2557 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2558 self.waitUntilSettled()
2559 self.worker.release('.*-merge')
2560 self.waitUntilSettled()
2561
2562 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2563 self.worker.addFailTest('project-merge', B)
2564 B.addApproval('CRVW', 2)
2565 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2566 self.waitUntilSettled()
2567
2568 self.worker.release('.*-merge')
2569 self.waitUntilSettled()
2570
2571 # Both -merge jobs have run, but no others.
2572 self.assertEqual(A.data['status'], 'NEW')
2573 self.assertEqual(A.reported, 1)
2574 self.assertEqual(B.data['status'], 'NEW')
2575 self.assertEqual(B.reported, 1)
2576 self.assertEqual(self.history[0].result, 'SUCCESS')
2577 self.assertEqual(self.history[0].name, 'project-merge')
2578 self.assertEqual(self.history[1].result, 'FAILURE')
2579 self.assertEqual(self.history[1].name, 'project-merge')
2580 self.assertEqual(len(self.history), 2)
2581
2582 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002583 self.updateConfigLayout(
2584 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002585 self.sched.reconfigure(self.config)
2586 self.waitUntilSettled()
2587
2588 self.worker.hold_jobs_in_build = False
2589 self.worker.release()
2590 self.waitUntilSettled()
2591
2592 self.assertEqual(A.data['status'], 'MERGED')
2593 self.assertEqual(A.reported, 2)
2594 self.assertEqual(B.data['status'], 'NEW')
2595 self.assertEqual(B.reported, 2)
2596 self.assertEqual(self.history[0].result, 'SUCCESS')
2597 self.assertEqual(self.history[0].name, 'project-merge')
2598 self.assertEqual(self.history[1].result, 'FAILURE')
2599 self.assertEqual(self.history[1].name, 'project-merge')
2600 self.assertEqual(self.history[2].result, 'SUCCESS')
2601 self.assertEqual(self.history[3].result, 'SUCCESS')
2602 self.assertEqual(self.history[4].result, 'SUCCESS')
2603 self.assertEqual(len(self.history), 5)
2604
James E. Blairec056492016-07-22 09:45:56 -07002605 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002606 def test_live_reconfiguration_failed_job(self):
2607 # Test that a change with a removed failing job does not
2608 # disrupt reconfiguration. If a change has a failed job and
2609 # that job is removed during a reconfiguration, we observed a
2610 # bug where the code to re-set build statuses would run on
2611 # that build and raise an exception because the job no longer
2612 # existed.
2613 self.worker.hold_jobs_in_build = True
2614
2615 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2616
2617 # This change will fail and later be removed by the reconfiguration.
2618 self.worker.addFailTest('project-test1', A)
2619
2620 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2621 self.waitUntilSettled()
2622 self.worker.release('.*-merge')
2623 self.waitUntilSettled()
2624 self.worker.release('project-test1')
2625 self.waitUntilSettled()
2626
2627 self.assertEqual(A.data['status'], 'NEW')
2628 self.assertEqual(A.reported, 0)
2629
2630 self.assertEqual(self.getJobFromHistory('project-merge').result,
2631 'SUCCESS')
2632 self.assertEqual(self.getJobFromHistory('project-test1').result,
2633 'FAILURE')
2634 self.assertEqual(len(self.history), 2)
2635
2636 # Remove the test1 job.
James E. Blairf84026c2015-12-08 16:11:46 -08002637 self.updateConfigLayout(
2638 'tests/fixtures/layout-live-reconfiguration-failed-job.yaml')
James E. Blair400e8fd2015-07-30 17:44:45 -07002639 self.sched.reconfigure(self.config)
2640 self.waitUntilSettled()
2641
2642 self.worker.hold_jobs_in_build = False
2643 self.worker.release()
2644 self.waitUntilSettled()
2645
2646 self.assertEqual(self.getJobFromHistory('project-test2').result,
2647 'SUCCESS')
2648 self.assertEqual(self.getJobFromHistory('project-testfile').result,
2649 'SUCCESS')
2650 self.assertEqual(len(self.history), 4)
2651
2652 self.assertEqual(A.data['status'], 'NEW')
2653 self.assertEqual(A.reported, 1)
2654 self.assertIn('Build succeeded', A.messages[0])
2655 # Ensure the removed job was not included in the report.
2656 self.assertNotIn('project-test1', A.messages[0])
2657
James E. Blairec056492016-07-22 09:45:56 -07002658 @skip("Disabled for early v3 development")
James E. Blairfe707d12015-08-05 15:18:15 -07002659 def test_live_reconfiguration_shared_queue(self):
2660 # Test that a change with a failing job which was removed from
2661 # this project but otherwise still exists in the system does
2662 # not disrupt reconfiguration.
2663
2664 self.worker.hold_jobs_in_build = True
2665
2666 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2667
2668 self.worker.addFailTest('project1-project2-integration', A)
2669
2670 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2671 self.waitUntilSettled()
2672 self.worker.release('.*-merge')
2673 self.waitUntilSettled()
2674 self.worker.release('project1-project2-integration')
2675 self.waitUntilSettled()
2676
2677 self.assertEqual(A.data['status'], 'NEW')
2678 self.assertEqual(A.reported, 0)
2679
2680 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2681 'SUCCESS')
2682 self.assertEqual(self.getJobFromHistory(
2683 'project1-project2-integration').result, 'FAILURE')
2684 self.assertEqual(len(self.history), 2)
2685
2686 # Remove the integration job.
James E. Blairf84026c2015-12-08 16:11:46 -08002687 self.updateConfigLayout(
2688 'tests/fixtures/layout-live-reconfiguration-shared-queue.yaml')
James E. Blairfe707d12015-08-05 15:18:15 -07002689 self.sched.reconfigure(self.config)
2690 self.waitUntilSettled()
2691
2692 self.worker.hold_jobs_in_build = False
2693 self.worker.release()
2694 self.waitUntilSettled()
2695
2696 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2697 'SUCCESS')
2698 self.assertEqual(self.getJobFromHistory('project1-test1').result,
2699 'SUCCESS')
2700 self.assertEqual(self.getJobFromHistory('project1-test2').result,
2701 'SUCCESS')
2702 self.assertEqual(self.getJobFromHistory(
2703 'project1-project2-integration').result, 'FAILURE')
2704 self.assertEqual(len(self.history), 4)
2705
2706 self.assertEqual(A.data['status'], 'NEW')
2707 self.assertEqual(A.reported, 1)
2708 self.assertIn('Build succeeded', A.messages[0])
2709 # Ensure the removed job was not included in the report.
2710 self.assertNotIn('project1-project2-integration', A.messages[0])
2711
James E. Blairec056492016-07-22 09:45:56 -07002712 @skip("Disabled for early v3 development")
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002713 def test_double_live_reconfiguration_shared_queue(self):
2714 # This was a real-world regression. A change is added to
2715 # gate; a reconfigure happens, a second change which depends
2716 # on the first is added, and a second reconfiguration happens.
2717 # Ensure that both changes merge.
2718
2719 # A failure may indicate incorrect caching or cleaning up of
2720 # references during a reconfiguration.
2721 self.worker.hold_jobs_in_build = True
2722
2723 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2724 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2725 B.setDependsOn(A, 1)
2726 A.addApproval('CRVW', 2)
2727 B.addApproval('CRVW', 2)
2728
2729 # Add the parent change.
2730 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2731 self.waitUntilSettled()
2732 self.worker.release('.*-merge')
2733 self.waitUntilSettled()
2734
2735 # Reconfigure (with only one change in the pipeline).
2736 self.sched.reconfigure(self.config)
2737 self.waitUntilSettled()
2738
2739 # Add the child change.
2740 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2741 self.waitUntilSettled()
2742 self.worker.release('.*-merge')
2743 self.waitUntilSettled()
2744
2745 # Reconfigure (with both in the pipeline).
2746 self.sched.reconfigure(self.config)
2747 self.waitUntilSettled()
2748
2749 self.worker.hold_jobs_in_build = False
2750 self.worker.release()
2751 self.waitUntilSettled()
2752
2753 self.assertEqual(len(self.history), 8)
2754
2755 self.assertEqual(A.data['status'], 'MERGED')
2756 self.assertEqual(A.reported, 2)
2757 self.assertEqual(B.data['status'], 'MERGED')
2758 self.assertEqual(B.reported, 2)
2759
James E. Blairec056492016-07-22 09:45:56 -07002760 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002761 def test_live_reconfiguration_del_project(self):
2762 # Test project deletion from layout
2763 # while changes are enqueued
2764
2765 self.worker.hold_jobs_in_build = True
2766 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2767 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2768 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
2769
2770 # A Depends-On: B
2771 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
2772 A.subject, B.data['id'])
2773 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2774
2775 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2776 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
2777 self.waitUntilSettled()
2778 self.worker.release('.*-merge')
2779 self.waitUntilSettled()
2780 self.assertEqual(len(self.builds), 5)
2781
2782 # This layout defines only org/project, not org/project1
James E. Blairf84026c2015-12-08 16:11:46 -08002783 self.updateConfigLayout(
2784 'tests/fixtures/layout-live-reconfiguration-del-project.yaml')
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002785 self.sched.reconfigure(self.config)
2786 self.waitUntilSettled()
2787
2788 # Builds for C aborted, builds for A succeed,
2789 # and have change B applied ahead
2790 job_c = self.getJobFromHistory('project1-test1')
2791 self.assertEqual(job_c.changes, '3,1')
2792 self.assertEqual(job_c.result, 'ABORTED')
2793
2794 self.worker.hold_jobs_in_build = False
2795 self.worker.release()
2796 self.waitUntilSettled()
2797
2798 self.assertEqual(self.getJobFromHistory('project-test1').changes,
2799 '2,1 1,1')
2800
2801 self.assertEqual(A.data['status'], 'NEW')
2802 self.assertEqual(B.data['status'], 'NEW')
2803 self.assertEqual(C.data['status'], 'NEW')
2804 self.assertEqual(A.reported, 1)
2805 self.assertEqual(B.reported, 0)
2806 self.assertEqual(C.reported, 0)
2807
2808 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
2809 self.assertIn('Build succeeded', A.messages[0])
2810
James E. Blairec056492016-07-22 09:45:56 -07002811 @skip("Disabled for early v3 development")
James E. Blaire712d9f2013-07-31 11:40:11 -07002812 def test_live_reconfiguration_functions(self):
2813 "Test live reconfiguration with a custom function"
2814 self.worker.registerFunction('build:node-project-test1:debian')
2815 self.worker.registerFunction('build:node-project-test1:wheezy')
2816 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
2817 A.addApproval('CRVW', 2)
2818 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2819 self.waitUntilSettled()
2820
2821 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2822 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2823 'debian')
2824 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2825
James E. Blairf84026c2015-12-08 16:11:46 -08002826 self.updateConfigLayout(
2827 'tests/fixtures/layout-live-reconfiguration-functions.yaml')
James E. Blaire712d9f2013-07-31 11:40:11 -07002828 self.sched.reconfigure(self.config)
2829 self.worker.build_history = []
2830
2831 B = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'B')
2832 B.addApproval('CRVW', 2)
2833 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2834 self.waitUntilSettled()
2835
2836 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2837 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2838 'wheezy')
2839 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2840
James E. Blairec056492016-07-22 09:45:56 -07002841 @skip("Disabled for early v3 development")
James E. Blair287c06d2013-07-24 10:39:30 -07002842 def test_delayed_repo_init(self):
James E. Blairf84026c2015-12-08 16:11:46 -08002843 self.updateConfigLayout(
2844 'tests/fixtures/layout-delayed-repo-init.yaml')
James E. Blair287c06d2013-07-24 10:39:30 -07002845 self.sched.reconfigure(self.config)
2846
2847 self.init_repo("org/new-project")
2848 A = self.fake_gerrit.addFakeChange('org/new-project', 'master', 'A')
2849
2850 A.addApproval('CRVW', 2)
2851 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2852 self.waitUntilSettled()
2853 self.assertEqual(self.getJobFromHistory('project-merge').result,
2854 'SUCCESS')
2855 self.assertEqual(self.getJobFromHistory('project-test1').result,
2856 'SUCCESS')
2857 self.assertEqual(self.getJobFromHistory('project-test2').result,
2858 'SUCCESS')
2859 self.assertEqual(A.data['status'], 'MERGED')
2860 self.assertEqual(A.reported, 2)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002861
James E. Blairec056492016-07-22 09:45:56 -07002862 @skip("Disabled for early v3 development")
Clark Boylan6dbbc482013-10-18 10:57:31 -07002863 def test_repo_deleted(self):
James E. Blairf84026c2015-12-08 16:11:46 -08002864 self.updateConfigLayout(
2865 'tests/fixtures/layout-repo-deleted.yaml')
Clark Boylan6dbbc482013-10-18 10:57:31 -07002866 self.sched.reconfigure(self.config)
2867
2868 self.init_repo("org/delete-project")
2869 A = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'A')
2870
2871 A.addApproval('CRVW', 2)
2872 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2873 self.waitUntilSettled()
2874 self.assertEqual(self.getJobFromHistory('project-merge').result,
2875 'SUCCESS')
2876 self.assertEqual(self.getJobFromHistory('project-test1').result,
2877 'SUCCESS')
2878 self.assertEqual(self.getJobFromHistory('project-test2').result,
2879 'SUCCESS')
2880 self.assertEqual(A.data['status'], 'MERGED')
2881 self.assertEqual(A.reported, 2)
2882
2883 # Delete org/new-project zuul repo. Should be recloned.
2884 shutil.rmtree(os.path.join(self.git_root, "org/delete-project"))
2885
2886 B = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'B')
2887
2888 B.addApproval('CRVW', 2)
2889 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2890 self.waitUntilSettled()
2891 self.assertEqual(self.getJobFromHistory('project-merge').result,
2892 'SUCCESS')
2893 self.assertEqual(self.getJobFromHistory('project-test1').result,
2894 'SUCCESS')
2895 self.assertEqual(self.getJobFromHistory('project-test2').result,
2896 'SUCCESS')
2897 self.assertEqual(B.data['status'], 'MERGED')
2898 self.assertEqual(B.reported, 2)
2899
James E. Blairec056492016-07-22 09:45:56 -07002900 @skip("Disabled for early v3 development")
James E. Blair456f2fb2016-02-09 09:29:33 -08002901 def test_tags(self):
2902 "Test job tags"
2903 self.config.set('zuul', 'layout_config',
2904 'tests/fixtures/layout-tags.yaml')
2905 self.sched.reconfigure(self.config)
2906
2907 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2908 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
2909 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2910 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2911 self.waitUntilSettled()
2912
2913 results = {'project1-merge': 'extratag merge project1',
2914 'project2-merge': 'merge'}
2915
2916 for build in self.history:
2917 self.assertEqual(results.get(build.name, ''),
2918 build.parameters.get('BUILD_TAGS'))
2919
James E. Blairec056492016-07-22 09:45:56 -07002920 @skip("Disabled for early v3 development")
James E. Blair63bb0ef2013-07-29 17:14:51 -07002921 def test_timer(self):
2922 "Test that a periodic job is triggered"
2923 self.worker.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08002924 self.updateConfigLayout(
2925 'tests/fixtures/layout-timer.yaml')
James E. Blair63bb0ef2013-07-29 17:14:51 -07002926 self.sched.reconfigure(self.config)
2927 self.registerJobs()
2928
Clark Boylan3ee090a2014-04-03 20:55:09 -07002929 # The pipeline triggers every second, so we should have seen
2930 # several by now.
2931 time.sleep(5)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002932 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002933
2934 self.assertEqual(len(self.builds), 2)
2935
James E. Blair63bb0ef2013-07-29 17:14:51 -07002936 port = self.webapp.server.socket.getsockname()[1]
2937
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002938 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2939 f = urllib.request.urlopen(req)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002940 data = f.read()
2941
2942 self.worker.hold_jobs_in_build = False
Clark Boylan3ee090a2014-04-03 20:55:09 -07002943 # Stop queuing timer triggered jobs so that the assertions
2944 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08002945 self.updateConfigLayout(
2946 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002947 self.sched.reconfigure(self.config)
2948 self.registerJobs()
James E. Blair63bb0ef2013-07-29 17:14:51 -07002949 self.worker.release()
2950 self.waitUntilSettled()
2951
2952 self.assertEqual(self.getJobFromHistory(
2953 'project-bitrot-stable-old').result, 'SUCCESS')
2954 self.assertEqual(self.getJobFromHistory(
2955 'project-bitrot-stable-older').result, 'SUCCESS')
2956
2957 data = json.loads(data)
2958 status_jobs = set()
2959 for p in data['pipelines']:
2960 for q in p['change_queues']:
2961 for head in q['heads']:
2962 for change in head:
Alex Gaynorddb9ef32013-09-16 21:04:58 -07002963 self.assertEqual(change['id'], None)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002964 for job in change['jobs']:
2965 status_jobs.add(job['name'])
2966 self.assertIn('project-bitrot-stable-old', status_jobs)
2967 self.assertIn('project-bitrot-stable-older', status_jobs)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002968
James E. Blairec056492016-07-22 09:45:56 -07002969 @skip("Disabled for early v3 development")
James E. Blair4f6033c2014-03-27 15:49:09 -07002970 def test_idle(self):
2971 "Test that frequent periodic jobs work"
2972 self.worker.hold_jobs_in_build = True
James E. Blair4f6033c2014-03-27 15:49:09 -07002973
Clark Boylan3ee090a2014-04-03 20:55:09 -07002974 for x in range(1, 3):
2975 # Test that timer triggers periodic jobs even across
2976 # layout config reloads.
2977 # Start timer trigger
James E. Blairf84026c2015-12-08 16:11:46 -08002978 self.updateConfigLayout(
2979 'tests/fixtures/layout-idle.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002980 self.sched.reconfigure(self.config)
2981 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08002982 self.waitUntilSettled()
James E. Blair4f6033c2014-03-27 15:49:09 -07002983
Clark Boylan3ee090a2014-04-03 20:55:09 -07002984 # The pipeline triggers every second, so we should have seen
2985 # several by now.
2986 time.sleep(5)
Clark Boylan3ee090a2014-04-03 20:55:09 -07002987
2988 # Stop queuing timer triggered jobs so that the assertions
2989 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08002990 self.updateConfigLayout(
2991 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002992 self.sched.reconfigure(self.config)
2993 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08002994 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002995
2996 self.assertEqual(len(self.builds), 2)
2997 self.worker.release('.*')
2998 self.waitUntilSettled()
2999 self.assertEqual(len(self.builds), 0)
3000 self.assertEqual(len(self.history), x * 2)
James E. Blair4f6033c2014-03-27 15:49:09 -07003001
James E. Blairec056492016-07-22 09:45:56 -07003002 @skip("Disabled for early v3 development")
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003003 def test_check_smtp_pool(self):
James E. Blairf84026c2015-12-08 16:11:46 -08003004 self.updateConfigLayout(
3005 'tests/fixtures/layout-smtp.yaml')
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003006 self.sched.reconfigure(self.config)
3007
3008 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3009 self.waitUntilSettled()
3010
3011 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
3012 self.waitUntilSettled()
3013
James E. Blairff80a2f2013-12-27 13:24:06 -08003014 self.assertEqual(len(self.smtp_messages), 2)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003015
3016 # A.messages only holds what FakeGerrit places in it. Thus we
3017 # work on the knowledge of what the first message should be as
3018 # it is only configured to go to SMTP.
3019
3020 self.assertEqual('zuul@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003021 self.smtp_messages[0]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003022 self.assertEqual(['you@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003023 self.smtp_messages[0]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003024 self.assertEqual('Starting check jobs.',
James E. Blairff80a2f2013-12-27 13:24:06 -08003025 self.smtp_messages[0]['body'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003026
3027 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003028 self.smtp_messages[1]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003029 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003030 self.smtp_messages[1]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003031 self.assertEqual(A.messages[0],
James E. Blairff80a2f2013-12-27 13:24:06 -08003032 self.smtp_messages[1]['body'])
James E. Blairad28e912013-11-27 10:43:22 -08003033
James E. Blairec056492016-07-22 09:45:56 -07003034 @skip("Disabled for early v3 development")
James E. Blaire5910202013-12-27 09:50:31 -08003035 def test_timer_smtp(self):
3036 "Test that a periodic job is triggered"
Clark Boylan3ee090a2014-04-03 20:55:09 -07003037 self.worker.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08003038 self.updateConfigLayout(
3039 'tests/fixtures/layout-timer-smtp.yaml')
James E. Blaire5910202013-12-27 09:50:31 -08003040 self.sched.reconfigure(self.config)
3041 self.registerJobs()
3042
Clark Boylan3ee090a2014-04-03 20:55:09 -07003043 # The pipeline triggers every second, so we should have seen
3044 # several by now.
3045 time.sleep(5)
James E. Blaire5910202013-12-27 09:50:31 -08003046 self.waitUntilSettled()
3047
Clark Boylan3ee090a2014-04-03 20:55:09 -07003048 self.assertEqual(len(self.builds), 2)
3049 self.worker.release('.*')
3050 self.waitUntilSettled()
3051 self.assertEqual(len(self.history), 2)
3052
James E. Blaire5910202013-12-27 09:50:31 -08003053 self.assertEqual(self.getJobFromHistory(
3054 'project-bitrot-stable-old').result, 'SUCCESS')
3055 self.assertEqual(self.getJobFromHistory(
3056 'project-bitrot-stable-older').result, 'SUCCESS')
3057
James E. Blairff80a2f2013-12-27 13:24:06 -08003058 self.assertEqual(len(self.smtp_messages), 1)
James E. Blaire5910202013-12-27 09:50:31 -08003059
3060 # A.messages only holds what FakeGerrit places in it. Thus we
3061 # work on the knowledge of what the first message should be as
3062 # it is only configured to go to SMTP.
3063
3064 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003065 self.smtp_messages[0]['from_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003066 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003067 self.smtp_messages[0]['to_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003068 self.assertIn('Subject: Periodic check for org/project succeeded',
James E. Blairff80a2f2013-12-27 13:24:06 -08003069 self.smtp_messages[0]['headers'])
James E. Blaire5910202013-12-27 09:50:31 -08003070
Clark Boylan3ee090a2014-04-03 20:55:09 -07003071 # Stop queuing timer triggered jobs and let any that may have
3072 # queued through so that end of test assertions pass.
James E. Blairf84026c2015-12-08 16:11:46 -08003073 self.updateConfigLayout(
3074 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07003075 self.sched.reconfigure(self.config)
3076 self.registerJobs()
James E. Blairf8058972014-08-15 16:09:16 -07003077 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07003078 self.worker.release('.*')
3079 self.waitUntilSettled()
3080
James E. Blairec056492016-07-22 09:45:56 -07003081 @skip("Disabled for early v3 development")
James E. Blair91e34592015-07-31 16:45:59 -07003082 def test_client_enqueue_change(self):
James E. Blairad28e912013-11-27 10:43:22 -08003083 "Test that the RPC client can enqueue a change"
3084 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3085 A.addApproval('CRVW', 2)
3086 A.addApproval('APRV', 1)
3087
3088 client = zuul.rpcclient.RPCClient('127.0.0.1',
3089 self.gearman_server.port)
3090 r = client.enqueue(pipeline='gate',
3091 project='org/project',
3092 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003093 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003094 self.waitUntilSettled()
3095 self.assertEqual(self.getJobFromHistory('project-merge').result,
3096 'SUCCESS')
3097 self.assertEqual(self.getJobFromHistory('project-test1').result,
3098 'SUCCESS')
3099 self.assertEqual(self.getJobFromHistory('project-test2').result,
3100 'SUCCESS')
3101 self.assertEqual(A.data['status'], 'MERGED')
3102 self.assertEqual(A.reported, 2)
3103 self.assertEqual(r, True)
3104
James E. Blairec056492016-07-22 09:45:56 -07003105 @skip("Disabled for early v3 development")
James E. Blair91e34592015-07-31 16:45:59 -07003106 def test_client_enqueue_ref(self):
3107 "Test that the RPC client can enqueue a ref"
3108
3109 client = zuul.rpcclient.RPCClient('127.0.0.1',
3110 self.gearman_server.port)
3111 r = client.enqueue_ref(
3112 pipeline='post',
3113 project='org/project',
3114 trigger='gerrit',
3115 ref='master',
3116 oldrev='90f173846e3af9154517b88543ffbd1691f31366',
3117 newrev='d479a0bfcb34da57a31adb2a595c0cf687812543')
3118 self.waitUntilSettled()
3119 job_names = [x.name for x in self.history]
3120 self.assertEqual(len(self.history), 1)
3121 self.assertIn('project-post', job_names)
3122 self.assertEqual(r, True)
3123
James E. Blairec056492016-07-22 09:45:56 -07003124 @skip("Disabled for early v3 development")
James E. Blairad28e912013-11-27 10:43:22 -08003125 def test_client_enqueue_negative(self):
3126 "Test that the RPC client returns errors"
3127 client = zuul.rpcclient.RPCClient('127.0.0.1',
3128 self.gearman_server.port)
3129 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3130 "Invalid project"):
3131 r = client.enqueue(pipeline='gate',
3132 project='project-does-not-exist',
3133 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003134 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003135 client.shutdown()
3136 self.assertEqual(r, False)
3137
3138 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3139 "Invalid pipeline"):
3140 r = client.enqueue(pipeline='pipeline-does-not-exist',
3141 project='org/project',
3142 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003143 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003144 client.shutdown()
3145 self.assertEqual(r, False)
3146
3147 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3148 "Invalid trigger"):
3149 r = client.enqueue(pipeline='gate',
3150 project='org/project',
3151 trigger='trigger-does-not-exist',
James E. Blair36658cf2013-12-06 17:53:48 -08003152 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003153 client.shutdown()
3154 self.assertEqual(r, False)
3155
3156 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3157 "Invalid change"):
3158 r = client.enqueue(pipeline='gate',
3159 project='org/project',
3160 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003161 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003162 client.shutdown()
3163 self.assertEqual(r, False)
3164
3165 self.waitUntilSettled()
3166 self.assertEqual(len(self.history), 0)
3167 self.assertEqual(len(self.builds), 0)
James E. Blair36658cf2013-12-06 17:53:48 -08003168
James E. Blairec056492016-07-22 09:45:56 -07003169 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003170 def test_client_promote(self):
3171 "Test that the RPC client can promote a change"
3172 self.worker.hold_jobs_in_build = True
3173 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3174 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3175 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3176 A.addApproval('CRVW', 2)
3177 B.addApproval('CRVW', 2)
3178 C.addApproval('CRVW', 2)
3179
3180 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3181 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3182 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3183
3184 self.waitUntilSettled()
3185
Sean Daguef39b9ca2014-01-10 21:34:35 -05003186 items = self.sched.layout.pipelines['gate'].getAllItems()
3187 enqueue_times = {}
3188 for item in items:
3189 enqueue_times[str(item.change)] = item.enqueue_time
3190
James E. Blair36658cf2013-12-06 17:53:48 -08003191 client = zuul.rpcclient.RPCClient('127.0.0.1',
3192 self.gearman_server.port)
3193 r = client.promote(pipeline='gate',
3194 change_ids=['2,1', '3,1'])
3195
Sean Daguef39b9ca2014-01-10 21:34:35 -05003196 # ensure that enqueue times are durable
3197 items = self.sched.layout.pipelines['gate'].getAllItems()
3198 for item in items:
3199 self.assertEqual(
3200 enqueue_times[str(item.change)], item.enqueue_time)
3201
James E. Blair78acec92014-02-06 07:11:32 -08003202 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08003203 self.worker.release('.*-merge')
3204 self.waitUntilSettled()
3205 self.worker.release('.*-merge')
3206 self.waitUntilSettled()
3207 self.worker.release('.*-merge')
3208 self.waitUntilSettled()
3209
3210 self.assertEqual(len(self.builds), 6)
3211 self.assertEqual(self.builds[0].name, 'project-test1')
3212 self.assertEqual(self.builds[1].name, 'project-test2')
3213 self.assertEqual(self.builds[2].name, 'project-test1')
3214 self.assertEqual(self.builds[3].name, 'project-test2')
3215 self.assertEqual(self.builds[4].name, 'project-test1')
3216 self.assertEqual(self.builds[5].name, 'project-test2')
3217
3218 self.assertTrue(self.job_has_changes(self.builds[0], B))
3219 self.assertFalse(self.job_has_changes(self.builds[0], A))
3220 self.assertFalse(self.job_has_changes(self.builds[0], C))
3221
3222 self.assertTrue(self.job_has_changes(self.builds[2], B))
3223 self.assertTrue(self.job_has_changes(self.builds[2], C))
3224 self.assertFalse(self.job_has_changes(self.builds[2], A))
3225
3226 self.assertTrue(self.job_has_changes(self.builds[4], B))
3227 self.assertTrue(self.job_has_changes(self.builds[4], C))
3228 self.assertTrue(self.job_has_changes(self.builds[4], A))
3229
3230 self.worker.release()
3231 self.waitUntilSettled()
3232
3233 self.assertEqual(A.data['status'], 'MERGED')
3234 self.assertEqual(A.reported, 2)
3235 self.assertEqual(B.data['status'], 'MERGED')
3236 self.assertEqual(B.reported, 2)
3237 self.assertEqual(C.data['status'], 'MERGED')
3238 self.assertEqual(C.reported, 2)
3239
3240 client.shutdown()
3241 self.assertEqual(r, True)
3242
James E. Blairec056492016-07-22 09:45:56 -07003243 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003244 def test_client_promote_dependent(self):
3245 "Test that the RPC client can promote a dependent change"
3246 # C (depends on B) -> B -> A ; then promote C to get:
3247 # A -> C (depends on B) -> B
3248 self.worker.hold_jobs_in_build = True
3249 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3250 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3251 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3252
3253 C.setDependsOn(B, 1)
3254
3255 A.addApproval('CRVW', 2)
3256 B.addApproval('CRVW', 2)
3257 C.addApproval('CRVW', 2)
3258
3259 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3260 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3261 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3262
3263 self.waitUntilSettled()
3264
3265 client = zuul.rpcclient.RPCClient('127.0.0.1',
3266 self.gearman_server.port)
3267 r = client.promote(pipeline='gate',
3268 change_ids=['3,1'])
3269
James E. Blair78acec92014-02-06 07:11:32 -08003270 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08003271 self.worker.release('.*-merge')
3272 self.waitUntilSettled()
3273 self.worker.release('.*-merge')
3274 self.waitUntilSettled()
3275 self.worker.release('.*-merge')
3276 self.waitUntilSettled()
3277
3278 self.assertEqual(len(self.builds), 6)
3279 self.assertEqual(self.builds[0].name, 'project-test1')
3280 self.assertEqual(self.builds[1].name, 'project-test2')
3281 self.assertEqual(self.builds[2].name, 'project-test1')
3282 self.assertEqual(self.builds[3].name, 'project-test2')
3283 self.assertEqual(self.builds[4].name, 'project-test1')
3284 self.assertEqual(self.builds[5].name, 'project-test2')
3285
3286 self.assertTrue(self.job_has_changes(self.builds[0], B))
3287 self.assertFalse(self.job_has_changes(self.builds[0], A))
3288 self.assertFalse(self.job_has_changes(self.builds[0], C))
3289
3290 self.assertTrue(self.job_has_changes(self.builds[2], B))
3291 self.assertTrue(self.job_has_changes(self.builds[2], C))
3292 self.assertFalse(self.job_has_changes(self.builds[2], A))
3293
3294 self.assertTrue(self.job_has_changes(self.builds[4], B))
3295 self.assertTrue(self.job_has_changes(self.builds[4], C))
3296 self.assertTrue(self.job_has_changes(self.builds[4], A))
3297
3298 self.worker.release()
3299 self.waitUntilSettled()
3300
3301 self.assertEqual(A.data['status'], 'MERGED')
3302 self.assertEqual(A.reported, 2)
3303 self.assertEqual(B.data['status'], 'MERGED')
3304 self.assertEqual(B.reported, 2)
3305 self.assertEqual(C.data['status'], 'MERGED')
3306 self.assertEqual(C.reported, 2)
3307
3308 client.shutdown()
3309 self.assertEqual(r, True)
3310
James E. Blairec056492016-07-22 09:45:56 -07003311 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003312 def test_client_promote_negative(self):
3313 "Test that the RPC client returns errors for promotion"
3314 self.worker.hold_jobs_in_build = True
3315 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3316 A.addApproval('CRVW', 2)
3317 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3318 self.waitUntilSettled()
3319
3320 client = zuul.rpcclient.RPCClient('127.0.0.1',
3321 self.gearman_server.port)
3322
3323 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
3324 r = client.promote(pipeline='nonexistent',
3325 change_ids=['2,1', '3,1'])
3326 client.shutdown()
3327 self.assertEqual(r, False)
3328
3329 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
3330 r = client.promote(pipeline='gate',
3331 change_ids=['4,1'])
3332 client.shutdown()
3333 self.assertEqual(r, False)
3334
3335 self.worker.hold_jobs_in_build = False
3336 self.worker.release()
3337 self.waitUntilSettled()
Clark Boylan7603a372014-01-21 11:43:20 -08003338
James E. Blairec056492016-07-22 09:45:56 -07003339 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003340 def test_queue_rate_limiting(self):
3341 "Test that DependentPipelines are rate limited with dep across window"
James E. Blairf84026c2015-12-08 16:11:46 -08003342 self.updateConfigLayout(
3343 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003344 self.sched.reconfigure(self.config)
3345 self.worker.hold_jobs_in_build = True
3346 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3347 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3348 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3349
3350 C.setDependsOn(B, 1)
3351 self.worker.addFailTest('project-test1', A)
3352
3353 A.addApproval('CRVW', 2)
3354 B.addApproval('CRVW', 2)
3355 C.addApproval('CRVW', 2)
3356
3357 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3358 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3359 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3360 self.waitUntilSettled()
3361
3362 # Only A and B will have their merge jobs queued because
3363 # window is 2.
3364 self.assertEqual(len(self.builds), 2)
3365 self.assertEqual(self.builds[0].name, 'project-merge')
3366 self.assertEqual(self.builds[1].name, 'project-merge')
3367
3368 self.worker.release('.*-merge')
3369 self.waitUntilSettled()
3370 self.worker.release('.*-merge')
3371 self.waitUntilSettled()
3372
3373 # Only A and B will have their test jobs queued because
3374 # window is 2.
3375 self.assertEqual(len(self.builds), 4)
3376 self.assertEqual(self.builds[0].name, 'project-test1')
3377 self.assertEqual(self.builds[1].name, 'project-test2')
3378 self.assertEqual(self.builds[2].name, 'project-test1')
3379 self.assertEqual(self.builds[3].name, 'project-test2')
3380
3381 self.worker.release('project-.*')
3382 self.waitUntilSettled()
3383
3384 queue = self.sched.layout.pipelines['gate'].queues[0]
3385 # A failed so window is reduced by 1 to 1.
3386 self.assertEqual(queue.window, 1)
3387 self.assertEqual(queue.window_floor, 1)
3388 self.assertEqual(A.data['status'], 'NEW')
3389
3390 # Gate is reset and only B's merge job is queued because
3391 # window shrunk to 1.
3392 self.assertEqual(len(self.builds), 1)
3393 self.assertEqual(self.builds[0].name, 'project-merge')
3394
3395 self.worker.release('.*-merge')
3396 self.waitUntilSettled()
3397
3398 # Only B's test jobs are queued because window is still 1.
3399 self.assertEqual(len(self.builds), 2)
3400 self.assertEqual(self.builds[0].name, 'project-test1')
3401 self.assertEqual(self.builds[1].name, 'project-test2')
3402
3403 self.worker.release('project-.*')
3404 self.waitUntilSettled()
3405
3406 # B was successfully merged so window is increased to 2.
3407 self.assertEqual(queue.window, 2)
3408 self.assertEqual(queue.window_floor, 1)
3409 self.assertEqual(B.data['status'], 'MERGED')
3410
3411 # Only C is left and its merge job is queued.
3412 self.assertEqual(len(self.builds), 1)
3413 self.assertEqual(self.builds[0].name, 'project-merge')
3414
3415 self.worker.release('.*-merge')
3416 self.waitUntilSettled()
3417
3418 # After successful merge job the test jobs for C are queued.
3419 self.assertEqual(len(self.builds), 2)
3420 self.assertEqual(self.builds[0].name, 'project-test1')
3421 self.assertEqual(self.builds[1].name, 'project-test2')
3422
3423 self.worker.release('project-.*')
3424 self.waitUntilSettled()
3425
3426 # C successfully merged so window is bumped to 3.
3427 self.assertEqual(queue.window, 3)
3428 self.assertEqual(queue.window_floor, 1)
3429 self.assertEqual(C.data['status'], 'MERGED')
3430
James E. Blairec056492016-07-22 09:45:56 -07003431 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003432 def test_queue_rate_limiting_dependent(self):
3433 "Test that DependentPipelines are rate limited with dep in window"
James E. Blairf84026c2015-12-08 16:11:46 -08003434 self.updateConfigLayout(
3435 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003436 self.sched.reconfigure(self.config)
3437 self.worker.hold_jobs_in_build = True
3438 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3439 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3440 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3441
3442 B.setDependsOn(A, 1)
3443
3444 self.worker.addFailTest('project-test1', A)
3445
3446 A.addApproval('CRVW', 2)
3447 B.addApproval('CRVW', 2)
3448 C.addApproval('CRVW', 2)
3449
3450 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3451 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3452 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3453 self.waitUntilSettled()
3454
3455 # Only A and B will have their merge jobs queued because
3456 # window is 2.
3457 self.assertEqual(len(self.builds), 2)
3458 self.assertEqual(self.builds[0].name, 'project-merge')
3459 self.assertEqual(self.builds[1].name, 'project-merge')
3460
3461 self.worker.release('.*-merge')
3462 self.waitUntilSettled()
3463 self.worker.release('.*-merge')
3464 self.waitUntilSettled()
3465
3466 # Only A and B will have their test jobs queued because
3467 # window is 2.
3468 self.assertEqual(len(self.builds), 4)
3469 self.assertEqual(self.builds[0].name, 'project-test1')
3470 self.assertEqual(self.builds[1].name, 'project-test2')
3471 self.assertEqual(self.builds[2].name, 'project-test1')
3472 self.assertEqual(self.builds[3].name, 'project-test2')
3473
3474 self.worker.release('project-.*')
3475 self.waitUntilSettled()
3476
3477 queue = self.sched.layout.pipelines['gate'].queues[0]
3478 # A failed so window is reduced by 1 to 1.
3479 self.assertEqual(queue.window, 1)
3480 self.assertEqual(queue.window_floor, 1)
3481 self.assertEqual(A.data['status'], 'NEW')
3482 self.assertEqual(B.data['status'], 'NEW')
3483
3484 # Gate is reset and only C's merge job is queued because
3485 # window shrunk to 1 and A and B were dequeued.
3486 self.assertEqual(len(self.builds), 1)
3487 self.assertEqual(self.builds[0].name, 'project-merge')
3488
3489 self.worker.release('.*-merge')
3490 self.waitUntilSettled()
3491
3492 # Only C's test jobs are queued because window is still 1.
3493 self.assertEqual(len(self.builds), 2)
3494 self.assertEqual(self.builds[0].name, 'project-test1')
3495 self.assertEqual(self.builds[1].name, 'project-test2')
3496
3497 self.worker.release('project-.*')
3498 self.waitUntilSettled()
3499
3500 # C was successfully merged so window is increased to 2.
3501 self.assertEqual(queue.window, 2)
3502 self.assertEqual(queue.window_floor, 1)
3503 self.assertEqual(C.data['status'], 'MERGED')
Joshua Heskethba8776a2014-01-12 14:35:40 +08003504
James E. Blairec056492016-07-22 09:45:56 -07003505 @skip("Disabled for early v3 development")
Joshua Heskethba8776a2014-01-12 14:35:40 +08003506 def test_worker_update_metadata(self):
3507 "Test if a worker can send back metadata about itself"
3508 self.worker.hold_jobs_in_build = True
3509
3510 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3511 A.addApproval('CRVW', 2)
3512 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3513 self.waitUntilSettled()
3514
3515 self.assertEqual(len(self.launcher.builds), 1)
3516
3517 self.log.debug('Current builds:')
3518 self.log.debug(self.launcher.builds)
3519
3520 start = time.time()
3521 while True:
3522 if time.time() - start > 10:
3523 raise Exception("Timeout waiting for gearman server to report "
3524 + "back to the client")
3525 build = self.launcher.builds.values()[0]
3526 if build.worker.name == "My Worker":
3527 break
3528 else:
3529 time.sleep(0)
3530
3531 self.log.debug(build)
3532 self.assertEqual("My Worker", build.worker.name)
3533 self.assertEqual("localhost", build.worker.hostname)
3534 self.assertEqual(['127.0.0.1', '192.168.1.1'], build.worker.ips)
3535 self.assertEqual("zuul.example.org", build.worker.fqdn)
3536 self.assertEqual("FakeBuilder", build.worker.program)
3537 self.assertEqual("v1.1", build.worker.version)
3538 self.assertEqual({'something': 'else'}, build.worker.extra)
3539
3540 self.worker.hold_jobs_in_build = False
3541 self.worker.release()
3542 self.waitUntilSettled()
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003543
James E. Blairec056492016-07-22 09:45:56 -07003544 @skip("Disabled for early v3 development")
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003545 def test_footer_message(self):
3546 "Test a pipeline's footer message is correctly added to the report."
James E. Blairf84026c2015-12-08 16:11:46 -08003547 self.updateConfigLayout(
3548 'tests/fixtures/layout-footer-message.yaml')
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003549 self.sched.reconfigure(self.config)
3550 self.registerJobs()
3551
3552 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3553 A.addApproval('CRVW', 2)
3554 self.worker.addFailTest('test1', A)
3555 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3556 self.waitUntilSettled()
3557
3558 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3559 B.addApproval('CRVW', 2)
3560 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3561 self.waitUntilSettled()
3562
3563 self.assertEqual(2, len(self.smtp_messages))
3564
3565 failure_body = """\
3566Build failed. For information on how to proceed, see \
3567http://wiki.example.org/Test_Failures
3568
3569- test1 http://logs.example.com/1/1/gate/test1/0 : FAILURE in 0s
3570- test2 http://logs.example.com/1/1/gate/test2/1 : SUCCESS in 0s
3571
3572For CI problems and help debugging, contact ci@example.org"""
3573
3574 success_body = """\
3575Build succeeded.
3576
3577- test1 http://logs.example.com/2/1/gate/test1/2 : SUCCESS in 0s
3578- test2 http://logs.example.com/2/1/gate/test2/3 : SUCCESS in 0s
3579
3580For CI problems and help debugging, contact ci@example.org"""
3581
3582 self.assertEqual(failure_body, self.smtp_messages[0]['body'])
3583 self.assertEqual(success_body, self.smtp_messages[1]['body'])
Joshua Heskethb7179772014-01-30 23:30:46 +11003584
James E. Blairec056492016-07-22 09:45:56 -07003585 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003586 def test_merge_failure_reporters(self):
3587 """Check that the config is set up correctly"""
3588
James E. Blairf84026c2015-12-08 16:11:46 -08003589 self.updateConfigLayout(
3590 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003591 self.sched.reconfigure(self.config)
3592 self.registerJobs()
3593
3594 self.assertEqual(
Jeremy Stanley1c2c3c22015-06-15 21:23:19 +00003595 "Merge Failed.\n\nThis change or one of its cross-repo "
3596 "dependencies was unable to be automatically merged with the "
3597 "current state of its repository. Please rebase the change and "
3598 "upload a new patchset.",
Joshua Heskethb7179772014-01-30 23:30:46 +11003599 self.sched.layout.pipelines['check'].merge_failure_message)
3600 self.assertEqual(
3601 "The merge failed! For more information...",
3602 self.sched.layout.pipelines['gate'].merge_failure_message)
3603
3604 self.assertEqual(
3605 len(self.sched.layout.pipelines['check'].merge_failure_actions), 1)
3606 self.assertEqual(
3607 len(self.sched.layout.pipelines['gate'].merge_failure_actions), 2)
3608
3609 self.assertTrue(isinstance(
Joshua Heskethde958652015-11-10 19:19:50 +11003610 self.sched.layout.pipelines['check'].merge_failure_actions[0],
3611 zuul.reporter.gerrit.GerritReporter))
Joshua Heskethb7179772014-01-30 23:30:46 +11003612
3613 self.assertTrue(
3614 (
3615 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003616 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003617 zuul.reporter.smtp.SMTPReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003618 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003619 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003620 zuul.reporter.gerrit.GerritReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003621 ) or (
3622 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003623 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003624 zuul.reporter.gerrit.GerritReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003625 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003626 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003627 zuul.reporter.smtp.SMTPReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003628 )
3629 )
3630
James E. Blairec056492016-07-22 09:45:56 -07003631 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003632 def test_merge_failure_reports(self):
3633 """Check that when a change fails to merge the correct message is sent
3634 to the correct reporter"""
James E. Blairf84026c2015-12-08 16:11:46 -08003635 self.updateConfigLayout(
3636 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003637 self.sched.reconfigure(self.config)
3638 self.registerJobs()
3639
3640 # Check a test failure isn't reported to SMTP
3641 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3642 A.addApproval('CRVW', 2)
3643 self.worker.addFailTest('project-test1', A)
3644 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3645 self.waitUntilSettled()
3646
3647 self.assertEqual(3, len(self.history)) # 3 jobs
3648 self.assertEqual(0, len(self.smtp_messages))
3649
3650 # Check a merge failure is reported to SMTP
3651 # B should be merged, but C will conflict with B
3652 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3653 B.addPatchset(['conflict'])
3654 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3655 C.addPatchset(['conflict'])
3656 B.addApproval('CRVW', 2)
3657 C.addApproval('CRVW', 2)
3658 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3659 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3660 self.waitUntilSettled()
3661
3662 self.assertEqual(6, len(self.history)) # A and B jobs
3663 self.assertEqual(1, len(self.smtp_messages))
3664 self.assertEqual('The merge failed! For more information...',
3665 self.smtp_messages[0]['body'])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003666
James E. Blairec056492016-07-22 09:45:56 -07003667 @skip("Disabled for early v3 development")
James E. Blairf760f0e2016-02-09 08:44:52 -08003668 def test_default_merge_failure_reports(self):
3669 """Check that the default merge failure reports are correct."""
3670
3671 # A should report success, B should report merge failure.
3672 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3673 A.addPatchset(['conflict'])
3674 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3675 B.addPatchset(['conflict'])
3676 A.addApproval('CRVW', 2)
3677 B.addApproval('CRVW', 2)
3678 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3679 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3680 self.waitUntilSettled()
3681
3682 self.assertEqual(3, len(self.history)) # A jobs
3683 self.assertEqual(A.reported, 2)
3684 self.assertEqual(B.reported, 2)
3685 self.assertEqual(A.data['status'], 'MERGED')
3686 self.assertEqual(B.data['status'], 'NEW')
3687 self.assertIn('Build succeeded', A.messages[1])
3688 self.assertIn('Merge Failed', B.messages[1])
3689 self.assertIn('automatically merged', B.messages[1])
3690 self.assertNotIn('logs.example.com', B.messages[1])
3691 self.assertNotIn('SKIPPED', B.messages[1])
3692
James E. Blairec056492016-07-22 09:45:56 -07003693 @skip("Disabled for early v3 development")
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003694 def test_swift_instructions(self):
3695 "Test that the correct swift instructions are sent to the workers"
James E. Blairf84026c2015-12-08 16:11:46 -08003696 self.updateConfigLayout(
3697 'tests/fixtures/layout-swift.yaml')
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003698 self.sched.reconfigure(self.config)
3699 self.registerJobs()
3700
3701 self.worker.hold_jobs_in_build = True
3702 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3703
3704 A.addApproval('CRVW', 2)
3705 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3706 self.waitUntilSettled()
3707
3708 self.assertEqual(
3709 "https://storage.example.org/V1/AUTH_account/merge_logs/1/1/1/"
3710 "gate/test-merge/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003711 self.builds[0].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003712 self.assertEqual(5,
3713 len(self.builds[0].parameters['SWIFT_logs_HMAC_BODY'].
3714 split('\n')))
3715 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[0].parameters)
3716
3717 self.assertEqual(
3718 "https://storage.example.org/V1/AUTH_account/logs/1/1/1/"
3719 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003720 self.builds[1].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003721 self.assertEqual(5,
3722 len(self.builds[1].parameters['SWIFT_logs_HMAC_BODY'].
3723 split('\n')))
3724 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[1].parameters)
3725
3726 self.assertEqual(
3727 "https://storage.example.org/V1/AUTH_account/stash/1/1/1/"
3728 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003729 self.builds[1].parameters['SWIFT_MOSTLY_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003730 self.assertEqual(5,
3731 len(self.builds[1].
3732 parameters['SWIFT_MOSTLY_HMAC_BODY'].split('\n')))
3733 self.assertIn('SWIFT_MOSTLY_SIGNATURE', self.builds[1].parameters)
3734
3735 self.worker.hold_jobs_in_build = False
3736 self.worker.release()
3737 self.waitUntilSettled()
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003738
James E. Blairec056492016-07-22 09:45:56 -07003739 @skip("Disabled for early v3 development")
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003740 def test_client_get_running_jobs(self):
3741 "Test that the RPC client can get a list of running jobs"
3742 self.worker.hold_jobs_in_build = True
3743 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3744 A.addApproval('CRVW', 2)
3745 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3746 self.waitUntilSettled()
3747
3748 client = zuul.rpcclient.RPCClient('127.0.0.1',
3749 self.gearman_server.port)
3750
3751 # Wait for gearman server to send the initial workData back to zuul
3752 start = time.time()
3753 while True:
3754 if time.time() - start > 10:
3755 raise Exception("Timeout waiting for gearman server to report "
3756 + "back to the client")
3757 build = self.launcher.builds.values()[0]
3758 if build.worker.name == "My Worker":
3759 break
3760 else:
3761 time.sleep(0)
3762
3763 running_items = client.get_running_jobs()
3764
3765 self.assertEqual(1, len(running_items))
3766 running_item = running_items[0]
3767 self.assertEqual([], running_item['failing_reasons'])
3768 self.assertEqual([], running_item['items_behind'])
3769 self.assertEqual('https://hostname/1', running_item['url'])
3770 self.assertEqual(None, running_item['item_ahead'])
3771 self.assertEqual('org/project', running_item['project'])
3772 self.assertEqual(None, running_item['remaining_time'])
3773 self.assertEqual(True, running_item['active'])
3774 self.assertEqual('1,1', running_item['id'])
3775
3776 self.assertEqual(3, len(running_item['jobs']))
3777 for job in running_item['jobs']:
3778 if job['name'] == 'project-merge':
3779 self.assertEqual('project-merge', job['name'])
3780 self.assertEqual('gate', job['pipeline'])
3781 self.assertEqual(False, job['retry'])
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003782 self.assertEqual('https://server/job/project-merge/0/',
3783 job['url'])
3784 self.assertEqual(7, len(job['worker']))
3785 self.assertEqual(False, job['canceled'])
3786 self.assertEqual(True, job['voting'])
3787 self.assertEqual(None, job['result'])
3788 self.assertEqual('gate', job['pipeline'])
3789 break
3790
3791 self.worker.hold_jobs_in_build = False
3792 self.worker.release()
3793 self.waitUntilSettled()
3794
3795 running_items = client.get_running_jobs()
3796 self.assertEqual(0, len(running_items))
James E. Blairbadc1ad2014-04-28 13:55:14 -07003797
James E. Blairec056492016-07-22 09:45:56 -07003798 @skip("Disabled for early v3 development")
James E. Blairbadc1ad2014-04-28 13:55:14 -07003799 def test_nonvoting_pipeline(self):
3800 "Test that a nonvoting pipeline (experimental) can still report"
3801
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003802 A = self.fake_gerrit.addFakeChange('org/experimental-project',
3803 'master', 'A')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003804 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
3805 self.waitUntilSettled()
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003806 self.assertEqual(
3807 self.getJobFromHistory('experimental-project-test').result,
3808 'SUCCESS')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003809 self.assertEqual(A.reported, 1)
James E. Blair5ee24252014-12-30 10:12:29 -08003810
James E. Blairec056492016-07-22 09:45:56 -07003811 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08003812 def test_crd_gate(self):
3813 "Test cross-repo dependencies"
3814 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3815 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3816 A.addApproval('CRVW', 2)
3817 B.addApproval('CRVW', 2)
3818
3819 AM2 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM2')
3820 AM1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM1')
3821 AM2.setMerged()
3822 AM1.setMerged()
3823
3824 BM2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM2')
3825 BM1 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM1')
3826 BM2.setMerged()
3827 BM1.setMerged()
3828
3829 # A -> AM1 -> AM2
3830 # B -> BM1 -> BM2
3831 # A Depends-On: B
3832 # M2 is here to make sure it is never queried. If it is, it
3833 # means zuul is walking down the entire history of merged
3834 # changes.
3835
3836 B.setDependsOn(BM1, 1)
3837 BM1.setDependsOn(BM2, 1)
3838
3839 A.setDependsOn(AM1, 1)
3840 AM1.setDependsOn(AM2, 1)
3841
3842 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3843 A.subject, B.data['id'])
3844
3845 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3846 self.waitUntilSettled()
3847
3848 self.assertEqual(A.data['status'], 'NEW')
3849 self.assertEqual(B.data['status'], 'NEW')
3850
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11003851 for connection in self.connections.values():
3852 connection.maintainCache([])
James E. Blair5ee24252014-12-30 10:12:29 -08003853
3854 self.worker.hold_jobs_in_build = True
3855 B.addApproval('APRV', 1)
3856 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3857 self.waitUntilSettled()
3858
3859 self.worker.release('.*-merge')
3860 self.waitUntilSettled()
3861 self.worker.release('.*-merge')
3862 self.waitUntilSettled()
3863 self.worker.hold_jobs_in_build = False
3864 self.worker.release()
3865 self.waitUntilSettled()
3866
3867 self.assertEqual(AM2.queried, 0)
3868 self.assertEqual(BM2.queried, 0)
3869 self.assertEqual(A.data['status'], 'MERGED')
3870 self.assertEqual(B.data['status'], 'MERGED')
3871 self.assertEqual(A.reported, 2)
3872 self.assertEqual(B.reported, 2)
3873
James E. Blair8f78d882015-02-05 08:51:37 -08003874 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3875 '2,1 1,1')
3876
James E. Blairec056492016-07-22 09:45:56 -07003877 @skip("Disabled for early v3 development")
James E. Blair8f78d882015-02-05 08:51:37 -08003878 def test_crd_branch(self):
3879 "Test cross-repo dependencies in multiple branches"
3880 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3881 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3882 C = self.fake_gerrit.addFakeChange('org/project2', 'mp', 'C')
3883 C.data['id'] = B.data['id']
3884 A.addApproval('CRVW', 2)
3885 B.addApproval('CRVW', 2)
3886 C.addApproval('CRVW', 2)
3887
3888 # A Depends-On: B+C
3889 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3890 A.subject, B.data['id'])
3891
3892 self.worker.hold_jobs_in_build = True
3893 B.addApproval('APRV', 1)
3894 C.addApproval('APRV', 1)
3895 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3896 self.waitUntilSettled()
3897
3898 self.worker.release('.*-merge')
3899 self.waitUntilSettled()
3900 self.worker.release('.*-merge')
3901 self.waitUntilSettled()
3902 self.worker.release('.*-merge')
3903 self.waitUntilSettled()
3904 self.worker.hold_jobs_in_build = False
3905 self.worker.release()
3906 self.waitUntilSettled()
3907
3908 self.assertEqual(A.data['status'], 'MERGED')
3909 self.assertEqual(B.data['status'], 'MERGED')
3910 self.assertEqual(C.data['status'], 'MERGED')
3911 self.assertEqual(A.reported, 2)
3912 self.assertEqual(B.reported, 2)
3913 self.assertEqual(C.reported, 2)
3914
3915 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3916 '2,1 3,1 1,1')
3917
James E. Blairec056492016-07-22 09:45:56 -07003918 @skip("Disabled for early v3 development")
James E. Blair8f78d882015-02-05 08:51:37 -08003919 def test_crd_multiline(self):
3920 "Test multiple depends-on lines in commit"
3921 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3922 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3923 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
3924 A.addApproval('CRVW', 2)
3925 B.addApproval('CRVW', 2)
3926 C.addApproval('CRVW', 2)
3927
3928 # A Depends-On: B+C
3929 A.data['commitMessage'] = '%s\n\nDepends-On: %s\nDepends-On: %s\n' % (
3930 A.subject, B.data['id'], C.data['id'])
3931
3932 self.worker.hold_jobs_in_build = True
3933 B.addApproval('APRV', 1)
3934 C.addApproval('APRV', 1)
3935 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3936 self.waitUntilSettled()
3937
3938 self.worker.release('.*-merge')
3939 self.waitUntilSettled()
3940 self.worker.release('.*-merge')
3941 self.waitUntilSettled()
3942 self.worker.release('.*-merge')
3943 self.waitUntilSettled()
3944 self.worker.hold_jobs_in_build = False
3945 self.worker.release()
3946 self.waitUntilSettled()
3947
3948 self.assertEqual(A.data['status'], 'MERGED')
3949 self.assertEqual(B.data['status'], 'MERGED')
3950 self.assertEqual(C.data['status'], 'MERGED')
3951 self.assertEqual(A.reported, 2)
3952 self.assertEqual(B.reported, 2)
3953 self.assertEqual(C.reported, 2)
3954
3955 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3956 '2,1 3,1 1,1')
James E. Blair5ee24252014-12-30 10:12:29 -08003957
James E. Blairec056492016-07-22 09:45:56 -07003958 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08003959 def test_crd_unshared_gate(self):
3960 "Test cross-repo dependencies in unshared gate queues"
3961 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3962 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3963 A.addApproval('CRVW', 2)
3964 B.addApproval('CRVW', 2)
3965
3966 # A Depends-On: B
3967 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3968 A.subject, B.data['id'])
3969
3970 # A and B do not share a queue, make sure that A is unable to
3971 # enqueue B (and therefore, A is unable to be enqueued).
3972 B.addApproval('APRV', 1)
3973 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3974 self.waitUntilSettled()
3975
3976 self.assertEqual(A.data['status'], 'NEW')
3977 self.assertEqual(B.data['status'], 'NEW')
3978 self.assertEqual(A.reported, 0)
3979 self.assertEqual(B.reported, 0)
3980 self.assertEqual(len(self.history), 0)
3981
3982 # Enqueue and merge B alone.
3983 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3984 self.waitUntilSettled()
3985
3986 self.assertEqual(B.data['status'], 'MERGED')
3987 self.assertEqual(B.reported, 2)
3988
3989 # Now that B is merged, A should be able to be enqueued and
3990 # merged.
3991 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3992 self.waitUntilSettled()
3993
3994 self.assertEqual(A.data['status'], 'MERGED')
3995 self.assertEqual(A.reported, 2)
3996
James E. Blairec056492016-07-22 09:45:56 -07003997 @skip("Disabled for early v3 development")
James E. Blair96698e22015-04-02 07:48:21 -07003998 def test_crd_gate_reverse(self):
3999 "Test reverse cross-repo dependencies"
4000 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4001 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4002 A.addApproval('CRVW', 2)
4003 B.addApproval('CRVW', 2)
4004
4005 # A Depends-On: B
4006
4007 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4008 A.subject, B.data['id'])
4009
4010 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4011 self.waitUntilSettled()
4012
4013 self.assertEqual(A.data['status'], 'NEW')
4014 self.assertEqual(B.data['status'], 'NEW')
4015
4016 self.worker.hold_jobs_in_build = True
4017 A.addApproval('APRV', 1)
4018 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
4019 self.waitUntilSettled()
4020
4021 self.worker.release('.*-merge')
4022 self.waitUntilSettled()
4023 self.worker.release('.*-merge')
4024 self.waitUntilSettled()
4025 self.worker.hold_jobs_in_build = False
4026 self.worker.release()
4027 self.waitUntilSettled()
4028
4029 self.assertEqual(A.data['status'], 'MERGED')
4030 self.assertEqual(B.data['status'], 'MERGED')
4031 self.assertEqual(A.reported, 2)
4032 self.assertEqual(B.reported, 2)
4033
4034 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
4035 '2,1 1,1')
4036
James E. Blairec056492016-07-22 09:45:56 -07004037 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08004038 def test_crd_cycle(self):
4039 "Test cross-repo dependency cycles"
4040 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4041 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4042 A.addApproval('CRVW', 2)
4043 B.addApproval('CRVW', 2)
4044
4045 # A -> B -> A (via commit-depends)
4046
4047 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4048 A.subject, B.data['id'])
4049 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4050 B.subject, A.data['id'])
4051
4052 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4053 self.waitUntilSettled()
4054
4055 self.assertEqual(A.reported, 0)
4056 self.assertEqual(B.reported, 0)
4057 self.assertEqual(A.data['status'], 'NEW')
4058 self.assertEqual(B.data['status'], 'NEW')
James E. Blairbfb8e042014-12-30 17:01:44 -08004059
James E. Blairec056492016-07-22 09:45:56 -07004060 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004061 def test_crd_gate_unknown(self):
4062 "Test unknown projects in dependent pipeline"
4063 self.init_repo("org/unknown")
4064 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4065 B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'B')
4066 A.addApproval('CRVW', 2)
4067 B.addApproval('CRVW', 2)
4068
4069 # A Depends-On: B
4070 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4071 A.subject, B.data['id'])
4072
4073 B.addApproval('APRV', 1)
4074 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4075 self.waitUntilSettled()
4076
4077 # Unknown projects cannot share a queue with any other
4078 # since they don't have common jobs with any other (they have no jobs).
4079 # Changes which depend on unknown project changes
4080 # should not be processed in dependent pipeline
4081 self.assertEqual(A.data['status'], 'NEW')
4082 self.assertEqual(B.data['status'], 'NEW')
4083 self.assertEqual(A.reported, 0)
4084 self.assertEqual(B.reported, 0)
4085 self.assertEqual(len(self.history), 0)
4086
4087 # Simulate change B being gated outside this layout
4088 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
4089 B.setMerged()
4090 self.waitUntilSettled()
4091 self.assertEqual(len(self.history), 0)
4092
4093 # Now that B is merged, A should be able to be enqueued and
4094 # merged.
4095 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4096 self.waitUntilSettled()
4097
4098 self.assertEqual(A.data['status'], 'MERGED')
4099 self.assertEqual(A.reported, 2)
4100 self.assertEqual(B.data['status'], 'MERGED')
4101 self.assertEqual(B.reported, 0)
4102
James E. Blairec056492016-07-22 09:45:56 -07004103 @skip("Disabled for early v3 development")
James E. Blairbfb8e042014-12-30 17:01:44 -08004104 def test_crd_check(self):
4105 "Test cross-repo dependencies in independent pipelines"
4106
4107 self.gearman_server.hold_jobs_in_queue = True
4108 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4109 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4110
4111 # A Depends-On: B
4112 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4113 A.subject, B.data['id'])
4114
4115 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4116 self.waitUntilSettled()
4117
4118 queue = self.gearman_server.getQueue()
4119 ref = self.getParameter(queue[-1], 'ZUUL_REF')
4120 self.gearman_server.hold_jobs_in_queue = False
4121 self.gearman_server.release()
4122 self.waitUntilSettled()
4123
4124 path = os.path.join(self.git_root, "org/project1")
4125 repo = git.Repo(path)
4126 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4127 repo_messages.reverse()
4128 correct_messages = ['initial commit', 'A-1']
4129 self.assertEqual(repo_messages, correct_messages)
4130
4131 path = os.path.join(self.git_root, "org/project2")
4132 repo = git.Repo(path)
4133 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4134 repo_messages.reverse()
4135 correct_messages = ['initial commit', 'B-1']
4136 self.assertEqual(repo_messages, correct_messages)
4137
4138 self.assertEqual(A.data['status'], 'NEW')
4139 self.assertEqual(B.data['status'], 'NEW')
4140 self.assertEqual(A.reported, 1)
4141 self.assertEqual(B.reported, 0)
4142
4143 self.assertEqual(self.history[0].changes, '2,1 1,1')
4144 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
James E. Blair8f78d882015-02-05 08:51:37 -08004145
James E. Blairec056492016-07-22 09:45:56 -07004146 @skip("Disabled for early v3 development")
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004147 def test_crd_check_git_depends(self):
4148 "Test single-repo dependencies in independent pipelines"
James E. Blairb8c16472015-05-05 14:55:26 -07004149 self.gearman_server.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004150 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4151 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4152
4153 # Add two git-dependent changes and make sure they both report
4154 # success.
4155 B.setDependsOn(A, 1)
4156 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4157 self.waitUntilSettled()
4158 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4159 self.waitUntilSettled()
4160
James E. Blairb8c16472015-05-05 14:55:26 -07004161 self.orderedRelease()
4162 self.gearman_server.hold_jobs_in_build = False
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004163 self.waitUntilSettled()
4164
4165 self.assertEqual(A.data['status'], 'NEW')
4166 self.assertEqual(B.data['status'], 'NEW')
4167 self.assertEqual(A.reported, 1)
4168 self.assertEqual(B.reported, 1)
4169
4170 self.assertEqual(self.history[0].changes, '1,1')
4171 self.assertEqual(self.history[-1].changes, '1,1 2,1')
4172 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
4173
4174 self.assertIn('Build succeeded', A.messages[0])
4175 self.assertIn('Build succeeded', B.messages[0])
4176
James E. Blairec056492016-07-22 09:45:56 -07004177 @skip("Disabled for early v3 development")
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004178 def test_crd_check_duplicate(self):
4179 "Test duplicate check in independent pipelines"
James E. Blair1e263032015-05-07 14:35:34 -07004180 self.worker.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004181 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4182 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4183 check_pipeline = self.sched.layout.pipelines['check']
4184
4185 # Add two git-dependent changes...
4186 B.setDependsOn(A, 1)
4187 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4188 self.waitUntilSettled()
4189 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4190
4191 # ...make sure the live one is not duplicated...
4192 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4193 self.waitUntilSettled()
4194 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4195
4196 # ...but the non-live one is able to be.
4197 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4198 self.waitUntilSettled()
4199 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4200
Clark Boylandd849822015-03-02 12:38:14 -08004201 # Release jobs in order to avoid races with change A jobs
4202 # finishing before change B jobs.
James E. Blaird7650852015-05-07 15:47:37 -07004203 self.orderedRelease()
James E. Blair1e263032015-05-07 14:35:34 -07004204 self.worker.hold_jobs_in_build = False
4205 self.worker.release()
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004206 self.waitUntilSettled()
4207
4208 self.assertEqual(A.data['status'], 'NEW')
4209 self.assertEqual(B.data['status'], 'NEW')
4210 self.assertEqual(A.reported, 1)
4211 self.assertEqual(B.reported, 1)
4212
4213 self.assertEqual(self.history[0].changes, '1,1 2,1')
4214 self.assertEqual(self.history[1].changes, '1,1')
4215 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
4216
4217 self.assertIn('Build succeeded', A.messages[0])
4218 self.assertIn('Build succeeded', B.messages[0])
4219
James E. Blairec056492016-07-22 09:45:56 -07004220 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004221 def _test_crd_check_reconfiguration(self, project1, project2):
James E. Blair8f78d882015-02-05 08:51:37 -08004222 "Test cross-repo dependencies re-enqueued in independent pipelines"
4223
4224 self.gearman_server.hold_jobs_in_queue = True
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004225 A = self.fake_gerrit.addFakeChange(project1, 'master', 'A')
4226 B = self.fake_gerrit.addFakeChange(project2, 'master', 'B')
James E. Blair8f78d882015-02-05 08:51:37 -08004227
4228 # A Depends-On: B
4229 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4230 A.subject, B.data['id'])
4231
4232 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4233 self.waitUntilSettled()
4234
4235 self.sched.reconfigure(self.config)
4236
4237 # Make sure the items still share a change queue, and the
4238 # first one is not live.
4239 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 1)
4240 queue = self.sched.layout.pipelines['check'].queues[0]
4241 first_item = queue.queue[0]
4242 for item in queue.queue:
4243 self.assertEqual(item.queue, first_item.queue)
4244 self.assertFalse(first_item.live)
4245 self.assertTrue(queue.queue[1].live)
4246
4247 self.gearman_server.hold_jobs_in_queue = False
4248 self.gearman_server.release()
4249 self.waitUntilSettled()
4250
4251 self.assertEqual(A.data['status'], 'NEW')
4252 self.assertEqual(B.data['status'], 'NEW')
4253 self.assertEqual(A.reported, 1)
4254 self.assertEqual(B.reported, 0)
4255
4256 self.assertEqual(self.history[0].changes, '2,1 1,1')
4257 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
James E. Blair17dd6772015-02-09 14:45:18 -08004258
James E. Blairec056492016-07-22 09:45:56 -07004259 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004260 def test_crd_check_reconfiguration(self):
4261 self._test_crd_check_reconfiguration('org/project1', 'org/project2')
4262
James E. Blairec056492016-07-22 09:45:56 -07004263 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004264 def test_crd_undefined_project(self):
4265 """Test that undefined projects in dependencies are handled for
4266 independent pipelines"""
4267 # It's a hack for fake gerrit,
4268 # as it implies repo creation upon the creation of any change
4269 self.init_repo("org/unknown")
4270 self._test_crd_check_reconfiguration('org/project1', 'org/unknown')
4271
James E. Blairec056492016-07-22 09:45:56 -07004272 @skip("Disabled for early v3 development")
James E. Blair17dd6772015-02-09 14:45:18 -08004273 def test_crd_check_ignore_dependencies(self):
4274 "Test cross-repo dependencies can be ignored"
James E. Blairf84026c2015-12-08 16:11:46 -08004275 self.updateConfigLayout(
4276 'tests/fixtures/layout-ignore-dependencies.yaml')
James E. Blair17dd6772015-02-09 14:45:18 -08004277 self.sched.reconfigure(self.config)
4278 self.registerJobs()
4279
4280 self.gearman_server.hold_jobs_in_queue = True
4281 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4282 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4283 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
4284
4285 # A Depends-On: B
4286 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4287 A.subject, B.data['id'])
4288 # C git-depends on B
4289 C.setDependsOn(B, 1)
4290 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4291 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4292 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4293 self.waitUntilSettled()
4294
4295 # Make sure none of the items share a change queue, and all
4296 # are live.
4297 check_pipeline = self.sched.layout.pipelines['check']
4298 self.assertEqual(len(check_pipeline.queues), 3)
4299 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4300 for item in check_pipeline.getAllItems():
4301 self.assertTrue(item.live)
4302
4303 self.gearman_server.hold_jobs_in_queue = False
4304 self.gearman_server.release()
4305 self.waitUntilSettled()
4306
4307 self.assertEqual(A.data['status'], 'NEW')
4308 self.assertEqual(B.data['status'], 'NEW')
4309 self.assertEqual(C.data['status'], 'NEW')
4310 self.assertEqual(A.reported, 1)
4311 self.assertEqual(B.reported, 1)
4312 self.assertEqual(C.reported, 1)
4313
4314 # Each job should have tested exactly one change
4315 for job in self.history:
4316 self.assertEqual(len(job.changes.split()), 1)
James E. Blair96698e22015-04-02 07:48:21 -07004317
James E. Blairec056492016-07-22 09:45:56 -07004318 @skip("Disabled for early v3 development")
James E. Blair96698e22015-04-02 07:48:21 -07004319 def test_crd_check_transitive(self):
4320 "Test transitive cross-repo dependencies"
4321 # Specifically, if A -> B -> C, and C gets a new patchset and
4322 # A gets a new patchset, ensure the test of A,2 includes B,1
4323 # and C,2 (not C,1 which would indicate stale data in the
4324 # cache for B).
4325 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4326 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4327 C = self.fake_gerrit.addFakeChange('org/project3', 'master', 'C')
4328
4329 # A Depends-On: B
4330 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4331 A.subject, B.data['id'])
4332
4333 # B Depends-On: C
4334 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4335 B.subject, C.data['id'])
4336
4337 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4338 self.waitUntilSettled()
4339 self.assertEqual(self.history[-1].changes, '3,1 2,1 1,1')
4340
4341 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4342 self.waitUntilSettled()
4343 self.assertEqual(self.history[-1].changes, '3,1 2,1')
4344
4345 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4346 self.waitUntilSettled()
4347 self.assertEqual(self.history[-1].changes, '3,1')
4348
4349 C.addPatchset()
4350 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(2))
4351 self.waitUntilSettled()
4352 self.assertEqual(self.history[-1].changes, '3,2')
4353
4354 A.addPatchset()
4355 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
4356 self.waitUntilSettled()
4357 self.assertEqual(self.history[-1].changes, '3,2 2,1 1,2')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004358
James E. Blairec056492016-07-22 09:45:56 -07004359 @skip("Disabled for early v3 development")
James E. Blair92464a22016-04-05 10:21:26 -07004360 def test_crd_cycle_join(self):
4361 "Test an updated change creates a cycle"
4362 A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A')
4363
4364 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4365 self.waitUntilSettled()
4366
4367 # Create B->A
4368 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4369 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4370 B.subject, A.data['id'])
4371 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4372 self.waitUntilSettled()
4373
4374 # Update A to add A->B (a cycle).
4375 A.addPatchset()
4376 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4377 A.subject, B.data['id'])
4378 # Normally we would submit the patchset-created event for
4379 # processing here, however, we have no way of noting whether
4380 # the dependency cycle detection correctly raised an
4381 # exception, so instead, we reach into the source driver and
4382 # call the method that would ultimately be called by the event
4383 # processing.
4384
4385 source = self.sched.layout.pipelines['gate'].source
4386 with testtools.ExpectedException(
4387 Exception, "Dependency cycle detected"):
4388 source._getChange(u'1', u'2', True)
4389 self.log.debug("Got expected dependency cycle exception")
4390
4391 # Now if we update B to remove the depends-on, everything
4392 # should be okay. B; A->B
4393
4394 B.addPatchset()
4395 B.data['commitMessage'] = '%s\n' % (B.subject,)
4396 source._getChange(u'1', u'2', True)
4397 source._getChange(u'2', u'2', True)
4398
James E. Blairec056492016-07-22 09:45:56 -07004399 @skip("Disabled for early v3 development")
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004400 def test_disable_at(self):
4401 "Test a pipeline will only report to the disabled trigger when failing"
4402
James E. Blairf84026c2015-12-08 16:11:46 -08004403 self.updateConfigLayout(
4404 'tests/fixtures/layout-disable-at.yaml')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004405 self.sched.reconfigure(self.config)
4406
4407 self.assertEqual(3, self.sched.layout.pipelines['check'].disable_at)
4408 self.assertEqual(
4409 0, self.sched.layout.pipelines['check']._consecutive_failures)
4410 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4411
4412 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4413 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
4414 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
4415 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
4416 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
4417 F = self.fake_gerrit.addFakeChange('org/project', 'master', 'F')
4418 G = self.fake_gerrit.addFakeChange('org/project', 'master', 'G')
4419 H = self.fake_gerrit.addFakeChange('org/project', 'master', 'H')
4420 I = self.fake_gerrit.addFakeChange('org/project', 'master', 'I')
4421 J = self.fake_gerrit.addFakeChange('org/project', 'master', 'J')
4422 K = self.fake_gerrit.addFakeChange('org/project', 'master', 'K')
4423
4424 self.worker.addFailTest('project-test1', A)
4425 self.worker.addFailTest('project-test1', B)
4426 # Let C pass, resetting the counter
4427 self.worker.addFailTest('project-test1', D)
4428 self.worker.addFailTest('project-test1', E)
4429 self.worker.addFailTest('project-test1', F)
4430 self.worker.addFailTest('project-test1', G)
4431 self.worker.addFailTest('project-test1', H)
4432 # I also passes but should only report to the disabled reporters
4433 self.worker.addFailTest('project-test1', J)
4434 self.worker.addFailTest('project-test1', K)
4435
4436 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4437 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4438 self.waitUntilSettled()
4439
4440 self.assertEqual(
4441 2, self.sched.layout.pipelines['check']._consecutive_failures)
4442 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4443
4444 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4445 self.waitUntilSettled()
4446
4447 self.assertEqual(
4448 0, self.sched.layout.pipelines['check']._consecutive_failures)
4449 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4450
4451 self.fake_gerrit.addEvent(D.getPatchsetCreatedEvent(1))
4452 self.fake_gerrit.addEvent(E.getPatchsetCreatedEvent(1))
4453 self.fake_gerrit.addEvent(F.getPatchsetCreatedEvent(1))
4454 self.waitUntilSettled()
4455
4456 # We should be disabled now
4457 self.assertEqual(
4458 3, self.sched.layout.pipelines['check']._consecutive_failures)
4459 self.assertTrue(self.sched.layout.pipelines['check']._disabled)
4460
4461 # We need to wait between each of these patches to make sure the
4462 # smtp messages come back in an expected order
4463 self.fake_gerrit.addEvent(G.getPatchsetCreatedEvent(1))
4464 self.waitUntilSettled()
4465 self.fake_gerrit.addEvent(H.getPatchsetCreatedEvent(1))
4466 self.waitUntilSettled()
4467 self.fake_gerrit.addEvent(I.getPatchsetCreatedEvent(1))
4468 self.waitUntilSettled()
4469
4470 # The first 6 (ABCDEF) jobs should have reported back to gerrt thus
4471 # leaving a message on each change
4472 self.assertEqual(1, len(A.messages))
4473 self.assertIn('Build failed.', A.messages[0])
4474 self.assertEqual(1, len(B.messages))
4475 self.assertIn('Build failed.', B.messages[0])
4476 self.assertEqual(1, len(C.messages))
4477 self.assertIn('Build succeeded.', C.messages[0])
4478 self.assertEqual(1, len(D.messages))
4479 self.assertIn('Build failed.', D.messages[0])
4480 self.assertEqual(1, len(E.messages))
4481 self.assertIn('Build failed.', E.messages[0])
4482 self.assertEqual(1, len(F.messages))
4483 self.assertIn('Build failed.', F.messages[0])
4484
4485 # The last 3 (GHI) would have only reported via smtp.
4486 self.assertEqual(3, len(self.smtp_messages))
4487 self.assertEqual(0, len(G.messages))
4488 self.assertIn('Build failed.', self.smtp_messages[0]['body'])
4489 self.assertIn('/7/1/check', self.smtp_messages[0]['body'])
4490 self.assertEqual(0, len(H.messages))
4491 self.assertIn('Build failed.', self.smtp_messages[1]['body'])
4492 self.assertIn('/8/1/check', self.smtp_messages[1]['body'])
4493 self.assertEqual(0, len(I.messages))
4494 self.assertIn('Build succeeded.', self.smtp_messages[2]['body'])
4495 self.assertIn('/9/1/check', self.smtp_messages[2]['body'])
4496
4497 # Now reload the configuration (simulate a HUP) to check the pipeline
4498 # comes out of disabled
4499 self.sched.reconfigure(self.config)
4500
4501 self.assertEqual(3, self.sched.layout.pipelines['check'].disable_at)
4502 self.assertEqual(
4503 0, self.sched.layout.pipelines['check']._consecutive_failures)
4504 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4505
4506 self.fake_gerrit.addEvent(J.getPatchsetCreatedEvent(1))
4507 self.fake_gerrit.addEvent(K.getPatchsetCreatedEvent(1))
4508 self.waitUntilSettled()
4509
4510 self.assertEqual(
4511 2, self.sched.layout.pipelines['check']._consecutive_failures)
4512 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4513
4514 # J and K went back to gerrit
4515 self.assertEqual(1, len(J.messages))
4516 self.assertIn('Build failed.', J.messages[0])
4517 self.assertEqual(1, len(K.messages))
4518 self.assertIn('Build failed.', K.messages[0])
4519 # No more messages reported via smtp
4520 self.assertEqual(3, len(self.smtp_messages))
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004521
James E. Blairec056492016-07-22 09:45:56 -07004522 @skip("Disabled for early v3 development")
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004523 def test_success_pattern(self):
4524 "Ensure bad build params are ignored"
4525
4526 # Use SMTP reporter to grab the result message easier
4527 self.init_repo("org/docs")
4528 self.config.set('zuul', 'layout_config',
4529 'tests/fixtures/layout-success-pattern.yaml')
4530 self.sched.reconfigure(self.config)
4531 self.worker.hold_jobs_in_build = True
4532 self.registerJobs()
4533
4534 A = self.fake_gerrit.addFakeChange('org/docs', 'master', 'A')
4535 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4536 self.waitUntilSettled()
4537
4538 # Grab build id
4539 self.assertEqual(len(self.builds), 1)
4540 uuid = self.builds[0].unique[:7]
4541
4542 self.worker.hold_jobs_in_build = False
4543 self.worker.release()
4544 self.waitUntilSettled()
4545
4546 self.assertEqual(len(self.smtp_messages), 1)
4547 body = self.smtp_messages[0]['body'].splitlines()
4548 self.assertEqual('Build succeeded.', body[0])
4549
4550 self.assertIn(
4551 '- docs-draft-test http://docs-draft.example.org/1/1/1/check/'
4552 'docs-draft-test/%s/publish-docs/' % uuid,
4553 body[2])
4554 self.assertIn(
4555 '- docs-draft-test2 https://server/job/docs-draft-test2/1/',
4556 body[3])