blob: 1be84a022c5229f1ff18c5478101b92325bf914b [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):
James E. Blair552b54f2016-07-22 13:55:32 -070047 tenant_config_file = 'config/single-tenant/main.yaml'
Antoine Mussobd86a312014-01-08 14:51:33 +010048
James E. Blairb0fcae42012-07-17 11:12:10 -070049 def test_jobs_launched(self):
50 "Test that jobs are launched and a change is merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -070051
James E. Blairb0fcae42012-07-17 11:12:10 -070052 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. 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. Blair552b54f2016-07-22 13:55:32 -070065 # TODOv3(jeblair): we may want to report stats by tenant (also?).
James E. Blair66eeebf2013-07-27 17:44:32 -070066 self.assertReportedStat('gerrit.event.comment-added', value='1|c')
67 self.assertReportedStat('zuul.pipeline.gate.current_changes',
68 value='1|g')
69 self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
70 kind='ms')
71 self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
72 value='1|c')
73 self.assertReportedStat('zuul.pipeline.gate.resident_time', kind='ms')
74 self.assertReportedStat('zuul.pipeline.gate.total_changes',
75 value='1|c')
James E. Blair412e5582013-04-22 15:50:12 -070076 self.assertReportedStat(
James E. Blair66eeebf2013-07-27 17:44:32 -070077 'zuul.pipeline.gate.org.project.resident_time', kind='ms')
James E. Blair412e5582013-04-22 15:50:12 -070078 self.assertReportedStat(
James E. Blair66eeebf2013-07-27 17:44:32 -070079 'zuul.pipeline.gate.org.project.total_changes', value='1|c')
James E. Blair412e5582013-04-22 15:50:12 -070080
James E. Blair5821bd92015-09-16 08:48:15 -070081 for build in self.builds:
82 self.assertEqual(build.parameters['ZUUL_VOTING'], '1')
83
James E. Blairec056492016-07-22 09:45:56 -070084 @skip("Disabled for early v3 development")
James E. Blair3cb10702013-08-24 08:56:03 -070085 def test_initial_pipeline_gauges(self):
86 "Test that each pipeline reported its length on start"
87 pipeline_names = self.sched.layout.pipelines.keys()
88 self.assertNotEqual(len(pipeline_names), 0)
89 for name in pipeline_names:
90 self.assertReportedStat('zuul.pipeline.%s.current_changes' % name,
91 value='0|g')
92
James E. Blairec056492016-07-22 09:45:56 -070093 @skip("Disabled for early v3 development")
James E. Blair42f74822013-05-14 15:18:03 -070094 def test_duplicate_pipelines(self):
95 "Test that a change matching multiple pipelines works"
James E. Blair1b4d9722013-05-21 10:32:04 -070096
James E. Blair42f74822013-05-14 15:18:03 -070097 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
98 self.fake_gerrit.addEvent(A.getChangeRestoredEvent())
99 self.waitUntilSettled()
James E. Blair42f74822013-05-14 15:18:03 -0700100
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400101 self.assertEqual(len(self.history), 2)
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400102 self.history[0].name == 'project-test1'
103 self.history[1].name == 'project-test1'
James E. Blair42f74822013-05-14 15:18:03 -0700104
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400105 self.assertEqual(len(A.messages), 2)
James E. Blair42f74822013-05-14 15:18:03 -0700106 if 'dup1/project-test1' in A.messages[0]:
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400107 self.assertIn('dup1/project-test1', A.messages[0])
108 self.assertNotIn('dup2/project-test1', A.messages[0])
109 self.assertNotIn('dup1/project-test1', A.messages[1])
110 self.assertIn('dup2/project-test1', A.messages[1])
James E. Blair42f74822013-05-14 15:18:03 -0700111 else:
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400112 self.assertIn('dup1/project-test1', A.messages[1])
113 self.assertNotIn('dup2/project-test1', A.messages[1])
114 self.assertNotIn('dup1/project-test1', A.messages[0])
115 self.assertIn('dup2/project-test1', A.messages[0])
James E. Blair42f74822013-05-14 15:18:03 -0700116
James E. Blairec056492016-07-22 09:45:56 -0700117 @skip("Disabled for early v3 development")
James E. Blairb0fcae42012-07-17 11:12:10 -0700118 def test_parallel_changes(self):
119 "Test that changes are tested in parallel and merged in series"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700120
121 self.worker.hold_jobs_in_build = True
James E. Blairb0fcae42012-07-17 11:12:10 -0700122 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
123 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
124 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700125 A.addApproval('CRVW', 2)
126 B.addApproval('CRVW', 2)
127 C.addApproval('CRVW', 2)
James E. Blairb0fcae42012-07-17 11:12:10 -0700128
129 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
130 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
131 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
132
133 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400134 self.assertEqual(len(self.builds), 1)
135 self.assertEqual(self.builds[0].name, 'project-merge')
136 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700137
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700138 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700139 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400140 self.assertEqual(len(self.builds), 3)
141 self.assertEqual(self.builds[0].name, 'project-test1')
142 self.assertTrue(self.job_has_changes(self.builds[0], A))
143 self.assertEqual(self.builds[1].name, 'project-test2')
144 self.assertTrue(self.job_has_changes(self.builds[1], A))
145 self.assertEqual(self.builds[2].name, 'project-merge')
146 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700147
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700148 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700149 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400150 self.assertEqual(len(self.builds), 5)
151 self.assertEqual(self.builds[0].name, 'project-test1')
152 self.assertTrue(self.job_has_changes(self.builds[0], A))
153 self.assertEqual(self.builds[1].name, 'project-test2')
154 self.assertTrue(self.job_has_changes(self.builds[1], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700155
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400156 self.assertEqual(self.builds[2].name, 'project-test1')
157 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
158 self.assertEqual(self.builds[3].name, 'project-test2')
159 self.assertTrue(self.job_has_changes(self.builds[3], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700160
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400161 self.assertEqual(self.builds[4].name, 'project-merge')
162 self.assertTrue(self.job_has_changes(self.builds[4], A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700163
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700164 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700165 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400166 self.assertEqual(len(self.builds), 6)
167 self.assertEqual(self.builds[0].name, 'project-test1')
168 self.assertTrue(self.job_has_changes(self.builds[0], A))
169 self.assertEqual(self.builds[1].name, 'project-test2')
170 self.assertTrue(self.job_has_changes(self.builds[1], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700171
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400172 self.assertEqual(self.builds[2].name, 'project-test1')
173 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
174 self.assertEqual(self.builds[3].name, 'project-test2')
175 self.assertTrue(self.job_has_changes(self.builds[3], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700176
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400177 self.assertEqual(self.builds[4].name, 'project-test1')
178 self.assertTrue(self.job_has_changes(self.builds[4], A, B, C))
179 self.assertEqual(self.builds[5].name, 'project-test2')
180 self.assertTrue(self.job_has_changes(self.builds[5], A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700181
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700182 self.worker.hold_jobs_in_build = False
183 self.worker.release()
James E. Blairb0fcae42012-07-17 11:12:10 -0700184 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400185 self.assertEqual(len(self.builds), 0)
James E. Blairb0fcae42012-07-17 11:12:10 -0700186
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400187 self.assertEqual(len(self.history), 9)
188 self.assertEqual(A.data['status'], 'MERGED')
189 self.assertEqual(B.data['status'], 'MERGED')
190 self.assertEqual(C.data['status'], 'MERGED')
191 self.assertEqual(A.reported, 2)
192 self.assertEqual(B.reported, 2)
193 self.assertEqual(C.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700194
James E. Blairec056492016-07-22 09:45:56 -0700195 @skip("Disabled for early v3 development")
James E. Blairb02a3bb2012-07-30 17:49:55 -0700196 def test_failed_changes(self):
197 "Test that a change behind a failed change is retested"
James E. Blaire2819012013-06-28 17:17:26 -0400198 self.worker.hold_jobs_in_build = True
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700199
James E. Blairb02a3bb2012-07-30 17:49:55 -0700200 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
201 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8c803f82012-07-31 16:25:42 -0700202 A.addApproval('CRVW', 2)
203 B.addApproval('CRVW', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700204
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700205 self.worker.addFailTest('project-test1', A)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700206
James E. Blaire2819012013-06-28 17:17:26 -0400207 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
208 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700209 self.waitUntilSettled()
James E. Blaire2819012013-06-28 17:17:26 -0400210
211 self.worker.release('.*-merge')
212 self.waitUntilSettled()
213
214 self.worker.hold_jobs_in_build = False
215 self.worker.release()
216
217 self.waitUntilSettled()
218 # It's certain that the merge job for change 2 will run, but
219 # the test1 and test2 jobs may or may not run.
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400220 self.assertTrue(len(self.history) > 6)
221 self.assertEqual(A.data['status'], 'NEW')
222 self.assertEqual(B.data['status'], 'MERGED')
223 self.assertEqual(A.reported, 2)
224 self.assertEqual(B.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700225
James E. Blairec056492016-07-22 09:45:56 -0700226 @skip("Disabled for early v3 development")
James E. Blairb02a3bb2012-07-30 17:49:55 -0700227 def test_independent_queues(self):
228 "Test that changes end up in the right queues"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700229
230 self.worker.hold_jobs_in_build = True
Zhongyue Luo5d556072012-09-21 02:00:47 +0900231 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700232 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
233 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700234 A.addApproval('CRVW', 2)
235 B.addApproval('CRVW', 2)
236 C.addApproval('CRVW', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700237
238 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
239 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
240 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
241
James E. Blairb02a3bb2012-07-30 17:49:55 -0700242 self.waitUntilSettled()
243
244 # There should be one merge job at the head of each queue running
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400245 self.assertEqual(len(self.builds), 2)
246 self.assertEqual(self.builds[0].name, 'project-merge')
247 self.assertTrue(self.job_has_changes(self.builds[0], A))
248 self.assertEqual(self.builds[1].name, 'project1-merge')
249 self.assertTrue(self.job_has_changes(self.builds[1], B))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700250
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700251 # Release the current merge builds
252 self.worker.release('.*-merge')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700253 self.waitUntilSettled()
254 # Release the merge job for project2 which is behind project1
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700255 self.worker.release('.*-merge')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700256 self.waitUntilSettled()
257
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700258 # All the test builds should be running:
James E. Blairb02a3bb2012-07-30 17:49:55 -0700259 # project1 (3) + project2 (3) + project (2) = 8
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400260 self.assertEqual(len(self.builds), 8)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700261
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700262 self.worker.release()
James E. Blairb02a3bb2012-07-30 17:49:55 -0700263 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400264 self.assertEqual(len(self.builds), 0)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700265
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400266 self.assertEqual(len(self.history), 11)
267 self.assertEqual(A.data['status'], 'MERGED')
268 self.assertEqual(B.data['status'], 'MERGED')
269 self.assertEqual(C.data['status'], 'MERGED')
270 self.assertEqual(A.reported, 2)
271 self.assertEqual(B.reported, 2)
272 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700273
James E. Blairec056492016-07-22 09:45:56 -0700274 @skip("Disabled for early v3 development")
James E. Blaird466dc42012-07-31 10:42:56 -0700275 def test_failed_change_at_head(self):
276 "Test that if a change at the head fails, jobs behind it are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700277
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700278 self.worker.hold_jobs_in_build = True
James E. Blaird466dc42012-07-31 10:42:56 -0700279 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
280 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
281 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700282 A.addApproval('CRVW', 2)
283 B.addApproval('CRVW', 2)
284 C.addApproval('CRVW', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700285
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700286 self.worker.addFailTest('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700287
288 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
289 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
290 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
291
292 self.waitUntilSettled()
James E. Blaird466dc42012-07-31 10:42:56 -0700293
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400294 self.assertEqual(len(self.builds), 1)
295 self.assertEqual(self.builds[0].name, 'project-merge')
296 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blaird466dc42012-07-31 10:42:56 -0700297
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700298 self.worker.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700299 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700300 self.worker.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700301 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700302 self.worker.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700303 self.waitUntilSettled()
304
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400305 self.assertEqual(len(self.builds), 6)
306 self.assertEqual(self.builds[0].name, 'project-test1')
307 self.assertEqual(self.builds[1].name, 'project-test2')
308 self.assertEqual(self.builds[2].name, 'project-test1')
309 self.assertEqual(self.builds[3].name, 'project-test2')
310 self.assertEqual(self.builds[4].name, 'project-test1')
311 self.assertEqual(self.builds[5].name, 'project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700312
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400313 self.release(self.builds[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700314 self.waitUntilSettled()
315
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400316 # project-test2, project-merge for B
317 self.assertEqual(len(self.builds), 2)
318 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 4)
James E. Blaird466dc42012-07-31 10:42:56 -0700319
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700320 self.worker.hold_jobs_in_build = False
321 self.worker.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700322 self.waitUntilSettled()
323
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400324 self.assertEqual(len(self.builds), 0)
325 self.assertEqual(len(self.history), 15)
326 self.assertEqual(A.data['status'], 'NEW')
327 self.assertEqual(B.data['status'], 'MERGED')
328 self.assertEqual(C.data['status'], 'MERGED')
329 self.assertEqual(A.reported, 2)
330 self.assertEqual(B.reported, 2)
331 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700332
James E. Blairec056492016-07-22 09:45:56 -0700333 @skip("Disabled for early v3 development")
James E. Blair0aac4872013-08-23 14:02:38 -0700334 def test_failed_change_in_middle(self):
335 "Test a failed change in the middle of the queue"
336
337 self.worker.hold_jobs_in_build = True
338 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
339 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
340 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
341 A.addApproval('CRVW', 2)
342 B.addApproval('CRVW', 2)
343 C.addApproval('CRVW', 2)
344
345 self.worker.addFailTest('project-test1', B)
346
347 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
348 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
349 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
350
351 self.waitUntilSettled()
352
353 self.worker.release('.*-merge')
354 self.waitUntilSettled()
355 self.worker.release('.*-merge')
356 self.waitUntilSettled()
357 self.worker.release('.*-merge')
358 self.waitUntilSettled()
359
360 self.assertEqual(len(self.builds), 6)
361 self.assertEqual(self.builds[0].name, 'project-test1')
362 self.assertEqual(self.builds[1].name, 'project-test2')
363 self.assertEqual(self.builds[2].name, 'project-test1')
364 self.assertEqual(self.builds[3].name, 'project-test2')
365 self.assertEqual(self.builds[4].name, 'project-test1')
366 self.assertEqual(self.builds[5].name, 'project-test2')
367
368 self.release(self.builds[2])
369 self.waitUntilSettled()
370
James E. Blair972e3c72013-08-29 12:04:55 -0700371 # project-test1 and project-test2 for A
372 # project-test2 for B
373 # project-merge for C (without B)
374 self.assertEqual(len(self.builds), 4)
James E. Blair0aac4872013-08-23 14:02:38 -0700375 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 2)
376
James E. Blair972e3c72013-08-29 12:04:55 -0700377 self.worker.release('.*-merge')
378 self.waitUntilSettled()
379
380 # project-test1 and project-test2 for A
381 # project-test2 for B
382 # project-test1 and project-test2 for C
383 self.assertEqual(len(self.builds), 5)
384
James E. Blair0aac4872013-08-23 14:02:38 -0700385 items = self.sched.layout.pipelines['gate'].getAllItems()
386 builds = items[0].current_build_set.getBuilds()
387 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
388 self.assertEqual(self.countJobResults(builds, None), 2)
389 builds = items[1].current_build_set.getBuilds()
390 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
391 self.assertEqual(self.countJobResults(builds, 'FAILURE'), 1)
392 self.assertEqual(self.countJobResults(builds, None), 1)
393 builds = items[2].current_build_set.getBuilds()
394 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
James E. Blair972e3c72013-08-29 12:04:55 -0700395 self.assertEqual(self.countJobResults(builds, None), 2)
James E. Blair0aac4872013-08-23 14:02:38 -0700396
397 self.worker.hold_jobs_in_build = False
398 self.worker.release()
399 self.waitUntilSettled()
400
401 self.assertEqual(len(self.builds), 0)
402 self.assertEqual(len(self.history), 12)
403 self.assertEqual(A.data['status'], 'MERGED')
404 self.assertEqual(B.data['status'], 'NEW')
405 self.assertEqual(C.data['status'], 'MERGED')
406 self.assertEqual(A.reported, 2)
407 self.assertEqual(B.reported, 2)
408 self.assertEqual(C.reported, 2)
409
James E. Blairec056492016-07-22 09:45:56 -0700410 @skip("Disabled for early v3 development")
James E. Blaird466dc42012-07-31 10:42:56 -0700411 def test_failed_change_at_head_with_queue(self):
412 "Test that if a change at the head fails, queued jobs are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700413
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700414 self.gearman_server.hold_jobs_in_queue = True
James E. Blaird466dc42012-07-31 10:42:56 -0700415 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
416 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
417 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700418 A.addApproval('CRVW', 2)
419 B.addApproval('CRVW', 2)
420 C.addApproval('CRVW', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700421
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700422 self.worker.addFailTest('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700423
424 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
425 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
426 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
427
428 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700429 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400430 self.assertEqual(len(self.builds), 0)
431 self.assertEqual(len(queue), 1)
432 self.assertEqual(queue[0].name, 'build:project-merge')
433 self.assertTrue(self.job_has_changes(queue[0], A))
James E. Blaird466dc42012-07-31 10:42:56 -0700434
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700435 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700436 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700437 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700438 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700439 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700440 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700441 queue = self.gearman_server.getQueue()
James E. Blaird466dc42012-07-31 10:42:56 -0700442
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400443 self.assertEqual(len(self.builds), 0)
444 self.assertEqual(len(queue), 6)
445 self.assertEqual(queue[0].name, 'build:project-test1')
446 self.assertEqual(queue[1].name, 'build:project-test2')
447 self.assertEqual(queue[2].name, 'build:project-test1')
448 self.assertEqual(queue[3].name, 'build:project-test2')
449 self.assertEqual(queue[4].name, 'build:project-test1')
450 self.assertEqual(queue[5].name, 'build:project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700451
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700452 self.release(queue[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700453 self.waitUntilSettled()
454
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400455 self.assertEqual(len(self.builds), 0)
James E. Blair701c5b42013-06-06 09:34:59 -0700456 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400457 self.assertEqual(len(queue), 2) # project-test2, project-merge for B
458 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 0)
James E. Blaird466dc42012-07-31 10:42:56 -0700459
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700460 self.gearman_server.hold_jobs_in_queue = False
461 self.gearman_server.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700462 self.waitUntilSettled()
463
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400464 self.assertEqual(len(self.builds), 0)
465 self.assertEqual(len(self.history), 11)
466 self.assertEqual(A.data['status'], 'NEW')
467 self.assertEqual(B.data['status'], 'MERGED')
468 self.assertEqual(C.data['status'], 'MERGED')
469 self.assertEqual(A.reported, 2)
470 self.assertEqual(B.reported, 2)
471 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700472
James E. Blairec056492016-07-22 09:45:56 -0700473 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700474 def _test_time_database(self, iteration):
475 self.worker.hold_jobs_in_build = True
476 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
477 A.addApproval('CRVW', 2)
478 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
479 self.waitUntilSettled()
480 time.sleep(2)
481
482 data = json.loads(self.sched.formatStatusJSON())
483 found_job = None
484 for pipeline in data['pipelines']:
485 if pipeline['name'] != 'gate':
486 continue
487 for queue in pipeline['change_queues']:
488 for head in queue['heads']:
489 for item in head:
490 for job in item['jobs']:
491 if job['name'] == 'project-merge':
492 found_job = job
493 break
494
495 self.assertIsNotNone(found_job)
496 if iteration == 1:
497 self.assertIsNotNone(found_job['estimated_time'])
498 self.assertIsNone(found_job['remaining_time'])
499 else:
500 self.assertIsNotNone(found_job['estimated_time'])
501 self.assertTrue(found_job['estimated_time'] >= 2)
502 self.assertIsNotNone(found_job['remaining_time'])
503
504 self.worker.hold_jobs_in_build = False
505 self.worker.release()
506 self.waitUntilSettled()
507
James E. Blairec056492016-07-22 09:45:56 -0700508 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700509 def test_time_database(self):
510 "Test the time database"
511
512 self._test_time_database(1)
513 self._test_time_database(2)
514
James E. Blairec056492016-07-22 09:45:56 -0700515 @skip("Disabled for early v3 development")
James E. Blairfef71632013-09-23 11:15:47 -0700516 def test_two_failed_changes_at_head(self):
517 "Test that changes are reparented correctly if 2 fail at head"
518
519 self.worker.hold_jobs_in_build = True
520 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
521 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
522 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
523 A.addApproval('CRVW', 2)
524 B.addApproval('CRVW', 2)
525 C.addApproval('CRVW', 2)
526
527 self.worker.addFailTest('project-test1', A)
528 self.worker.addFailTest('project-test1', B)
529
530 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
531 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
532 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
533 self.waitUntilSettled()
534
535 self.worker.release('.*-merge')
536 self.waitUntilSettled()
537 self.worker.release('.*-merge')
538 self.waitUntilSettled()
539 self.worker.release('.*-merge')
540 self.waitUntilSettled()
541
542 self.assertEqual(len(self.builds), 6)
543 self.assertEqual(self.builds[0].name, 'project-test1')
544 self.assertEqual(self.builds[1].name, 'project-test2')
545 self.assertEqual(self.builds[2].name, 'project-test1')
546 self.assertEqual(self.builds[3].name, 'project-test2')
547 self.assertEqual(self.builds[4].name, 'project-test1')
548 self.assertEqual(self.builds[5].name, 'project-test2')
549
550 self.assertTrue(self.job_has_changes(self.builds[0], A))
551 self.assertTrue(self.job_has_changes(self.builds[2], A))
552 self.assertTrue(self.job_has_changes(self.builds[2], B))
553 self.assertTrue(self.job_has_changes(self.builds[4], A))
554 self.assertTrue(self.job_has_changes(self.builds[4], B))
555 self.assertTrue(self.job_has_changes(self.builds[4], C))
556
557 # Fail change B first
558 self.release(self.builds[2])
559 self.waitUntilSettled()
560
561 # restart of C after B failure
562 self.worker.release('.*-merge')
563 self.waitUntilSettled()
564
565 self.assertEqual(len(self.builds), 5)
566 self.assertEqual(self.builds[0].name, 'project-test1')
567 self.assertEqual(self.builds[1].name, 'project-test2')
568 self.assertEqual(self.builds[2].name, 'project-test2')
569 self.assertEqual(self.builds[3].name, 'project-test1')
570 self.assertEqual(self.builds[4].name, 'project-test2')
571
572 self.assertTrue(self.job_has_changes(self.builds[1], A))
573 self.assertTrue(self.job_has_changes(self.builds[2], A))
574 self.assertTrue(self.job_has_changes(self.builds[2], B))
575 self.assertTrue(self.job_has_changes(self.builds[4], A))
576 self.assertFalse(self.job_has_changes(self.builds[4], B))
577 self.assertTrue(self.job_has_changes(self.builds[4], C))
578
579 # Finish running all passing jobs for change A
580 self.release(self.builds[1])
581 self.waitUntilSettled()
582 # Fail and report change A
583 self.release(self.builds[0])
584 self.waitUntilSettled()
585
586 # restart of B,C after A failure
587 self.worker.release('.*-merge')
588 self.waitUntilSettled()
589 self.worker.release('.*-merge')
590 self.waitUntilSettled()
591
592 self.assertEqual(len(self.builds), 4)
593 self.assertEqual(self.builds[0].name, 'project-test1') # B
594 self.assertEqual(self.builds[1].name, 'project-test2') # B
595 self.assertEqual(self.builds[2].name, 'project-test1') # C
596 self.assertEqual(self.builds[3].name, 'project-test2') # C
597
598 self.assertFalse(self.job_has_changes(self.builds[1], A))
599 self.assertTrue(self.job_has_changes(self.builds[1], B))
600 self.assertFalse(self.job_has_changes(self.builds[1], C))
601
602 self.assertFalse(self.job_has_changes(self.builds[2], A))
603 # After A failed and B and C restarted, B should be back in
604 # C's tests because it has not failed yet.
605 self.assertTrue(self.job_has_changes(self.builds[2], B))
606 self.assertTrue(self.job_has_changes(self.builds[2], C))
607
608 self.worker.hold_jobs_in_build = False
609 self.worker.release()
610 self.waitUntilSettled()
611
612 self.assertEqual(len(self.builds), 0)
613 self.assertEqual(len(self.history), 21)
614 self.assertEqual(A.data['status'], 'NEW')
615 self.assertEqual(B.data['status'], 'NEW')
616 self.assertEqual(C.data['status'], 'MERGED')
617 self.assertEqual(A.reported, 2)
618 self.assertEqual(B.reported, 2)
619 self.assertEqual(C.reported, 2)
620
James E. Blairec056492016-07-22 09:45:56 -0700621 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700622 def test_parse_skip_if(self):
623 job_yaml = """
624jobs:
625 - name: job_name
626 skip-if:
627 - project: ^project_name$
628 branch: ^stable/icehouse$
629 all-files-match-any:
630 - ^filename$
631 - project: ^project2_name$
632 all-files-match-any:
633 - ^filename2$
634 """.strip()
635 data = yaml.load(job_yaml)
636 config_job = data.get('jobs')[0]
637 cm = zuul.change_matcher
638 expected = cm.MatchAny([
639 cm.MatchAll([
640 cm.ProjectMatcher('^project_name$'),
641 cm.BranchMatcher('^stable/icehouse$'),
642 cm.MatchAllFiles([cm.FileMatcher('^filename$')]),
643 ]),
644 cm.MatchAll([
645 cm.ProjectMatcher('^project2_name$'),
646 cm.MatchAllFiles([cm.FileMatcher('^filename2$')]),
647 ]),
648 ])
649 matcher = self.sched._parseSkipIf(config_job)
650 self.assertEqual(expected, matcher)
651
James E. Blairec056492016-07-22 09:45:56 -0700652 @skip("Disabled for early v3 development")
James E. Blair8c803f82012-07-31 16:25:42 -0700653 def test_patch_order(self):
654 "Test that dependent patches are tested in the right order"
655 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
656 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
657 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
658 A.addApproval('CRVW', 2)
659 B.addApproval('CRVW', 2)
660 C.addApproval('CRVW', 2)
661
662 M2 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M2')
663 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
664 M2.setMerged()
665 M1.setMerged()
666
667 # C -> B -> A -> M1 -> M2
668 # M2 is here to make sure it is never queried. If it is, it
669 # means zuul is walking down the entire history of merged
670 # changes.
671
672 C.setDependsOn(B, 1)
673 B.setDependsOn(A, 1)
674 A.setDependsOn(M1, 1)
675 M1.setDependsOn(M2, 1)
676
677 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
678
679 self.waitUntilSettled()
680
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400681 self.assertEqual(A.data['status'], 'NEW')
682 self.assertEqual(B.data['status'], 'NEW')
683 self.assertEqual(C.data['status'], 'NEW')
James E. Blair8c803f82012-07-31 16:25:42 -0700684
685 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
686 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
687
688 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400689 self.assertEqual(M2.queried, 0)
690 self.assertEqual(A.data['status'], 'MERGED')
691 self.assertEqual(B.data['status'], 'MERGED')
692 self.assertEqual(C.data['status'], 'MERGED')
693 self.assertEqual(A.reported, 2)
694 self.assertEqual(B.reported, 2)
695 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700696
James E. Blairec056492016-07-22 09:45:56 -0700697 @skip("Disabled for early v3 development")
James E. Blair063672f2015-01-29 13:09:12 -0800698 def test_needed_changes_enqueue(self):
699 "Test that a needed change is enqueued ahead"
700 # A Given a git tree like this, if we enqueue
701 # / \ change C, we should walk up and down the tree
702 # B G and enqueue changes in the order ABCDEFG.
703 # /|\ This is also the order that you would get if
704 # *C E F you enqueued changes in the order ABCDEFG, so
705 # / the ordering is stable across re-enqueue events.
706 # D
707
708 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
709 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
710 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
711 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
712 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
713 F = self.fake_gerrit.addFakeChange('org/project', 'master', 'F')
714 G = self.fake_gerrit.addFakeChange('org/project', 'master', 'G')
715 B.setDependsOn(A, 1)
716 C.setDependsOn(B, 1)
717 D.setDependsOn(C, 1)
718 E.setDependsOn(B, 1)
719 F.setDependsOn(B, 1)
720 G.setDependsOn(A, 1)
721
722 A.addApproval('CRVW', 2)
723 B.addApproval('CRVW', 2)
724 C.addApproval('CRVW', 2)
725 D.addApproval('CRVW', 2)
726 E.addApproval('CRVW', 2)
727 F.addApproval('CRVW', 2)
728 G.addApproval('CRVW', 2)
729 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
730
731 self.waitUntilSettled()
732
733 self.assertEqual(A.data['status'], 'NEW')
734 self.assertEqual(B.data['status'], 'NEW')
735 self.assertEqual(C.data['status'], 'NEW')
736 self.assertEqual(D.data['status'], 'NEW')
737 self.assertEqual(E.data['status'], 'NEW')
738 self.assertEqual(F.data['status'], 'NEW')
739 self.assertEqual(G.data['status'], 'NEW')
740
741 # We're about to add approvals to changes without adding the
742 # triggering events to Zuul, so that we can be sure that it is
743 # enqueing the changes based on dependencies, not because of
744 # triggering events. Since it will have the changes cached
745 # already (without approvals), we need to clear the cache
746 # first.
Joshua Hesketh4bd7da32016-02-17 20:58:47 +1100747 for connection in self.connections.values():
748 connection.maintainCache([])
James E. Blair063672f2015-01-29 13:09:12 -0800749
750 self.worker.hold_jobs_in_build = True
751 A.addApproval('APRV', 1)
752 B.addApproval('APRV', 1)
753 D.addApproval('APRV', 1)
754 E.addApproval('APRV', 1)
755 F.addApproval('APRV', 1)
756 G.addApproval('APRV', 1)
757 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
758
759 for x in range(8):
760 self.worker.release('.*-merge')
761 self.waitUntilSettled()
762 self.worker.hold_jobs_in_build = False
763 self.worker.release()
764 self.waitUntilSettled()
765
766 self.assertEqual(A.data['status'], 'MERGED')
767 self.assertEqual(B.data['status'], 'MERGED')
768 self.assertEqual(C.data['status'], 'MERGED')
769 self.assertEqual(D.data['status'], 'MERGED')
770 self.assertEqual(E.data['status'], 'MERGED')
771 self.assertEqual(F.data['status'], 'MERGED')
772 self.assertEqual(G.data['status'], 'MERGED')
773 self.assertEqual(A.reported, 2)
774 self.assertEqual(B.reported, 2)
775 self.assertEqual(C.reported, 2)
776 self.assertEqual(D.reported, 2)
777 self.assertEqual(E.reported, 2)
778 self.assertEqual(F.reported, 2)
779 self.assertEqual(G.reported, 2)
780 self.assertEqual(self.history[6].changes,
781 '1,1 2,1 3,1 4,1 5,1 6,1 7,1')
782
James E. Blairec056492016-07-22 09:45:56 -0700783 @skip("Disabled for early v3 development")
Joshua Hesketh850ccb62014-11-27 11:31:02 +1100784 def test_source_cache(self):
785 "Test that the source cache operates correctly"
James E. Blair0e933c52013-07-11 10:18:52 -0700786 self.worker.hold_jobs_in_build = True
787
788 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
789 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
790 X = self.fake_gerrit.addFakeChange('org/project', 'master', 'X')
791 A.addApproval('CRVW', 2)
792 B.addApproval('CRVW', 2)
793
794 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
795 M1.setMerged()
796
797 B.setDependsOn(A, 1)
798 A.setDependsOn(M1, 1)
799
800 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
801 self.fake_gerrit.addEvent(X.getPatchsetCreatedEvent(1))
802
803 self.waitUntilSettled()
804
805 for build in self.builds:
806 if build.parameters['ZUUL_PIPELINE'] == 'check':
807 build.release()
808 self.waitUntilSettled()
809 for build in self.builds:
810 if build.parameters['ZUUL_PIPELINE'] == 'check':
811 build.release()
812 self.waitUntilSettled()
813
814 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
815 self.waitUntilSettled()
816
Joshua Hesketh352264b2015-08-11 23:42:08 +1000817 self.log.debug("len %s" % self.fake_gerrit._change_cache.keys())
James E. Blair0e933c52013-07-11 10:18:52 -0700818 # there should still be changes in the cache
Joshua Hesketh352264b2015-08-11 23:42:08 +1000819 self.assertNotEqual(len(self.fake_gerrit._change_cache.keys()), 0)
James E. Blair0e933c52013-07-11 10:18:52 -0700820
821 self.worker.hold_jobs_in_build = False
822 self.worker.release()
823 self.waitUntilSettled()
824
825 self.assertEqual(A.data['status'], 'MERGED')
826 self.assertEqual(B.data['status'], 'MERGED')
827 self.assertEqual(A.queried, 2) # Initial and isMerged
828 self.assertEqual(B.queried, 3) # Initial A, refresh from B, isMerged
829
James E. Blairec056492016-07-22 09:45:56 -0700830 @skip("Disabled for early v3 development")
James E. Blair8c803f82012-07-31 16:25:42 -0700831 def test_can_merge(self):
James E. Blair4886cc12012-07-18 15:39:41 -0700832 "Test whether a change is ready to merge"
James E. Blair8c803f82012-07-31 16:25:42 -0700833 # TODO: move to test_gerrit (this is a unit test!)
834 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairc0dedf82014-08-06 09:37:52 -0700835 source = self.sched.layout.pipelines['gate'].source
836 a = source._getChange(1, 2)
James E. Blaireff88162013-07-01 12:44:14 -0400837 mgr = self.sched.layout.pipelines['gate'].manager
James E. Blairc0dedf82014-08-06 09:37:52 -0700838 self.assertFalse(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700839
840 A.addApproval('CRVW', 2)
James E. Blairc0dedf82014-08-06 09:37:52 -0700841 a = source._getChange(1, 2, refresh=True)
842 self.assertFalse(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700843
844 A.addApproval('APRV', 1)
James E. Blairc0dedf82014-08-06 09:37:52 -0700845 a = source._getChange(1, 2, refresh=True)
846 self.assertTrue(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair4886cc12012-07-18 15:39:41 -0700847
James E. Blairec056492016-07-22 09:45:56 -0700848 @skip("Disabled for early v3 development")
James E. Blair4886cc12012-07-18 15:39:41 -0700849 def test_build_configuration(self):
850 "Test that zuul merges the right commits for testing"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700851
852 self.gearman_server.hold_jobs_in_queue = True
James E. Blair4886cc12012-07-18 15:39:41 -0700853 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
854 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
855 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
856 A.addApproval('CRVW', 2)
857 B.addApproval('CRVW', 2)
858 C.addApproval('CRVW', 2)
859 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
860 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
861 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
862 self.waitUntilSettled()
863
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700864 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700865 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700866 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700867 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700868 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700869 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700870 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700871 ref = self.getParameter(queue[-1], 'ZUUL_REF')
872 self.gearman_server.hold_jobs_in_queue = False
873 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700874 self.waitUntilSettled()
James E. Blair4886cc12012-07-18 15:39:41 -0700875
Monty Taylorbc758832013-06-17 17:22:42 -0400876 path = os.path.join(self.git_root, "org/project")
James E. Blair4886cc12012-07-18 15:39:41 -0700877 repo = git.Repo(path)
878 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
879 repo_messages.reverse()
James E. Blair4886cc12012-07-18 15:39:41 -0700880 correct_messages = ['initial commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400881 self.assertEqual(repo_messages, correct_messages)
James E. Blair973721f2012-08-15 10:19:43 -0700882
James E. Blairec056492016-07-22 09:45:56 -0700883 @skip("Disabled for early v3 development")
James E. Blair973721f2012-08-15 10:19:43 -0700884 def test_build_configuration_conflict(self):
885 "Test that merge conflicts are handled"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700886
887 self.gearman_server.hold_jobs_in_queue = True
James E. Blair6736beb2013-07-11 15:18:15 -0700888 A = self.fake_gerrit.addFakeChange('org/conflict-project',
889 'master', 'A')
James E. Blair973721f2012-08-15 10:19:43 -0700890 A.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700891 B = self.fake_gerrit.addFakeChange('org/conflict-project',
892 'master', 'B')
James E. Blair973721f2012-08-15 10:19:43 -0700893 B.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700894 C = self.fake_gerrit.addFakeChange('org/conflict-project',
895 'master', 'C')
James E. Blair973721f2012-08-15 10:19:43 -0700896 A.addApproval('CRVW', 2)
897 B.addApproval('CRVW', 2)
898 C.addApproval('CRVW', 2)
899 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
900 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
901 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
902 self.waitUntilSettled()
903
James E. Blair6736beb2013-07-11 15:18:15 -0700904 self.assertEqual(A.reported, 1)
905 self.assertEqual(B.reported, 1)
906 self.assertEqual(C.reported, 1)
907
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700908 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700909 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700910 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700911 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700912 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700913 self.waitUntilSettled()
James E. Blair972e3c72013-08-29 12:04:55 -0700914
915 self.assertEqual(len(self.history), 2) # A and C merge jobs
916
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700917 self.gearman_server.hold_jobs_in_queue = False
918 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700919 self.waitUntilSettled()
920
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400921 self.assertEqual(A.data['status'], 'MERGED')
922 self.assertEqual(B.data['status'], 'NEW')
923 self.assertEqual(C.data['status'], 'MERGED')
924 self.assertEqual(A.reported, 2)
925 self.assertEqual(B.reported, 2)
926 self.assertEqual(C.reported, 2)
James E. Blair972e3c72013-08-29 12:04:55 -0700927 self.assertEqual(len(self.history), 6)
James E. Blair6736beb2013-07-11 15:18:15 -0700928
James E. Blairec056492016-07-22 09:45:56 -0700929 @skip("Disabled for early v3 development")
James E. Blairdaabed22012-08-15 15:38:57 -0700930 def test_post(self):
931 "Test that post jobs run"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700932
Zhongyue Luo5d556072012-09-21 02:00:47 +0900933 e = {
934 "type": "ref-updated",
935 "submitter": {
936 "name": "User Name",
937 },
938 "refUpdate": {
939 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
940 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
941 "refName": "master",
942 "project": "org/project",
943 }
944 }
James E. Blairdaabed22012-08-15 15:38:57 -0700945 self.fake_gerrit.addEvent(e)
946 self.waitUntilSettled()
947
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400948 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400949 self.assertEqual(len(self.history), 1)
950 self.assertIn('project-post', job_names)
James E. Blairc6294a52012-08-17 10:19:48 -0700951
James E. Blairec056492016-07-22 09:45:56 -0700952 @skip("Disabled for early v3 development")
K Jonathan Harkerf95e7232015-04-29 13:33:16 -0700953 def test_post_ignore_deletes(self):
954 "Test that deleting refs does not trigger post jobs"
955
956 e = {
957 "type": "ref-updated",
958 "submitter": {
959 "name": "User Name",
960 },
961 "refUpdate": {
962 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
963 "newRev": "0000000000000000000000000000000000000000",
964 "refName": "master",
965 "project": "org/project",
966 }
967 }
968 self.fake_gerrit.addEvent(e)
969 self.waitUntilSettled()
970
971 job_names = [x.name for x in self.history]
972 self.assertEqual(len(self.history), 0)
973 self.assertNotIn('project-post', job_names)
974
James E. Blairec056492016-07-22 09:45:56 -0700975 @skip("Disabled for early v3 development")
K Jonathan Harkerf95e7232015-04-29 13:33:16 -0700976 def test_post_ignore_deletes_negative(self):
977 "Test that deleting refs does trigger post jobs"
978
James E. Blairf84026c2015-12-08 16:11:46 -0800979 self.updateConfigLayout(
980 'tests/fixtures/layout-dont-ignore-deletes.yaml')
K Jonathan Harkerf95e7232015-04-29 13:33:16 -0700981 self.sched.reconfigure(self.config)
982
983 e = {
984 "type": "ref-updated",
985 "submitter": {
986 "name": "User Name",
987 },
988 "refUpdate": {
989 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
990 "newRev": "0000000000000000000000000000000000000000",
991 "refName": "master",
992 "project": "org/project",
993 }
994 }
995 self.fake_gerrit.addEvent(e)
996 self.waitUntilSettled()
997
998 job_names = [x.name for x in self.history]
999 self.assertEqual(len(self.history), 1)
1000 self.assertIn('project-post', job_names)
1001
James E. Blairec056492016-07-22 09:45:56 -07001002 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001003 def test_build_configuration_branch(self):
1004 "Test that the right commits are on alternate branches"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001005
1006 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -07001007 A = self.fake_gerrit.addFakeChange('org/project', 'mp', 'A')
1008 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
1009 C = self.fake_gerrit.addFakeChange('org/project', 'mp', 'C')
1010 A.addApproval('CRVW', 2)
1011 B.addApproval('CRVW', 2)
1012 C.addApproval('CRVW', 2)
1013 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1014 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1015 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1016 self.waitUntilSettled()
1017
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001018 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001019 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001020 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001021 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001022 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001023 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001024 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001025 ref = self.getParameter(queue[-1], 'ZUUL_REF')
1026 self.gearman_server.hold_jobs_in_queue = False
1027 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -07001028 self.waitUntilSettled()
1029
Monty Taylorbc758832013-06-17 17:22:42 -04001030 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001031 repo = git.Repo(path)
1032 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
1033 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001034 correct_messages = ['initial commit', 'mp commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001035 self.assertEqual(repo_messages, correct_messages)
James E. Blairc6294a52012-08-17 10:19:48 -07001036
James E. Blairec056492016-07-22 09:45:56 -07001037 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001038 def test_build_configuration_branch_interaction(self):
1039 "Test that switching between branches works"
1040 self.test_build_configuration()
1041 self.test_build_configuration_branch()
1042 # C has been merged, undo that
Monty Taylorbc758832013-06-17 17:22:42 -04001043 path = os.path.join(self.upstream_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001044 repo = git.Repo(path)
1045 repo.heads.master.commit = repo.commit('init')
1046 self.test_build_configuration()
1047
James E. Blairec056492016-07-22 09:45:56 -07001048 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001049 def test_build_configuration_multi_branch(self):
1050 "Test that dependent changes on multiple branches are merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001051
1052 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -07001053 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1054 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
1055 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1056 A.addApproval('CRVW', 2)
1057 B.addApproval('CRVW', 2)
1058 C.addApproval('CRVW', 2)
1059 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1060 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1061 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1062 self.waitUntilSettled()
James E. Blairbb1fe502014-03-04 10:15:06 -08001063 queue = self.gearman_server.getQueue()
1064 job_A = None
1065 for job in queue:
1066 if 'project-merge' in job.name:
1067 job_A = job
1068 ref_A = self.getParameter(job_A, 'ZUUL_REF')
1069 commit_A = self.getParameter(job_A, 'ZUUL_COMMIT')
1070 self.log.debug("Got Zuul ref for change A: %s" % ref_A)
1071 self.log.debug("Got Zuul commit for change A: %s" % commit_A)
James E. Blairc6294a52012-08-17 10:19:48 -07001072
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001073 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001074 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001075 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -07001076 job_B = None
1077 for job in queue:
1078 if 'project-merge' in job.name:
1079 job_B = job
1080 ref_B = self.getParameter(job_B, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -08001081 commit_B = self.getParameter(job_B, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -07001082 self.log.debug("Got Zuul ref for change B: %s" % ref_B)
James E. Blairbb1fe502014-03-04 10:15:06 -08001083 self.log.debug("Got Zuul commit for change B: %s" % commit_B)
1084
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001085 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001086 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001087 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -07001088 for job in queue:
1089 if 'project-merge' in job.name:
1090 job_C = job
1091 ref_C = self.getParameter(job_C, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -08001092 commit_C = self.getParameter(job_C, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -07001093 self.log.debug("Got Zuul ref for change C: %s" % ref_C)
James E. Blairbb1fe502014-03-04 10:15:06 -08001094 self.log.debug("Got Zuul commit for change C: %s" % commit_C)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001095 self.gearman_server.hold_jobs_in_queue = False
1096 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -07001097 self.waitUntilSettled()
1098
Monty Taylorbc758832013-06-17 17:22:42 -04001099 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001100 repo = git.Repo(path)
1101
1102 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -07001103 for c in repo.iter_commits(ref_C)]
James E. Blairbb1fe502014-03-04 10:15:06 -08001104 repo_shas = [c.hexsha for c in repo.iter_commits(ref_C)]
James E. Blairc6294a52012-08-17 10:19:48 -07001105 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001106 correct_messages = ['initial commit', 'A-1', 'C-1']
James E. Blairbb1fe502014-03-04 10:15:06 -08001107 # Ensure the right commits are in the history for this ref
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001108 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -08001109 # Ensure ZUUL_REF -> ZUUL_COMMIT
1110 self.assertEqual(repo_shas[0], commit_C)
James E. Blairc6294a52012-08-17 10:19:48 -07001111
1112 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -07001113 for c in repo.iter_commits(ref_B)]
James E. Blairbb1fe502014-03-04 10:15:06 -08001114 repo_shas = [c.hexsha for c in repo.iter_commits(ref_B)]
James E. Blairc6294a52012-08-17 10:19:48 -07001115 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001116 correct_messages = ['initial commit', 'mp commit', 'B-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001117 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -08001118 self.assertEqual(repo_shas[0], commit_B)
1119
1120 repo_messages = [c.message.strip()
1121 for c in repo.iter_commits(ref_A)]
1122 repo_shas = [c.hexsha for c in repo.iter_commits(ref_A)]
1123 repo_messages.reverse()
1124 correct_messages = ['initial commit', 'A-1']
1125 self.assertEqual(repo_messages, correct_messages)
1126 self.assertEqual(repo_shas[0], commit_A)
1127
1128 self.assertNotEqual(ref_A, ref_B, ref_C)
1129 self.assertNotEqual(commit_A, commit_B, commit_C)
James E. Blair7f71c802012-08-22 13:04:32 -07001130
James E. Blairec056492016-07-22 09:45:56 -07001131 @skip("Disabled for early v3 development")
James E. Blair7f71c802012-08-22 13:04:32 -07001132 def test_one_job_project(self):
1133 "Test that queueing works with one job"
1134 A = self.fake_gerrit.addFakeChange('org/one-job-project',
1135 'master', 'A')
1136 B = self.fake_gerrit.addFakeChange('org/one-job-project',
1137 'master', 'B')
1138 A.addApproval('CRVW', 2)
1139 B.addApproval('CRVW', 2)
1140 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1141 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1142 self.waitUntilSettled()
1143
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001144 self.assertEqual(A.data['status'], 'MERGED')
1145 self.assertEqual(A.reported, 2)
1146 self.assertEqual(B.data['status'], 'MERGED')
1147 self.assertEqual(B.reported, 2)
James E. Blaircaec0c52012-08-22 14:52:22 -07001148
James E. Blairec056492016-07-22 09:45:56 -07001149 @skip("Disabled for early v3 development")
Antoine Musso80edd5a2013-02-13 15:37:53 +01001150 def test_job_from_templates_launched(self):
1151 "Test whether a job generated via a template can be launched"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001152
Antoine Musso80edd5a2013-02-13 15:37:53 +01001153 A = self.fake_gerrit.addFakeChange(
1154 'org/templated-project', 'master', 'A')
1155 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1156 self.waitUntilSettled()
Antoine Musso80edd5a2013-02-13 15:37:53 +01001157
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001158 self.assertEqual(self.getJobFromHistory('project-test1').result,
1159 'SUCCESS')
1160 self.assertEqual(self.getJobFromHistory('project-test2').result,
1161 'SUCCESS')
Antoine Musso80edd5a2013-02-13 15:37:53 +01001162
James E. Blairec056492016-07-22 09:45:56 -07001163 @skip("Disabled for early v3 development")
James E. Blair3e98c022013-12-16 15:25:38 -08001164 def test_layered_templates(self):
1165 "Test whether a job generated via a template can be launched"
1166
1167 A = self.fake_gerrit.addFakeChange(
1168 'org/layered-project', 'master', 'A')
1169 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1170 self.waitUntilSettled()
1171
1172 self.assertEqual(self.getJobFromHistory('project-test1').result,
1173 'SUCCESS')
1174 self.assertEqual(self.getJobFromHistory('project-test2').result,
1175 'SUCCESS')
James E. Blairaea6cf62013-12-16 15:38:12 -08001176 self.assertEqual(self.getJobFromHistory('layered-project-test3'
1177 ).result, 'SUCCESS')
1178 self.assertEqual(self.getJobFromHistory('layered-project-test4'
1179 ).result, 'SUCCESS')
James E. Blair12a92b12014-03-26 11:54:53 -07001180 self.assertEqual(self.getJobFromHistory('layered-project-foo-test5'
1181 ).result, 'SUCCESS')
James E. Blair3e98c022013-12-16 15:25:38 -08001182 self.assertEqual(self.getJobFromHistory('project-test6').result,
1183 'SUCCESS')
1184
James E. Blairec056492016-07-22 09:45:56 -07001185 @skip("Disabled for early v3 development")
James E. Blaircaec0c52012-08-22 14:52:22 -07001186 def test_dependent_changes_dequeue(self):
1187 "Test that dependent patches are not needlessly tested"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001188
James E. Blaircaec0c52012-08-22 14:52:22 -07001189 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1190 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1191 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1192 A.addApproval('CRVW', 2)
1193 B.addApproval('CRVW', 2)
1194 C.addApproval('CRVW', 2)
1195
1196 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
1197 M1.setMerged()
1198
1199 # C -> B -> A -> M1
1200
1201 C.setDependsOn(B, 1)
1202 B.setDependsOn(A, 1)
1203 A.setDependsOn(M1, 1)
1204
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001205 self.worker.addFailTest('project-merge', A)
James E. Blaircaec0c52012-08-22 14:52:22 -07001206
1207 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1208 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1209 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1210
1211 self.waitUntilSettled()
1212
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001213 self.assertEqual(A.data['status'], 'NEW')
1214 self.assertEqual(A.reported, 2)
1215 self.assertEqual(B.data['status'], 'NEW')
1216 self.assertEqual(B.reported, 2)
1217 self.assertEqual(C.data['status'], 'NEW')
1218 self.assertEqual(C.reported, 2)
1219 self.assertEqual(len(self.history), 1)
James E. Blairec590122012-08-22 15:19:31 -07001220
James E. Blairec056492016-07-22 09:45:56 -07001221 @skip("Disabled for early v3 development")
James E. Blair972e3c72013-08-29 12:04:55 -07001222 def test_failing_dependent_changes(self):
1223 "Test that failing dependent patches are taken out of stream"
1224 self.worker.hold_jobs_in_build = True
1225 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1226 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1227 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1228 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1229 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
1230 A.addApproval('CRVW', 2)
1231 B.addApproval('CRVW', 2)
1232 C.addApproval('CRVW', 2)
1233 D.addApproval('CRVW', 2)
1234 E.addApproval('CRVW', 2)
1235
1236 # E, D -> C -> B, A
1237
1238 D.setDependsOn(C, 1)
1239 C.setDependsOn(B, 1)
1240
1241 self.worker.addFailTest('project-test1', B)
1242
1243 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1244 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1245 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1246 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1247 self.fake_gerrit.addEvent(E.addApproval('APRV', 1))
1248
1249 self.waitUntilSettled()
1250 self.worker.release('.*-merge')
1251 self.waitUntilSettled()
1252 self.worker.release('.*-merge')
1253 self.waitUntilSettled()
1254 self.worker.release('.*-merge')
1255 self.waitUntilSettled()
1256 self.worker.release('.*-merge')
1257 self.waitUntilSettled()
1258 self.worker.release('.*-merge')
1259 self.waitUntilSettled()
1260
1261 self.worker.hold_jobs_in_build = False
1262 for build in self.builds:
1263 if build.parameters['ZUUL_CHANGE'] != '1':
1264 build.release()
1265 self.waitUntilSettled()
1266
1267 self.worker.release()
1268 self.waitUntilSettled()
1269
1270 self.assertEqual(A.data['status'], 'MERGED')
1271 self.assertEqual(A.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001272 self.assertIn('Build succeeded', A.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001273 self.assertEqual(B.data['status'], 'NEW')
1274 self.assertEqual(B.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001275 self.assertIn('Build failed', B.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001276 self.assertEqual(C.data['status'], 'NEW')
1277 self.assertEqual(C.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001278 self.assertIn('depends on a change', C.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001279 self.assertEqual(D.data['status'], 'NEW')
1280 self.assertEqual(D.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001281 self.assertIn('depends on a change', D.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001282 self.assertEqual(E.data['status'], 'MERGED')
1283 self.assertEqual(E.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001284 self.assertIn('Build succeeded', E.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001285 self.assertEqual(len(self.history), 18)
1286
James E. Blairec056492016-07-22 09:45:56 -07001287 @skip("Disabled for early v3 development")
James E. Blairec590122012-08-22 15:19:31 -07001288 def test_head_is_dequeued_once(self):
James E. Blair2fa50962013-01-30 21:50:41 -08001289 "Test that if a change at the head fails it is dequeued only once"
James E. Blairec590122012-08-22 15:19:31 -07001290 # If it's dequeued more than once, we should see extra
1291 # aborted jobs.
James E. Blairec590122012-08-22 15:19:31 -07001292
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001293 self.worker.hold_jobs_in_build = True
James E. Blairec590122012-08-22 15:19:31 -07001294 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1295 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1296 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
1297 A.addApproval('CRVW', 2)
1298 B.addApproval('CRVW', 2)
1299 C.addApproval('CRVW', 2)
1300
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001301 self.worker.addFailTest('project1-test1', A)
1302 self.worker.addFailTest('project1-test2', A)
1303 self.worker.addFailTest('project1-project2-integration', A)
James E. Blairec590122012-08-22 15:19:31 -07001304
1305 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1306 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1307 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1308
1309 self.waitUntilSettled()
James E. Blairec590122012-08-22 15:19:31 -07001310
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001311 self.assertEqual(len(self.builds), 1)
1312 self.assertEqual(self.builds[0].name, 'project1-merge')
1313 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blairec590122012-08-22 15:19:31 -07001314
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001315 self.worker.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001316 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001317 self.worker.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001318 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001319 self.worker.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001320 self.waitUntilSettled()
1321
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001322 self.assertEqual(len(self.builds), 9)
1323 self.assertEqual(self.builds[0].name, 'project1-test1')
1324 self.assertEqual(self.builds[1].name, 'project1-test2')
1325 self.assertEqual(self.builds[2].name, 'project1-project2-integration')
1326 self.assertEqual(self.builds[3].name, 'project1-test1')
1327 self.assertEqual(self.builds[4].name, 'project1-test2')
1328 self.assertEqual(self.builds[5].name, 'project1-project2-integration')
1329 self.assertEqual(self.builds[6].name, 'project1-test1')
1330 self.assertEqual(self.builds[7].name, 'project1-test2')
1331 self.assertEqual(self.builds[8].name, 'project1-project2-integration')
James E. Blairec590122012-08-22 15:19:31 -07001332
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001333 self.release(self.builds[0])
James E. Blairec590122012-08-22 15:19:31 -07001334 self.waitUntilSettled()
1335
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001336 self.assertEqual(len(self.builds), 3) # test2,integration, merge for B
1337 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 6)
James E. Blairec590122012-08-22 15:19:31 -07001338
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001339 self.worker.hold_jobs_in_build = False
1340 self.worker.release()
James E. Blairec590122012-08-22 15:19:31 -07001341 self.waitUntilSettled()
1342
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001343 self.assertEqual(len(self.builds), 0)
1344 self.assertEqual(len(self.history), 20)
James E. Blaircaec0c52012-08-22 14:52:22 -07001345
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001346 self.assertEqual(A.data['status'], 'NEW')
1347 self.assertEqual(B.data['status'], 'MERGED')
1348 self.assertEqual(C.data['status'], 'MERGED')
1349 self.assertEqual(A.reported, 2)
1350 self.assertEqual(B.reported, 2)
1351 self.assertEqual(C.reported, 2)
James E. Blair4ec821f2012-08-23 15:28:28 -07001352
James E. Blairec056492016-07-22 09:45:56 -07001353 @skip("Disabled for early v3 development")
James E. Blair4ec821f2012-08-23 15:28:28 -07001354 def test_nonvoting_job(self):
1355 "Test that non-voting jobs don't vote."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001356
James E. Blair4ec821f2012-08-23 15:28:28 -07001357 A = self.fake_gerrit.addFakeChange('org/nonvoting-project',
1358 'master', 'A')
1359 A.addApproval('CRVW', 2)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001360 self.worker.addFailTest('nonvoting-project-test2', A)
James E. Blair4ec821f2012-08-23 15:28:28 -07001361 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1362
1363 self.waitUntilSettled()
James E. Blair4ec821f2012-08-23 15:28:28 -07001364
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001365 self.assertEqual(A.data['status'], 'MERGED')
1366 self.assertEqual(A.reported, 2)
1367 self.assertEqual(
1368 self.getJobFromHistory('nonvoting-project-merge').result,
1369 'SUCCESS')
1370 self.assertEqual(
1371 self.getJobFromHistory('nonvoting-project-test1').result,
1372 'SUCCESS')
1373 self.assertEqual(
1374 self.getJobFromHistory('nonvoting-project-test2').result,
1375 'FAILURE')
James E. Blaire0487072012-08-29 17:38:31 -07001376
James E. Blair5821bd92015-09-16 08:48:15 -07001377 for build in self.builds:
1378 self.assertEqual(build.parameters['ZUUL_VOTING'], '0')
1379
James E. Blairec056492016-07-22 09:45:56 -07001380 @skip("Disabled for early v3 development")
James E. Blaire0487072012-08-29 17:38:31 -07001381 def test_check_queue_success(self):
1382 "Test successful check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001383
James E. Blaire0487072012-08-29 17:38:31 -07001384 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1385 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1386
1387 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001388
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001389 self.assertEqual(A.data['status'], 'NEW')
1390 self.assertEqual(A.reported, 1)
1391 self.assertEqual(self.getJobFromHistory('project-merge').result,
1392 'SUCCESS')
1393 self.assertEqual(self.getJobFromHistory('project-test1').result,
1394 'SUCCESS')
1395 self.assertEqual(self.getJobFromHistory('project-test2').result,
1396 'SUCCESS')
James E. Blaire0487072012-08-29 17:38:31 -07001397
James E. Blairec056492016-07-22 09:45:56 -07001398 @skip("Disabled for early v3 development")
James E. Blaire0487072012-08-29 17:38:31 -07001399 def test_check_queue_failure(self):
1400 "Test failed check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001401
James E. Blaire0487072012-08-29 17:38:31 -07001402 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001403 self.worker.addFailTest('project-test2', A)
James E. Blaire0487072012-08-29 17:38:31 -07001404 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1405
1406 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001407
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001408 self.assertEqual(A.data['status'], 'NEW')
1409 self.assertEqual(A.reported, 1)
1410 self.assertEqual(self.getJobFromHistory('project-merge').result,
James E. Blair78e31b32013-07-09 09:11:34 -07001411 'SUCCESS')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001412 self.assertEqual(self.getJobFromHistory('project-test1').result,
1413 'SUCCESS')
1414 self.assertEqual(self.getJobFromHistory('project-test2').result,
1415 'FAILURE')
James E. Blair127bc182012-08-28 15:55:15 -07001416
James E. Blairec056492016-07-22 09:45:56 -07001417 @skip("Disabled for early v3 development")
James E. Blair127bc182012-08-28 15:55:15 -07001418 def test_dependent_behind_dequeue(self):
1419 "test that dependent changes behind dequeued changes work"
1420 # This complicated test is a reproduction of a real life bug
1421 self.sched.reconfigure(self.config)
James E. Blair127bc182012-08-28 15:55:15 -07001422
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001423 self.worker.hold_jobs_in_build = True
James E. Blair127bc182012-08-28 15:55:15 -07001424 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1425 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1426 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
1427 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
1428 E = self.fake_gerrit.addFakeChange('org/project2', 'master', 'E')
1429 F = self.fake_gerrit.addFakeChange('org/project3', 'master', 'F')
1430 D.setDependsOn(C, 1)
1431 E.setDependsOn(D, 1)
1432 A.addApproval('CRVW', 2)
1433 B.addApproval('CRVW', 2)
1434 C.addApproval('CRVW', 2)
1435 D.addApproval('CRVW', 2)
1436 E.addApproval('CRVW', 2)
1437 F.addApproval('CRVW', 2)
1438
1439 A.fail_merge = True
James E. Blair127bc182012-08-28 15:55:15 -07001440
1441 # Change object re-use in the gerrit trigger is hidden if
1442 # changes are added in quick succession; waiting makes it more
1443 # like real life.
1444 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1445 self.waitUntilSettled()
1446 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1447 self.waitUntilSettled()
1448
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001449 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001450 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001451 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001452 self.waitUntilSettled()
1453
1454 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1455 self.waitUntilSettled()
1456 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1457 self.waitUntilSettled()
1458 self.fake_gerrit.addEvent(E.addApproval('APRV', 1))
1459 self.waitUntilSettled()
1460 self.fake_gerrit.addEvent(F.addApproval('APRV', 1))
1461 self.waitUntilSettled()
1462
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001463 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001464 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001465 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001466 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001467 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001468 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001469 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001470 self.waitUntilSettled()
1471
1472 # all jobs running
James E. Blaire955e062012-10-08 09:49:03 -07001473
1474 # Grab pointers to the jobs we want to release before
1475 # releasing any, because list indexes may change as
1476 # the jobs complete.
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001477 a, b, c = self.builds[:3]
James E. Blaire955e062012-10-08 09:49:03 -07001478 a.release()
1479 b.release()
1480 c.release()
James E. Blair127bc182012-08-28 15:55:15 -07001481 self.waitUntilSettled()
1482
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001483 self.worker.hold_jobs_in_build = False
1484 self.worker.release()
James E. Blair127bc182012-08-28 15:55:15 -07001485 self.waitUntilSettled()
1486
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001487 self.assertEqual(A.data['status'], 'NEW')
1488 self.assertEqual(B.data['status'], 'MERGED')
1489 self.assertEqual(C.data['status'], 'MERGED')
1490 self.assertEqual(D.data['status'], 'MERGED')
1491 self.assertEqual(E.data['status'], 'MERGED')
1492 self.assertEqual(F.data['status'], 'MERGED')
James E. Blair127bc182012-08-28 15:55:15 -07001493
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001494 self.assertEqual(A.reported, 2)
1495 self.assertEqual(B.reported, 2)
1496 self.assertEqual(C.reported, 2)
1497 self.assertEqual(D.reported, 2)
1498 self.assertEqual(E.reported, 2)
1499 self.assertEqual(F.reported, 2)
James E. Blair127bc182012-08-28 15:55:15 -07001500
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001501 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 15)
1502 self.assertEqual(len(self.history), 44)
James E. Blair05fed602012-09-07 12:45:24 -07001503
James E. Blairec056492016-07-22 09:45:56 -07001504 @skip("Disabled for early v3 development")
James E. Blair05fed602012-09-07 12:45:24 -07001505 def test_merger_repack(self):
1506 "Test that the merger works after a repack"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001507
James E. Blair05fed602012-09-07 12:45:24 -07001508 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1509 A.addApproval('CRVW', 2)
1510 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1511 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001512 self.assertEqual(self.getJobFromHistory('project-merge').result,
1513 'SUCCESS')
1514 self.assertEqual(self.getJobFromHistory('project-test1').result,
1515 'SUCCESS')
1516 self.assertEqual(self.getJobFromHistory('project-test2').result,
1517 'SUCCESS')
1518 self.assertEqual(A.data['status'], 'MERGED')
1519 self.assertEqual(A.reported, 2)
James E. Blair05fed602012-09-07 12:45:24 -07001520 self.assertEmptyQueues()
James E. Blair4ca985f2013-05-30 12:27:43 -07001521 self.worker.build_history = []
James E. Blair05fed602012-09-07 12:45:24 -07001522
Monty Taylorbc758832013-06-17 17:22:42 -04001523 path = os.path.join(self.git_root, "org/project")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001524 print(repack_repo(path))
James E. Blair05fed602012-09-07 12:45:24 -07001525
1526 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1527 A.addApproval('CRVW', 2)
1528 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1529 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001530 self.assertEqual(self.getJobFromHistory('project-merge').result,
1531 'SUCCESS')
1532 self.assertEqual(self.getJobFromHistory('project-test1').result,
1533 'SUCCESS')
1534 self.assertEqual(self.getJobFromHistory('project-test2').result,
1535 'SUCCESS')
1536 self.assertEqual(A.data['status'], 'MERGED')
1537 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001538
James E. Blairec056492016-07-22 09:45:56 -07001539 @skip("Disabled for early v3 development")
James E. Blair4886f282012-11-15 09:27:33 -08001540 def test_merger_repack_large_change(self):
1541 "Test that the merger works with large changes after a repack"
1542 # https://bugs.launchpad.net/zuul/+bug/1078946
James E. Blairac2c3242014-01-24 13:38:51 -08001543 # This test assumes the repo is already cloned; make sure it is
Joshua Hesketh352264b2015-08-11 23:42:08 +10001544 url = self.fake_gerrit.getGitUrl(
James E. Blairac2c3242014-01-24 13:38:51 -08001545 self.sched.layout.projects['org/project1'])
James E. Blair4076e2b2014-01-28 12:42:20 -08001546 self.merge_server.merger.addProject('org/project1', url)
James E. Blair4886f282012-11-15 09:27:33 -08001547 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1548 A.addPatchset(large=True)
Monty Taylorbc758832013-06-17 17:22:42 -04001549 path = os.path.join(self.upstream_root, "org/project1")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001550 print(repack_repo(path))
Monty Taylorbc758832013-06-17 17:22:42 -04001551 path = os.path.join(self.git_root, "org/project1")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001552 print(repack_repo(path))
James E. Blair4886f282012-11-15 09:27:33 -08001553
1554 A.addApproval('CRVW', 2)
1555 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1556 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001557 self.assertEqual(self.getJobFromHistory('project1-merge').result,
1558 'SUCCESS')
1559 self.assertEqual(self.getJobFromHistory('project1-test1').result,
1560 'SUCCESS')
1561 self.assertEqual(self.getJobFromHistory('project1-test2').result,
1562 'SUCCESS')
1563 self.assertEqual(A.data['status'], 'MERGED')
1564 self.assertEqual(A.reported, 2)
James E. Blair4886f282012-11-15 09:27:33 -08001565
James E. Blairec056492016-07-22 09:45:56 -07001566 @skip("Disabled for early v3 development")
James E. Blair7ee88a22012-09-12 18:59:31 +02001567 def test_nonexistent_job(self):
1568 "Test launching a job that doesn't exist"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001569 # Set to the state immediately after a restart
1570 self.resetGearmanServer()
1571 self.launcher.negative_function_cache_ttl = 0
James E. Blair7ee88a22012-09-12 18:59:31 +02001572
1573 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1574 A.addApproval('CRVW', 2)
1575 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1576 # There may be a thread about to report a lost change
1577 while A.reported < 2:
1578 self.waitUntilSettled()
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001579 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001580 self.assertFalse(job_names)
1581 self.assertEqual(A.data['status'], 'NEW')
1582 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001583 self.assertEmptyQueues()
1584
1585 # Make sure things still work:
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001586 self.registerJobs()
James E. Blair7ee88a22012-09-12 18:59:31 +02001587 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1588 A.addApproval('CRVW', 2)
1589 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1590 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001591 self.assertEqual(self.getJobFromHistory('project-merge').result,
1592 'SUCCESS')
1593 self.assertEqual(self.getJobFromHistory('project-test1').result,
1594 'SUCCESS')
1595 self.assertEqual(self.getJobFromHistory('project-test2').result,
1596 'SUCCESS')
1597 self.assertEqual(A.data['status'], 'MERGED')
1598 self.assertEqual(A.reported, 2)
James E. Blairf62d4282012-12-31 17:01:50 -08001599
James E. Blairec056492016-07-22 09:45:56 -07001600 @skip("Disabled for early v3 development")
James E. Blairf62d4282012-12-31 17:01:50 -08001601 def test_single_nonexistent_post_job(self):
1602 "Test launching a single post job that doesn't exist"
James E. Blairf62d4282012-12-31 17:01:50 -08001603 e = {
1604 "type": "ref-updated",
1605 "submitter": {
1606 "name": "User Name",
1607 },
1608 "refUpdate": {
1609 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
1610 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
1611 "refName": "master",
1612 "project": "org/project",
1613 }
1614 }
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001615 # Set to the state immediately after a restart
1616 self.resetGearmanServer()
1617 self.launcher.negative_function_cache_ttl = 0
1618
James E. Blairf62d4282012-12-31 17:01:50 -08001619 self.fake_gerrit.addEvent(e)
1620 self.waitUntilSettled()
1621
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001622 self.assertEqual(len(self.history), 0)
James E. Blair2fa50962013-01-30 21:50:41 -08001623
James E. Blairec056492016-07-22 09:45:56 -07001624 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001625 def test_new_patchset_dequeues_old(self):
1626 "Test that a new patchset causes the old to be dequeued"
1627 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001628 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001629 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1630 M.setMerged()
1631
1632 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1633 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1634 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1635 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1636 A.addApproval('CRVW', 2)
1637 B.addApproval('CRVW', 2)
1638 C.addApproval('CRVW', 2)
1639 D.addApproval('CRVW', 2)
1640
1641 C.setDependsOn(B, 1)
1642 B.setDependsOn(A, 1)
1643 A.setDependsOn(M, 1)
1644
1645 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1646 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1647 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1648 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1649 self.waitUntilSettled()
1650
1651 B.addPatchset()
1652 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1653 self.waitUntilSettled()
1654
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001655 self.worker.hold_jobs_in_build = False
1656 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001657 self.waitUntilSettled()
1658
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001659 self.assertEqual(A.data['status'], 'MERGED')
1660 self.assertEqual(A.reported, 2)
1661 self.assertEqual(B.data['status'], 'NEW')
1662 self.assertEqual(B.reported, 2)
1663 self.assertEqual(C.data['status'], 'NEW')
1664 self.assertEqual(C.reported, 2)
1665 self.assertEqual(D.data['status'], 'MERGED')
1666 self.assertEqual(D.reported, 2)
1667 self.assertEqual(len(self.history), 9) # 3 each for A, B, D.
James E. Blair2fa50962013-01-30 21:50:41 -08001668
James E. Blairec056492016-07-22 09:45:56 -07001669 @skip("Disabled for early v3 development")
James E. Blairba437362015-02-07 11:41:52 -08001670 def test_new_patchset_check(self):
1671 "Test a new patchset in check"
Antoine Mussobd86a312014-01-08 14:51:33 +01001672
1673 self.worker.hold_jobs_in_build = True
1674
1675 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairba437362015-02-07 11:41:52 -08001676 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1677 check_pipeline = self.sched.layout.pipelines['check']
1678
1679 # Add two git-dependent changes
1680 B.setDependsOn(A, 1)
1681 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1682 self.waitUntilSettled()
Antoine Mussobd86a312014-01-08 14:51:33 +01001683 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1684 self.waitUntilSettled()
James E. Blairba437362015-02-07 11:41:52 -08001685
1686 # A live item, and a non-live/live pair
1687 items = check_pipeline.getAllItems()
1688 self.assertEqual(len(items), 3)
1689
1690 self.assertEqual(items[0].change.number, '1')
1691 self.assertEqual(items[0].change.patchset, '1')
1692 self.assertFalse(items[0].live)
1693
1694 self.assertEqual(items[1].change.number, '2')
1695 self.assertEqual(items[1].change.patchset, '1')
1696 self.assertTrue(items[1].live)
1697
1698 self.assertEqual(items[2].change.number, '1')
1699 self.assertEqual(items[2].change.patchset, '1')
1700 self.assertTrue(items[2].live)
1701
1702 # Add a new patchset to A
1703 A.addPatchset()
1704 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1705 self.waitUntilSettled()
1706
1707 # The live copy of A,1 should be gone, but the non-live and B
1708 # should continue, and we should have a new A,2
1709 items = check_pipeline.getAllItems()
1710 self.assertEqual(len(items), 3)
1711
1712 self.assertEqual(items[0].change.number, '1')
1713 self.assertEqual(items[0].change.patchset, '1')
1714 self.assertFalse(items[0].live)
1715
1716 self.assertEqual(items[1].change.number, '2')
1717 self.assertEqual(items[1].change.patchset, '1')
1718 self.assertTrue(items[1].live)
1719
1720 self.assertEqual(items[2].change.number, '1')
1721 self.assertEqual(items[2].change.patchset, '2')
1722 self.assertTrue(items[2].live)
1723
1724 # Add a new patchset to B
1725 B.addPatchset()
1726 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1727 self.waitUntilSettled()
1728
1729 # The live copy of B,1 should be gone, and it's non-live copy of A,1
1730 # but we should have a new B,2 (still based on A,1)
1731 items = check_pipeline.getAllItems()
1732 self.assertEqual(len(items), 3)
1733
1734 self.assertEqual(items[0].change.number, '1')
1735 self.assertEqual(items[0].change.patchset, '2')
1736 self.assertTrue(items[0].live)
1737
1738 self.assertEqual(items[1].change.number, '1')
1739 self.assertEqual(items[1].change.patchset, '1')
1740 self.assertFalse(items[1].live)
1741
1742 self.assertEqual(items[2].change.number, '2')
1743 self.assertEqual(items[2].change.patchset, '2')
1744 self.assertTrue(items[2].live)
1745
1746 self.builds[0].release()
1747 self.waitUntilSettled()
1748 self.builds[0].release()
1749 self.waitUntilSettled()
1750 self.worker.hold_jobs_in_build = False
1751 self.worker.release()
1752 self.waitUntilSettled()
1753
1754 self.assertEqual(A.reported, 1)
1755 self.assertEqual(B.reported, 1)
1756 self.assertEqual(self.history[0].result, 'ABORTED')
1757 self.assertEqual(self.history[0].changes, '1,1')
1758 self.assertEqual(self.history[1].result, 'ABORTED')
1759 self.assertEqual(self.history[1].changes, '1,1 2,1')
1760 self.assertEqual(self.history[2].result, 'SUCCESS')
1761 self.assertEqual(self.history[2].changes, '1,2')
1762 self.assertEqual(self.history[3].result, 'SUCCESS')
1763 self.assertEqual(self.history[3].changes, '1,1 2,2')
1764
James E. Blairec056492016-07-22 09:45:56 -07001765 @skip("Disabled for early v3 development")
James E. Blairba437362015-02-07 11:41:52 -08001766 def test_abandoned_gate(self):
1767 "Test that an abandoned change is dequeued from gate"
1768
1769 self.worker.hold_jobs_in_build = True
1770
1771 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1772 A.addApproval('CRVW', 2)
1773 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1774 self.waitUntilSettled()
Antoine Mussobd86a312014-01-08 14:51:33 +01001775 self.assertEqual(len(self.builds), 1, "One job being built (on hold)")
1776 self.assertEqual(self.builds[0].name, 'project-merge')
1777
1778 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1779 self.waitUntilSettled()
1780
Antoine Mussobd86a312014-01-08 14:51:33 +01001781 self.worker.release('.*-merge')
1782 self.waitUntilSettled()
1783
1784 self.assertEqual(len(self.builds), 0, "No job running")
Antoine Mussobd86a312014-01-08 14:51:33 +01001785 self.assertEqual(len(self.history), 1, "Only one build in history")
1786 self.assertEqual(self.history[0].result, 'ABORTED',
James E. Blairba437362015-02-07 11:41:52 -08001787 "Build should have been aborted")
1788 self.assertEqual(A.reported, 1,
1789 "Abandoned gate change should report only start")
1790
James E. Blairec056492016-07-22 09:45:56 -07001791 @skip("Disabled for early v3 development")
James E. Blairba437362015-02-07 11:41:52 -08001792 def test_abandoned_check(self):
1793 "Test that an abandoned change is dequeued from check"
1794
1795 self.worker.hold_jobs_in_build = True
1796
1797 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1798 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1799 check_pipeline = self.sched.layout.pipelines['check']
1800
1801 # Add two git-dependent changes
1802 B.setDependsOn(A, 1)
1803 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1804 self.waitUntilSettled()
1805 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1806 self.waitUntilSettled()
1807 # A live item, and a non-live/live pair
1808 items = check_pipeline.getAllItems()
1809 self.assertEqual(len(items), 3)
1810
1811 self.assertEqual(items[0].change.number, '1')
1812 self.assertFalse(items[0].live)
1813
1814 self.assertEqual(items[1].change.number, '2')
1815 self.assertTrue(items[1].live)
1816
1817 self.assertEqual(items[2].change.number, '1')
1818 self.assertTrue(items[2].live)
1819
1820 # Abandon A
1821 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1822 self.waitUntilSettled()
1823
1824 # The live copy of A should be gone, but the non-live and B
1825 # should continue
1826 items = check_pipeline.getAllItems()
1827 self.assertEqual(len(items), 2)
1828
1829 self.assertEqual(items[0].change.number, '1')
1830 self.assertFalse(items[0].live)
1831
1832 self.assertEqual(items[1].change.number, '2')
1833 self.assertTrue(items[1].live)
1834
1835 self.worker.hold_jobs_in_build = False
1836 self.worker.release()
1837 self.waitUntilSettled()
1838
1839 self.assertEqual(len(self.history), 4)
1840 self.assertEqual(self.history[0].result, 'ABORTED',
Antoine Mussobd86a312014-01-08 14:51:33 +01001841 'Build should have been aborted')
1842 self.assertEqual(A.reported, 0, "Abandoned change should not report")
James E. Blairba437362015-02-07 11:41:52 -08001843 self.assertEqual(B.reported, 1, "Change should report")
Antoine Mussobd86a312014-01-08 14:51:33 +01001844
James E. Blairec056492016-07-22 09:45:56 -07001845 @skip("Disabled for early v3 development")
Steve Varnau7b78b312015-04-03 14:49:46 -07001846 def test_abandoned_not_timer(self):
1847 "Test that an abandoned change does not cancel timer jobs"
1848
1849 self.worker.hold_jobs_in_build = True
1850
1851 # Start timer trigger - also org/project
James E. Blairf84026c2015-12-08 16:11:46 -08001852 self.updateConfigLayout(
1853 'tests/fixtures/layout-idle.yaml')
Steve Varnau7b78b312015-04-03 14:49:46 -07001854 self.sched.reconfigure(self.config)
1855 self.registerJobs()
1856 # The pipeline triggers every second, so we should have seen
1857 # several by now.
1858 time.sleep(5)
1859 self.waitUntilSettled()
1860 # Stop queuing timer triggered jobs so that the assertions
1861 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08001862 self.updateConfigLayout(
1863 'tests/fixtures/layout-no-timer.yaml')
Steve Varnau7b78b312015-04-03 14:49:46 -07001864 self.sched.reconfigure(self.config)
1865 self.registerJobs()
1866 self.assertEqual(len(self.builds), 2, "Two timer jobs")
1867
1868 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1869 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1870 self.waitUntilSettled()
1871 self.assertEqual(len(self.builds), 3, "One change plus two timer jobs")
1872
1873 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1874 self.waitUntilSettled()
1875
1876 self.assertEqual(len(self.builds), 2, "Two timer jobs remain")
1877
1878 self.worker.release()
1879 self.waitUntilSettled()
1880
James E. Blairec056492016-07-22 09:45:56 -07001881 @skip("Disabled for early v3 development")
Arx Cruzb1b010d2013-10-28 19:49:59 -02001882 def test_zuul_url_return(self):
1883 "Test if ZUUL_URL is returning when zuul_url is set in zuul.conf"
James E. Blair4076e2b2014-01-28 12:42:20 -08001884 self.assertTrue(self.sched.config.has_option('merger', 'zuul_url'))
Arx Cruzb1b010d2013-10-28 19:49:59 -02001885 self.worker.hold_jobs_in_build = True
1886
1887 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1888 A.addApproval('CRVW', 2)
1889 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1890 self.waitUntilSettled()
1891
1892 self.assertEqual(len(self.builds), 1)
1893 for build in self.builds:
1894 self.assertTrue('ZUUL_URL' in build.parameters)
1895
1896 self.worker.hold_jobs_in_build = False
1897 self.worker.release()
1898 self.waitUntilSettled()
1899
James E. Blairec056492016-07-22 09:45:56 -07001900 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001901 def test_new_patchset_dequeues_old_on_head(self):
1902 "Test that a new patchset causes the old to be dequeued (at head)"
1903 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001904 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001905 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1906 M.setMerged()
1907 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1908 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1909 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1910 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1911 A.addApproval('CRVW', 2)
1912 B.addApproval('CRVW', 2)
1913 C.addApproval('CRVW', 2)
1914 D.addApproval('CRVW', 2)
1915
1916 C.setDependsOn(B, 1)
1917 B.setDependsOn(A, 1)
1918 A.setDependsOn(M, 1)
1919
1920 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1921 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1922 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1923 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1924 self.waitUntilSettled()
1925
1926 A.addPatchset()
1927 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1928 self.waitUntilSettled()
1929
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001930 self.worker.hold_jobs_in_build = False
1931 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001932 self.waitUntilSettled()
1933
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001934 self.assertEqual(A.data['status'], 'NEW')
1935 self.assertEqual(A.reported, 2)
1936 self.assertEqual(B.data['status'], 'NEW')
1937 self.assertEqual(B.reported, 2)
1938 self.assertEqual(C.data['status'], 'NEW')
1939 self.assertEqual(C.reported, 2)
1940 self.assertEqual(D.data['status'], 'MERGED')
1941 self.assertEqual(D.reported, 2)
1942 self.assertEqual(len(self.history), 7)
James E. Blair2fa50962013-01-30 21:50:41 -08001943
James E. Blairec056492016-07-22 09:45:56 -07001944 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001945 def test_new_patchset_dequeues_old_without_dependents(self):
1946 "Test that a new patchset causes only the old to be dequeued"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001947 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001948 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1949 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1950 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1951 A.addApproval('CRVW', 2)
1952 B.addApproval('CRVW', 2)
1953 C.addApproval('CRVW', 2)
1954
1955 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1956 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1957 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1958 self.waitUntilSettled()
1959
1960 B.addPatchset()
1961 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1962 self.waitUntilSettled()
1963
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001964 self.worker.hold_jobs_in_build = False
1965 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001966 self.waitUntilSettled()
1967
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001968 self.assertEqual(A.data['status'], 'MERGED')
1969 self.assertEqual(A.reported, 2)
1970 self.assertEqual(B.data['status'], 'NEW')
1971 self.assertEqual(B.reported, 2)
1972 self.assertEqual(C.data['status'], 'MERGED')
1973 self.assertEqual(C.reported, 2)
1974 self.assertEqual(len(self.history), 9)
James E. Blair2fa50962013-01-30 21:50:41 -08001975
James E. Blairec056492016-07-22 09:45:56 -07001976 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001977 def test_new_patchset_dequeues_old_independent_queue(self):
1978 "Test that a new patchset causes the old to be dequeued (independent)"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001979 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001980 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1981 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1982 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1983 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1984 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1985 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
1986 self.waitUntilSettled()
1987
1988 B.addPatchset()
1989 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1990 self.waitUntilSettled()
1991
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001992 self.worker.hold_jobs_in_build = False
1993 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001994 self.waitUntilSettled()
1995
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001996 self.assertEqual(A.data['status'], 'NEW')
1997 self.assertEqual(A.reported, 1)
1998 self.assertEqual(B.data['status'], 'NEW')
1999 self.assertEqual(B.reported, 1)
2000 self.assertEqual(C.data['status'], 'NEW')
2001 self.assertEqual(C.reported, 1)
2002 self.assertEqual(len(self.history), 10)
2003 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 1)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002004
James E. Blairec056492016-07-22 09:45:56 -07002005 @skip("Disabled for early v3 development")
James E. Blair18c64442014-03-18 10:14:45 -07002006 def test_noop_job(self):
2007 "Test that the internal noop job works"
2008 A = self.fake_gerrit.addFakeChange('org/noop-project', 'master', 'A')
2009 A.addApproval('CRVW', 2)
2010 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2011 self.waitUntilSettled()
2012
2013 self.assertEqual(len(self.gearman_server.getQueue()), 0)
2014 self.assertTrue(self.sched._areAllBuildsComplete())
2015 self.assertEqual(len(self.history), 0)
2016 self.assertEqual(A.data['status'], 'MERGED')
2017 self.assertEqual(A.reported, 2)
2018
James E. Blairec056492016-07-22 09:45:56 -07002019 @skip("Disabled for early v3 development")
Evgeny Antyshevd6e546c2015-06-11 15:13:57 +00002020 def test_no_job_project(self):
2021 "Test that reports with no jobs don't get sent"
2022 A = self.fake_gerrit.addFakeChange('org/no-jobs-project',
2023 'master', 'A')
2024 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2025 self.waitUntilSettled()
2026
2027 # Change wasn't reported to
2028 self.assertEqual(A.reported, False)
2029
2030 # Check queue is empty afterwards
2031 check_pipeline = self.sched.layout.pipelines['check']
2032 items = check_pipeline.getAllItems()
2033 self.assertEqual(len(items), 0)
2034
2035 self.assertEqual(len(self.history), 0)
2036
James E. Blairec056492016-07-22 09:45:56 -07002037 @skip("Disabled for early v3 development")
James E. Blair7d0dedc2013-02-21 17:26:09 -08002038 def test_zuul_refs(self):
2039 "Test that zuul refs exist and have the right changes"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002040 self.worker.hold_jobs_in_build = True
James E. Blair7d0dedc2013-02-21 17:26:09 -08002041 M1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'M1')
2042 M1.setMerged()
2043 M2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'M2')
2044 M2.setMerged()
2045
2046 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2047 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2048 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
2049 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
2050 A.addApproval('CRVW', 2)
2051 B.addApproval('CRVW', 2)
2052 C.addApproval('CRVW', 2)
2053 D.addApproval('CRVW', 2)
2054 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2055 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2056 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2057 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
2058
2059 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002060 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002061 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002062 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002063 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002064 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002065 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002066 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002067 self.waitUntilSettled()
2068
James E. Blair7d0dedc2013-02-21 17:26:09 -08002069 a_zref = b_zref = c_zref = d_zref = None
Monty Taylor6bef8ef2013-06-02 08:17:12 -04002070 for x in self.builds:
James E. Blair7d0dedc2013-02-21 17:26:09 -08002071 if x.parameters['ZUUL_CHANGE'] == '3':
2072 a_zref = x.parameters['ZUUL_REF']
2073 if x.parameters['ZUUL_CHANGE'] == '4':
2074 b_zref = x.parameters['ZUUL_REF']
2075 if x.parameters['ZUUL_CHANGE'] == '5':
2076 c_zref = x.parameters['ZUUL_REF']
2077 if x.parameters['ZUUL_CHANGE'] == '6':
2078 d_zref = x.parameters['ZUUL_REF']
2079
2080 # There are... four... refs.
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002081 self.assertIsNotNone(a_zref)
2082 self.assertIsNotNone(b_zref)
2083 self.assertIsNotNone(c_zref)
2084 self.assertIsNotNone(d_zref)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002085
2086 # And they should all be different
2087 refs = set([a_zref, b_zref, c_zref, d_zref])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002088 self.assertEqual(len(refs), 4)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002089
2090 # a ref should have a, not b, and should not be in project2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002091 self.assertTrue(self.ref_has_change(a_zref, A))
2092 self.assertFalse(self.ref_has_change(a_zref, B))
2093 self.assertFalse(self.ref_has_change(a_zref, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002094
2095 # b ref should have a and b, and should not be in project2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002096 self.assertTrue(self.ref_has_change(b_zref, A))
2097 self.assertTrue(self.ref_has_change(b_zref, B))
2098 self.assertFalse(self.ref_has_change(b_zref, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002099
2100 # c ref should have a and b in 1, c in 2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002101 self.assertTrue(self.ref_has_change(c_zref, A))
2102 self.assertTrue(self.ref_has_change(c_zref, B))
2103 self.assertTrue(self.ref_has_change(c_zref, C))
2104 self.assertFalse(self.ref_has_change(c_zref, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002105
2106 # d ref should have a and b in 1, c and d in 2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002107 self.assertTrue(self.ref_has_change(d_zref, A))
2108 self.assertTrue(self.ref_has_change(d_zref, B))
2109 self.assertTrue(self.ref_has_change(d_zref, C))
2110 self.assertTrue(self.ref_has_change(d_zref, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002111
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002112 self.worker.hold_jobs_in_build = False
2113 self.worker.release()
James E. Blair7d0dedc2013-02-21 17:26:09 -08002114 self.waitUntilSettled()
2115
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002116 self.assertEqual(A.data['status'], 'MERGED')
2117 self.assertEqual(A.reported, 2)
2118 self.assertEqual(B.data['status'], 'MERGED')
2119 self.assertEqual(B.reported, 2)
2120 self.assertEqual(C.data['status'], 'MERGED')
2121 self.assertEqual(C.reported, 2)
2122 self.assertEqual(D.data['status'], 'MERGED')
2123 self.assertEqual(D.reported, 2)
James E. Blair70c71582013-03-06 08:50:50 -08002124
James E. Blairec056492016-07-22 09:45:56 -07002125 @skip("Disabled for early v3 development")
James E. Blair4a28a882013-08-23 15:17:33 -07002126 def test_rerun_on_error(self):
2127 "Test that if a worker fails to run a job, it is run again"
2128 self.worker.hold_jobs_in_build = True
2129 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2130 A.addApproval('CRVW', 2)
2131 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2132 self.waitUntilSettled()
2133
2134 self.builds[0].run_error = True
2135 self.worker.hold_jobs_in_build = False
2136 self.worker.release()
2137 self.waitUntilSettled()
2138 self.assertEqual(self.countJobResults(self.history, 'RUN_ERROR'), 1)
2139 self.assertEqual(self.countJobResults(self.history, 'SUCCESS'), 3)
2140
James E. Blairec056492016-07-22 09:45:56 -07002141 @skip("Disabled for early v3 development")
James E. Blair412e5582013-04-22 15:50:12 -07002142 def test_statsd(self):
2143 "Test each of the statsd methods used in the scheduler"
2144 import extras
2145 statsd = extras.try_import('statsd.statsd')
2146 statsd.incr('test-incr')
2147 statsd.timing('test-timing', 3)
Alex Gaynor813d39b2014-05-17 16:17:16 -07002148 statsd.gauge('test-gauge', 12)
James E. Blair412e5582013-04-22 15:50:12 -07002149 self.assertReportedStat('test-incr', '1|c')
2150 self.assertReportedStat('test-timing', '3|ms')
Alex Gaynor813d39b2014-05-17 16:17:16 -07002151 self.assertReportedStat('test-gauge', '12|g')
James E. Blair412e5582013-04-22 15:50:12 -07002152
James E. Blairec056492016-07-22 09:45:56 -07002153 @skip("Disabled for early v3 development")
James E. Blairdad52252014-02-07 16:59:17 -08002154 def test_stuck_job_cleanup(self):
2155 "Test that pending jobs are cleaned up if removed from layout"
James E. Blair18c64442014-03-18 10:14:45 -07002156 # This job won't be registered at startup because it is not in
2157 # the standard layout, but we need it to already be registerd
2158 # for when we reconfigure, as that is when Zuul will attempt
2159 # to run the new job.
2160 self.worker.registerFunction('build:gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002161 self.gearman_server.hold_jobs_in_queue = True
2162 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2163 A.addApproval('CRVW', 2)
2164 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2165 self.waitUntilSettled()
2166 self.assertEqual(len(self.gearman_server.getQueue()), 1)
2167
James E. Blairf84026c2015-12-08 16:11:46 -08002168 self.updateConfigLayout(
2169 'tests/fixtures/layout-no-jobs.yaml')
James E. Blairdad52252014-02-07 16:59:17 -08002170 self.sched.reconfigure(self.config)
2171 self.waitUntilSettled()
2172
James E. Blair18c64442014-03-18 10:14:45 -07002173 self.gearman_server.release('gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002174 self.waitUntilSettled()
2175 self.assertEqual(len(self.gearman_server.getQueue()), 0)
2176 self.assertTrue(self.sched._areAllBuildsComplete())
2177
2178 self.assertEqual(len(self.history), 1)
James E. Blair18c64442014-03-18 10:14:45 -07002179 self.assertEqual(self.history[0].name, 'gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002180 self.assertEqual(self.history[0].result, 'SUCCESS')
2181
James E. Blairec056492016-07-22 09:45:56 -07002182 @skip("Disabled for early v3 development")
James E. Blair879dafb2015-07-17 14:04:49 -07002183 def test_file_head(self):
2184 # This is a regression test for an observed bug. A change
2185 # with a file named "HEAD" in the root directory of the repo
2186 # was processed by a merger. It then was unable to reset the
2187 # repo because of:
2188 # GitCommandError: 'git reset --hard HEAD' returned
2189 # with exit code 128
2190 # stderr: 'fatal: ambiguous argument 'HEAD': both revision
2191 # and filename
2192 # Use '--' to separate filenames from revisions'
2193
2194 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2195 A.addPatchset(['HEAD'])
2196 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2197
2198 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
2199 self.waitUntilSettled()
2200
2201 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2202 self.waitUntilSettled()
2203
2204 self.assertIn('Build succeeded', A.messages[0])
2205 self.assertIn('Build succeeded', B.messages[0])
2206
James E. Blairec056492016-07-22 09:45:56 -07002207 @skip("Disabled for early v3 development")
James E. Blair70c71582013-03-06 08:50:50 -08002208 def test_file_jobs(self):
2209 "Test that file jobs run only when appropriate"
2210 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2211 A.addPatchset(['pip-requires'])
2212 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2213 A.addApproval('CRVW', 2)
2214 B.addApproval('CRVW', 2)
2215 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2216 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2217 self.waitUntilSettled()
2218
Monty Taylor6bef8ef2013-06-02 08:17:12 -04002219 testfile_jobs = [x for x in self.history
James E. Blair70c71582013-03-06 08:50:50 -08002220 if x.name == 'project-testfile']
2221
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002222 self.assertEqual(len(testfile_jobs), 1)
2223 self.assertEqual(testfile_jobs[0].changes, '1,2')
2224 self.assertEqual(A.data['status'], 'MERGED')
2225 self.assertEqual(A.reported, 2)
2226 self.assertEqual(B.data['status'], 'MERGED')
2227 self.assertEqual(B.reported, 2)
James E. Blair3c5e5b52013-04-26 11:17:03 -07002228
James E. Blairec056492016-07-22 09:45:56 -07002229 @skip("Disabled for early v3 development")
Maru Newby3fe5f852015-01-13 04:22:14 +00002230 def _test_skip_if_jobs(self, branch, should_skip):
2231 "Test that jobs with a skip-if filter run only when appropriate"
James E. Blairf84026c2015-12-08 16:11:46 -08002232 self.updateConfigLayout(
2233 'tests/fixtures/layout-skip-if.yaml')
Maru Newby3fe5f852015-01-13 04:22:14 +00002234 self.sched.reconfigure(self.config)
2235 self.registerJobs()
2236
2237 change = self.fake_gerrit.addFakeChange('org/project',
2238 branch,
2239 'test skip-if')
2240 self.fake_gerrit.addEvent(change.getPatchsetCreatedEvent(1))
2241 self.waitUntilSettled()
2242
2243 tested_change_ids = [x.changes[0] for x in self.history
2244 if x.name == 'project-test-skip-if']
2245
2246 if should_skip:
2247 self.assertEqual([], tested_change_ids)
2248 else:
2249 self.assertIn(change.data['number'], tested_change_ids)
2250
James E. Blairec056492016-07-22 09:45:56 -07002251 @skip("Disabled for early v3 development")
Maru Newby3fe5f852015-01-13 04:22:14 +00002252 def test_skip_if_match_skips_job(self):
2253 self._test_skip_if_jobs(branch='master', should_skip=True)
2254
James E. Blairec056492016-07-22 09:45:56 -07002255 @skip("Disabled for early v3 development")
Maru Newby3fe5f852015-01-13 04:22:14 +00002256 def test_skip_if_no_match_runs_job(self):
2257 self._test_skip_if_jobs(branch='mp', should_skip=False)
2258
James E. Blairec056492016-07-22 09:45:56 -07002259 @skip("Disabled for early v3 development")
James E. Blair3c5e5b52013-04-26 11:17:03 -07002260 def test_test_config(self):
2261 "Test that we can test the config"
James E. Blairf84026c2015-12-08 16:11:46 -08002262 self.sched.testConfig(self.config.get('zuul', 'tenant_config'),
Joshua Hesketh352264b2015-08-11 23:42:08 +10002263 self.connections)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002264
James E. Blairec056492016-07-22 09:45:56 -07002265 @skip("Disabled for early v3 development")
James E. Blairc8a1e052014-02-25 09:29:26 -08002266 def test_queue_names(self):
2267 "Test shared change queue names"
2268 project1 = self.sched.layout.projects['org/project1']
2269 project2 = self.sched.layout.projects['org/project2']
2270 q1 = self.sched.layout.pipelines['gate'].getQueue(project1)
2271 q2 = self.sched.layout.pipelines['gate'].getQueue(project2)
2272 self.assertEqual(q1.name, 'integration')
2273 self.assertEqual(q2.name, 'integration')
2274
James E. Blairf84026c2015-12-08 16:11:46 -08002275 self.updateConfigLayout(
2276 'tests/fixtures/layout-bad-queue.yaml')
James E. Blairc8a1e052014-02-25 09:29:26 -08002277 with testtools.ExpectedException(
2278 Exception, "More than one name assigned to change queue"):
2279 self.sched.reconfigure(self.config)
2280
James E. Blairec056492016-07-22 09:45:56 -07002281 @skip("Disabled for early v3 development")
James E. Blair64ed6f22013-07-10 14:07:23 -07002282 def test_queue_precedence(self):
2283 "Test that queue precedence works"
2284
2285 self.gearman_server.hold_jobs_in_queue = True
James E. Blair8de58bd2013-07-18 16:23:33 -07002286 self.worker.hold_jobs_in_build = True
James E. Blair64ed6f22013-07-10 14:07:23 -07002287 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2288 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2289 A.addApproval('CRVW', 2)
2290 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2291
2292 self.waitUntilSettled()
2293 self.gearman_server.hold_jobs_in_queue = False
2294 self.gearman_server.release()
2295 self.waitUntilSettled()
2296
James E. Blair8de58bd2013-07-18 16:23:33 -07002297 # Run one build at a time to ensure non-race order:
James E. Blairb8c16472015-05-05 14:55:26 -07002298 self.orderedRelease()
James E. Blair8de58bd2013-07-18 16:23:33 -07002299 self.worker.hold_jobs_in_build = False
2300 self.waitUntilSettled()
2301
James E. Blair64ed6f22013-07-10 14:07:23 -07002302 self.log.debug(self.history)
2303 self.assertEqual(self.history[0].pipeline, 'gate')
2304 self.assertEqual(self.history[1].pipeline, 'check')
2305 self.assertEqual(self.history[2].pipeline, 'gate')
2306 self.assertEqual(self.history[3].pipeline, 'gate')
2307 self.assertEqual(self.history[4].pipeline, 'check')
2308 self.assertEqual(self.history[5].pipeline, 'check')
2309
James E. Blairec056492016-07-22 09:45:56 -07002310 @skip("Disabled for early v3 development")
Clark Boylana5edbe42014-06-03 16:39:10 -07002311 def test_json_status(self):
James E. Blair1843a552013-07-03 14:19:52 -07002312 "Test that we can retrieve JSON status info"
2313 self.worker.hold_jobs_in_build = True
2314 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2315 A.addApproval('CRVW', 2)
2316 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2317 self.waitUntilSettled()
2318
James E. Blairb7273ef2016-04-19 08:58:51 -07002319 self.worker.release('project-merge')
2320 self.waitUntilSettled()
2321
James E. Blair1843a552013-07-03 14:19:52 -07002322 port = self.webapp.server.socket.getsockname()[1]
2323
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002324 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2325 f = urllib.request.urlopen(req)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002326 headers = f.info()
2327 self.assertIn('Content-Length', headers)
2328 self.assertIn('Content-Type', headers)
Sachi Kingdc963fc2016-03-23 16:00:33 +11002329 self.assertIsNotNone(re.match('^application/json(; charset=UTF-8)?$',
2330 headers['Content-Type']))
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002331 self.assertIn('Access-Control-Allow-Origin', headers)
2332 self.assertIn('Cache-Control', headers)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002333 self.assertIn('Last-Modified', headers)
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002334 self.assertIn('Expires', headers)
James E. Blair1843a552013-07-03 14:19:52 -07002335 data = f.read()
2336
2337 self.worker.hold_jobs_in_build = False
2338 self.worker.release()
2339 self.waitUntilSettled()
2340
2341 data = json.loads(data)
James E. Blairb7273ef2016-04-19 08:58:51 -07002342 status_jobs = []
James E. Blair1843a552013-07-03 14:19:52 -07002343 for p in data['pipelines']:
2344 for q in p['change_queues']:
James E. Blairbfb8e042014-12-30 17:01:44 -08002345 if p['name'] in ['gate', 'conflict']:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002346 self.assertEqual(q['window'], 20)
2347 else:
2348 self.assertEqual(q['window'], 0)
James E. Blair1843a552013-07-03 14:19:52 -07002349 for head in q['heads']:
2350 for change in head:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002351 self.assertTrue(change['active'])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002352 self.assertEqual(change['id'], '1,1')
James E. Blair1843a552013-07-03 14:19:52 -07002353 for job in change['jobs']:
James E. Blairb7273ef2016-04-19 08:58:51 -07002354 status_jobs.append(job)
2355 self.assertEqual('project-merge', status_jobs[0]['name'])
2356 self.assertEqual('https://server/job/project-merge/0/',
2357 status_jobs[0]['url'])
2358 self.assertEqual('http://logs.example.com/1/1/gate/project-merge/0',
2359 status_jobs[0]['report_url'])
2360
2361 self.assertEqual('project-test1', status_jobs[1]['name'])
2362 self.assertEqual('https://server/job/project-test1/1/',
2363 status_jobs[1]['url'])
2364 self.assertEqual('http://logs.example.com/1/1/gate/project-test1/1',
2365 status_jobs[1]['report_url'])
2366
2367 self.assertEqual('project-test2', status_jobs[2]['name'])
2368 self.assertEqual('https://server/job/project-test2/2/',
2369 status_jobs[2]['url'])
2370 self.assertEqual('http://logs.example.com/1/1/gate/project-test2/2',
2371 status_jobs[2]['report_url'])
James E. Blair1843a552013-07-03 14:19:52 -07002372
James E. Blairec056492016-07-22 09:45:56 -07002373 @skip("Disabled for early v3 development")
James E. Blairc3d428e2013-12-03 15:06:48 -08002374 def test_merging_queues(self):
2375 "Test that transitively-connected change queues are merged"
James E. Blairf84026c2015-12-08 16:11:46 -08002376 self.updateConfigLayout(
2377 'tests/fixtures/layout-merge-queues.yaml')
James E. Blairc3d428e2013-12-03 15:06:48 -08002378 self.sched.reconfigure(self.config)
2379 self.assertEqual(len(self.sched.layout.pipelines['gate'].queues), 1)
2380
James E. Blairec056492016-07-22 09:45:56 -07002381 @skip("Disabled for early v3 development")
James E. Blairaf17a972016-02-03 15:07:18 -08002382 def test_mutex(self):
2383 "Test job mutexes"
2384 self.config.set('zuul', 'layout_config',
2385 'tests/fixtures/layout-mutex.yaml')
2386 self.sched.reconfigure(self.config)
2387
2388 self.worker.hold_jobs_in_build = True
2389 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2390 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2391 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2392
2393 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2394 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2395 self.waitUntilSettled()
2396 self.assertEqual(len(self.builds), 3)
2397 self.assertEqual(self.builds[0].name, 'project-test1')
2398 self.assertEqual(self.builds[1].name, 'mutex-one')
2399 self.assertEqual(self.builds[2].name, 'project-test1')
2400
2401 self.worker.release('mutex-one')
2402 self.waitUntilSettled()
2403
2404 self.assertEqual(len(self.builds), 3)
2405 self.assertEqual(self.builds[0].name, 'project-test1')
2406 self.assertEqual(self.builds[1].name, 'project-test1')
2407 self.assertEqual(self.builds[2].name, 'mutex-two')
2408 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2409
2410 self.worker.release('mutex-two')
2411 self.waitUntilSettled()
2412
2413 self.assertEqual(len(self.builds), 3)
2414 self.assertEqual(self.builds[0].name, 'project-test1')
2415 self.assertEqual(self.builds[1].name, 'project-test1')
2416 self.assertEqual(self.builds[2].name, 'mutex-one')
2417 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2418
2419 self.worker.release('mutex-one')
2420 self.waitUntilSettled()
2421
2422 self.assertEqual(len(self.builds), 3)
2423 self.assertEqual(self.builds[0].name, 'project-test1')
2424 self.assertEqual(self.builds[1].name, 'project-test1')
2425 self.assertEqual(self.builds[2].name, 'mutex-two')
2426 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2427
2428 self.worker.release('mutex-two')
2429 self.waitUntilSettled()
2430
2431 self.assertEqual(len(self.builds), 2)
2432 self.assertEqual(self.builds[0].name, 'project-test1')
2433 self.assertEqual(self.builds[1].name, 'project-test1')
2434 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2435
2436 self.worker.hold_jobs_in_build = False
2437 self.worker.release()
2438
2439 self.waitUntilSettled()
2440 self.assertEqual(len(self.builds), 0)
2441
2442 self.assertEqual(A.reported, 1)
2443 self.assertEqual(B.reported, 1)
2444 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2445
James E. Blairec056492016-07-22 09:45:56 -07002446 @skip("Disabled for early v3 development")
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002447 def test_node_label(self):
2448 "Test that a job runs on a specific node label"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002449 self.worker.registerFunction('build:node-project-test1:debian')
2450
2451 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
2452 A.addApproval('CRVW', 2)
2453 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2454 self.waitUntilSettled()
James E. Blair4ca985f2013-05-30 12:27:43 -07002455
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002456 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2457 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2458 'debian')
2459 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
James E. Blaircdccd972013-07-01 12:10:22 -07002460
James E. Blairec056492016-07-22 09:45:56 -07002461 @skip("Disabled for early v3 development")
James E. Blaircdccd972013-07-01 12:10:22 -07002462 def test_live_reconfiguration(self):
2463 "Test that live reconfiguration works"
2464 self.worker.hold_jobs_in_build = True
2465 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2466 A.addApproval('CRVW', 2)
2467 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2468 self.waitUntilSettled()
2469
2470 self.sched.reconfigure(self.config)
2471
2472 self.worker.hold_jobs_in_build = False
2473 self.worker.release()
2474 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002475 self.assertEqual(self.getJobFromHistory('project-merge').result,
2476 'SUCCESS')
2477 self.assertEqual(self.getJobFromHistory('project-test1').result,
2478 'SUCCESS')
2479 self.assertEqual(self.getJobFromHistory('project-test2').result,
2480 'SUCCESS')
2481 self.assertEqual(A.data['status'], 'MERGED')
2482 self.assertEqual(A.reported, 2)
James E. Blair287c06d2013-07-24 10:39:30 -07002483
James E. Blairec056492016-07-22 09:45:56 -07002484 @skip("Disabled for early v3 development")
James E. Blair6bc782d2015-07-17 16:20:21 -07002485 def test_live_reconfiguration_merge_conflict(self):
2486 # A real-world bug: a change in a gate queue has a merge
2487 # conflict and a job is added to its project while it's
2488 # sitting in the queue. The job gets added to the change and
2489 # enqueued and the change gets stuck.
2490 self.worker.registerFunction('build:project-test3')
2491 self.worker.hold_jobs_in_build = True
2492
2493 # This change is fine. It's here to stop the queue long
2494 # enough for the next change to be subject to the
2495 # reconfiguration, as well as to provide a conflict for the
2496 # next change. This change will succeed and merge.
2497 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2498 A.addPatchset(['conflict'])
2499 A.addApproval('CRVW', 2)
James E. Blair6bc782d2015-07-17 16:20:21 -07002500
2501 # This change will be in merge conflict. During the
2502 # reconfiguration, we will add a job. We want to make sure
2503 # that doesn't cause it to get stuck.
2504 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2505 B.addPatchset(['conflict'])
2506 B.addApproval('CRVW', 2)
James E. Blair4eb21fa2015-07-27 14:56:47 -07002507
2508 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
James E. Blair6bc782d2015-07-17 16:20:21 -07002509 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2510
2511 self.waitUntilSettled()
2512
2513 # No jobs have run yet
2514 self.assertEqual(A.data['status'], 'NEW')
2515 self.assertEqual(A.reported, 1)
2516 self.assertEqual(B.data['status'], 'NEW')
2517 self.assertEqual(B.reported, 1)
2518 self.assertEqual(len(self.history), 0)
2519
2520 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002521 self.updateConfigLayout(
2522 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002523 self.sched.reconfigure(self.config)
2524 self.waitUntilSettled()
2525
2526 self.worker.hold_jobs_in_build = False
2527 self.worker.release()
2528 self.waitUntilSettled()
2529
2530 self.assertEqual(A.data['status'], 'MERGED')
2531 self.assertEqual(A.reported, 2)
2532 self.assertEqual(B.data['status'], 'NEW')
2533 self.assertEqual(B.reported, 2)
2534 self.assertEqual(self.getJobFromHistory('project-merge').result,
2535 'SUCCESS')
2536 self.assertEqual(self.getJobFromHistory('project-test1').result,
2537 'SUCCESS')
2538 self.assertEqual(self.getJobFromHistory('project-test2').result,
2539 'SUCCESS')
2540 self.assertEqual(self.getJobFromHistory('project-test3').result,
2541 'SUCCESS')
2542 self.assertEqual(len(self.history), 4)
2543
James E. Blairec056492016-07-22 09:45:56 -07002544 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002545 def test_live_reconfiguration_failed_root(self):
James E. Blair6bc782d2015-07-17 16:20:21 -07002546 # An extrapolation of test_live_reconfiguration_merge_conflict
2547 # that tests a job added to a job tree with a failed root does
2548 # not run.
2549 self.worker.registerFunction('build:project-test3')
2550 self.worker.hold_jobs_in_build = True
2551
2552 # This change is fine. It's here to stop the queue long
2553 # enough for the next change to be subject to the
2554 # reconfiguration. This change will succeed and merge.
2555 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2556 A.addPatchset(['conflict'])
2557 A.addApproval('CRVW', 2)
2558 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2559 self.waitUntilSettled()
2560 self.worker.release('.*-merge')
2561 self.waitUntilSettled()
2562
2563 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2564 self.worker.addFailTest('project-merge', B)
2565 B.addApproval('CRVW', 2)
2566 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2567 self.waitUntilSettled()
2568
2569 self.worker.release('.*-merge')
2570 self.waitUntilSettled()
2571
2572 # Both -merge jobs have run, but no others.
2573 self.assertEqual(A.data['status'], 'NEW')
2574 self.assertEqual(A.reported, 1)
2575 self.assertEqual(B.data['status'], 'NEW')
2576 self.assertEqual(B.reported, 1)
2577 self.assertEqual(self.history[0].result, 'SUCCESS')
2578 self.assertEqual(self.history[0].name, 'project-merge')
2579 self.assertEqual(self.history[1].result, 'FAILURE')
2580 self.assertEqual(self.history[1].name, 'project-merge')
2581 self.assertEqual(len(self.history), 2)
2582
2583 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002584 self.updateConfigLayout(
2585 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002586 self.sched.reconfigure(self.config)
2587 self.waitUntilSettled()
2588
2589 self.worker.hold_jobs_in_build = False
2590 self.worker.release()
2591 self.waitUntilSettled()
2592
2593 self.assertEqual(A.data['status'], 'MERGED')
2594 self.assertEqual(A.reported, 2)
2595 self.assertEqual(B.data['status'], 'NEW')
2596 self.assertEqual(B.reported, 2)
2597 self.assertEqual(self.history[0].result, 'SUCCESS')
2598 self.assertEqual(self.history[0].name, 'project-merge')
2599 self.assertEqual(self.history[1].result, 'FAILURE')
2600 self.assertEqual(self.history[1].name, 'project-merge')
2601 self.assertEqual(self.history[2].result, 'SUCCESS')
2602 self.assertEqual(self.history[3].result, 'SUCCESS')
2603 self.assertEqual(self.history[4].result, 'SUCCESS')
2604 self.assertEqual(len(self.history), 5)
2605
James E. Blairec056492016-07-22 09:45:56 -07002606 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002607 def test_live_reconfiguration_failed_job(self):
2608 # Test that a change with a removed failing job does not
2609 # disrupt reconfiguration. If a change has a failed job and
2610 # that job is removed during a reconfiguration, we observed a
2611 # bug where the code to re-set build statuses would run on
2612 # that build and raise an exception because the job no longer
2613 # existed.
2614 self.worker.hold_jobs_in_build = True
2615
2616 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2617
2618 # This change will fail and later be removed by the reconfiguration.
2619 self.worker.addFailTest('project-test1', A)
2620
2621 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2622 self.waitUntilSettled()
2623 self.worker.release('.*-merge')
2624 self.waitUntilSettled()
2625 self.worker.release('project-test1')
2626 self.waitUntilSettled()
2627
2628 self.assertEqual(A.data['status'], 'NEW')
2629 self.assertEqual(A.reported, 0)
2630
2631 self.assertEqual(self.getJobFromHistory('project-merge').result,
2632 'SUCCESS')
2633 self.assertEqual(self.getJobFromHistory('project-test1').result,
2634 'FAILURE')
2635 self.assertEqual(len(self.history), 2)
2636
2637 # Remove the test1 job.
James E. Blairf84026c2015-12-08 16:11:46 -08002638 self.updateConfigLayout(
2639 'tests/fixtures/layout-live-reconfiguration-failed-job.yaml')
James E. Blair400e8fd2015-07-30 17:44:45 -07002640 self.sched.reconfigure(self.config)
2641 self.waitUntilSettled()
2642
2643 self.worker.hold_jobs_in_build = False
2644 self.worker.release()
2645 self.waitUntilSettled()
2646
2647 self.assertEqual(self.getJobFromHistory('project-test2').result,
2648 'SUCCESS')
2649 self.assertEqual(self.getJobFromHistory('project-testfile').result,
2650 'SUCCESS')
2651 self.assertEqual(len(self.history), 4)
2652
2653 self.assertEqual(A.data['status'], 'NEW')
2654 self.assertEqual(A.reported, 1)
2655 self.assertIn('Build succeeded', A.messages[0])
2656 # Ensure the removed job was not included in the report.
2657 self.assertNotIn('project-test1', A.messages[0])
2658
James E. Blairec056492016-07-22 09:45:56 -07002659 @skip("Disabled for early v3 development")
James E. Blairfe707d12015-08-05 15:18:15 -07002660 def test_live_reconfiguration_shared_queue(self):
2661 # Test that a change with a failing job which was removed from
2662 # this project but otherwise still exists in the system does
2663 # not disrupt reconfiguration.
2664
2665 self.worker.hold_jobs_in_build = True
2666
2667 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2668
2669 self.worker.addFailTest('project1-project2-integration', A)
2670
2671 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2672 self.waitUntilSettled()
2673 self.worker.release('.*-merge')
2674 self.waitUntilSettled()
2675 self.worker.release('project1-project2-integration')
2676 self.waitUntilSettled()
2677
2678 self.assertEqual(A.data['status'], 'NEW')
2679 self.assertEqual(A.reported, 0)
2680
2681 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2682 'SUCCESS')
2683 self.assertEqual(self.getJobFromHistory(
2684 'project1-project2-integration').result, 'FAILURE')
2685 self.assertEqual(len(self.history), 2)
2686
2687 # Remove the integration job.
James E. Blairf84026c2015-12-08 16:11:46 -08002688 self.updateConfigLayout(
2689 'tests/fixtures/layout-live-reconfiguration-shared-queue.yaml')
James E. Blairfe707d12015-08-05 15:18:15 -07002690 self.sched.reconfigure(self.config)
2691 self.waitUntilSettled()
2692
2693 self.worker.hold_jobs_in_build = False
2694 self.worker.release()
2695 self.waitUntilSettled()
2696
2697 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2698 'SUCCESS')
2699 self.assertEqual(self.getJobFromHistory('project1-test1').result,
2700 'SUCCESS')
2701 self.assertEqual(self.getJobFromHistory('project1-test2').result,
2702 'SUCCESS')
2703 self.assertEqual(self.getJobFromHistory(
2704 'project1-project2-integration').result, 'FAILURE')
2705 self.assertEqual(len(self.history), 4)
2706
2707 self.assertEqual(A.data['status'], 'NEW')
2708 self.assertEqual(A.reported, 1)
2709 self.assertIn('Build succeeded', A.messages[0])
2710 # Ensure the removed job was not included in the report.
2711 self.assertNotIn('project1-project2-integration', A.messages[0])
2712
James E. Blairec056492016-07-22 09:45:56 -07002713 @skip("Disabled for early v3 development")
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002714 def test_double_live_reconfiguration_shared_queue(self):
2715 # This was a real-world regression. A change is added to
2716 # gate; a reconfigure happens, a second change which depends
2717 # on the first is added, and a second reconfiguration happens.
2718 # Ensure that both changes merge.
2719
2720 # A failure may indicate incorrect caching or cleaning up of
2721 # references during a reconfiguration.
2722 self.worker.hold_jobs_in_build = True
2723
2724 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2725 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2726 B.setDependsOn(A, 1)
2727 A.addApproval('CRVW', 2)
2728 B.addApproval('CRVW', 2)
2729
2730 # Add the parent change.
2731 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2732 self.waitUntilSettled()
2733 self.worker.release('.*-merge')
2734 self.waitUntilSettled()
2735
2736 # Reconfigure (with only one change in the pipeline).
2737 self.sched.reconfigure(self.config)
2738 self.waitUntilSettled()
2739
2740 # Add the child change.
2741 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2742 self.waitUntilSettled()
2743 self.worker.release('.*-merge')
2744 self.waitUntilSettled()
2745
2746 # Reconfigure (with both in the pipeline).
2747 self.sched.reconfigure(self.config)
2748 self.waitUntilSettled()
2749
2750 self.worker.hold_jobs_in_build = False
2751 self.worker.release()
2752 self.waitUntilSettled()
2753
2754 self.assertEqual(len(self.history), 8)
2755
2756 self.assertEqual(A.data['status'], 'MERGED')
2757 self.assertEqual(A.reported, 2)
2758 self.assertEqual(B.data['status'], 'MERGED')
2759 self.assertEqual(B.reported, 2)
2760
James E. Blairec056492016-07-22 09:45:56 -07002761 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002762 def test_live_reconfiguration_del_project(self):
2763 # Test project deletion from layout
2764 # while changes are enqueued
2765
2766 self.worker.hold_jobs_in_build = True
2767 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2768 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2769 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
2770
2771 # A Depends-On: B
2772 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
2773 A.subject, B.data['id'])
2774 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2775
2776 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2777 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
2778 self.waitUntilSettled()
2779 self.worker.release('.*-merge')
2780 self.waitUntilSettled()
2781 self.assertEqual(len(self.builds), 5)
2782
2783 # This layout defines only org/project, not org/project1
James E. Blairf84026c2015-12-08 16:11:46 -08002784 self.updateConfigLayout(
2785 'tests/fixtures/layout-live-reconfiguration-del-project.yaml')
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002786 self.sched.reconfigure(self.config)
2787 self.waitUntilSettled()
2788
2789 # Builds for C aborted, builds for A succeed,
2790 # and have change B applied ahead
2791 job_c = self.getJobFromHistory('project1-test1')
2792 self.assertEqual(job_c.changes, '3,1')
2793 self.assertEqual(job_c.result, 'ABORTED')
2794
2795 self.worker.hold_jobs_in_build = False
2796 self.worker.release()
2797 self.waitUntilSettled()
2798
2799 self.assertEqual(self.getJobFromHistory('project-test1').changes,
2800 '2,1 1,1')
2801
2802 self.assertEqual(A.data['status'], 'NEW')
2803 self.assertEqual(B.data['status'], 'NEW')
2804 self.assertEqual(C.data['status'], 'NEW')
2805 self.assertEqual(A.reported, 1)
2806 self.assertEqual(B.reported, 0)
2807 self.assertEqual(C.reported, 0)
2808
2809 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
2810 self.assertIn('Build succeeded', A.messages[0])
2811
James E. Blairec056492016-07-22 09:45:56 -07002812 @skip("Disabled for early v3 development")
James E. Blaire712d9f2013-07-31 11:40:11 -07002813 def test_live_reconfiguration_functions(self):
2814 "Test live reconfiguration with a custom function"
2815 self.worker.registerFunction('build:node-project-test1:debian')
2816 self.worker.registerFunction('build:node-project-test1:wheezy')
2817 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
2818 A.addApproval('CRVW', 2)
2819 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2820 self.waitUntilSettled()
2821
2822 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2823 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2824 'debian')
2825 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2826
James E. Blairf84026c2015-12-08 16:11:46 -08002827 self.updateConfigLayout(
2828 'tests/fixtures/layout-live-reconfiguration-functions.yaml')
James E. Blaire712d9f2013-07-31 11:40:11 -07002829 self.sched.reconfigure(self.config)
2830 self.worker.build_history = []
2831
2832 B = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'B')
2833 B.addApproval('CRVW', 2)
2834 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2835 self.waitUntilSettled()
2836
2837 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2838 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2839 'wheezy')
2840 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2841
James E. Blairec056492016-07-22 09:45:56 -07002842 @skip("Disabled for early v3 development")
James E. Blair287c06d2013-07-24 10:39:30 -07002843 def test_delayed_repo_init(self):
James E. Blairf84026c2015-12-08 16:11:46 -08002844 self.updateConfigLayout(
2845 'tests/fixtures/layout-delayed-repo-init.yaml')
James E. Blair287c06d2013-07-24 10:39:30 -07002846 self.sched.reconfigure(self.config)
2847
2848 self.init_repo("org/new-project")
2849 A = self.fake_gerrit.addFakeChange('org/new-project', 'master', 'A')
2850
2851 A.addApproval('CRVW', 2)
2852 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2853 self.waitUntilSettled()
2854 self.assertEqual(self.getJobFromHistory('project-merge').result,
2855 'SUCCESS')
2856 self.assertEqual(self.getJobFromHistory('project-test1').result,
2857 'SUCCESS')
2858 self.assertEqual(self.getJobFromHistory('project-test2').result,
2859 'SUCCESS')
2860 self.assertEqual(A.data['status'], 'MERGED')
2861 self.assertEqual(A.reported, 2)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002862
James E. Blairec056492016-07-22 09:45:56 -07002863 @skip("Disabled for early v3 development")
Clark Boylan6dbbc482013-10-18 10:57:31 -07002864 def test_repo_deleted(self):
James E. Blairf84026c2015-12-08 16:11:46 -08002865 self.updateConfigLayout(
2866 'tests/fixtures/layout-repo-deleted.yaml')
Clark Boylan6dbbc482013-10-18 10:57:31 -07002867 self.sched.reconfigure(self.config)
2868
2869 self.init_repo("org/delete-project")
2870 A = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'A')
2871
2872 A.addApproval('CRVW', 2)
2873 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2874 self.waitUntilSettled()
2875 self.assertEqual(self.getJobFromHistory('project-merge').result,
2876 'SUCCESS')
2877 self.assertEqual(self.getJobFromHistory('project-test1').result,
2878 'SUCCESS')
2879 self.assertEqual(self.getJobFromHistory('project-test2').result,
2880 'SUCCESS')
2881 self.assertEqual(A.data['status'], 'MERGED')
2882 self.assertEqual(A.reported, 2)
2883
2884 # Delete org/new-project zuul repo. Should be recloned.
2885 shutil.rmtree(os.path.join(self.git_root, "org/delete-project"))
2886
2887 B = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'B')
2888
2889 B.addApproval('CRVW', 2)
2890 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2891 self.waitUntilSettled()
2892 self.assertEqual(self.getJobFromHistory('project-merge').result,
2893 'SUCCESS')
2894 self.assertEqual(self.getJobFromHistory('project-test1').result,
2895 'SUCCESS')
2896 self.assertEqual(self.getJobFromHistory('project-test2').result,
2897 'SUCCESS')
2898 self.assertEqual(B.data['status'], 'MERGED')
2899 self.assertEqual(B.reported, 2)
2900
James E. Blairec056492016-07-22 09:45:56 -07002901 @skip("Disabled for early v3 development")
James E. Blair456f2fb2016-02-09 09:29:33 -08002902 def test_tags(self):
2903 "Test job tags"
2904 self.config.set('zuul', 'layout_config',
2905 'tests/fixtures/layout-tags.yaml')
2906 self.sched.reconfigure(self.config)
2907
2908 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2909 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
2910 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2911 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2912 self.waitUntilSettled()
2913
2914 results = {'project1-merge': 'extratag merge project1',
2915 'project2-merge': 'merge'}
2916
2917 for build in self.history:
2918 self.assertEqual(results.get(build.name, ''),
2919 build.parameters.get('BUILD_TAGS'))
2920
James E. Blairec056492016-07-22 09:45:56 -07002921 @skip("Disabled for early v3 development")
James E. Blair63bb0ef2013-07-29 17:14:51 -07002922 def test_timer(self):
2923 "Test that a periodic job is triggered"
2924 self.worker.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08002925 self.updateConfigLayout(
2926 'tests/fixtures/layout-timer.yaml')
James E. Blair63bb0ef2013-07-29 17:14:51 -07002927 self.sched.reconfigure(self.config)
2928 self.registerJobs()
2929
Clark Boylan3ee090a2014-04-03 20:55:09 -07002930 # The pipeline triggers every second, so we should have seen
2931 # several by now.
2932 time.sleep(5)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002933 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002934
2935 self.assertEqual(len(self.builds), 2)
2936
James E. Blair63bb0ef2013-07-29 17:14:51 -07002937 port = self.webapp.server.socket.getsockname()[1]
2938
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002939 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2940 f = urllib.request.urlopen(req)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002941 data = f.read()
2942
2943 self.worker.hold_jobs_in_build = False
Clark Boylan3ee090a2014-04-03 20:55:09 -07002944 # Stop queuing timer triggered jobs so that the assertions
2945 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08002946 self.updateConfigLayout(
2947 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002948 self.sched.reconfigure(self.config)
2949 self.registerJobs()
James E. Blair63bb0ef2013-07-29 17:14:51 -07002950 self.worker.release()
2951 self.waitUntilSettled()
2952
2953 self.assertEqual(self.getJobFromHistory(
2954 'project-bitrot-stable-old').result, 'SUCCESS')
2955 self.assertEqual(self.getJobFromHistory(
2956 'project-bitrot-stable-older').result, 'SUCCESS')
2957
2958 data = json.loads(data)
2959 status_jobs = set()
2960 for p in data['pipelines']:
2961 for q in p['change_queues']:
2962 for head in q['heads']:
2963 for change in head:
Alex Gaynorddb9ef32013-09-16 21:04:58 -07002964 self.assertEqual(change['id'], None)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002965 for job in change['jobs']:
2966 status_jobs.add(job['name'])
2967 self.assertIn('project-bitrot-stable-old', status_jobs)
2968 self.assertIn('project-bitrot-stable-older', status_jobs)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002969
James E. Blairec056492016-07-22 09:45:56 -07002970 @skip("Disabled for early v3 development")
James E. Blair4f6033c2014-03-27 15:49:09 -07002971 def test_idle(self):
2972 "Test that frequent periodic jobs work"
2973 self.worker.hold_jobs_in_build = True
James E. Blair4f6033c2014-03-27 15:49:09 -07002974
Clark Boylan3ee090a2014-04-03 20:55:09 -07002975 for x in range(1, 3):
2976 # Test that timer triggers periodic jobs even across
2977 # layout config reloads.
2978 # Start timer trigger
James E. Blairf84026c2015-12-08 16:11:46 -08002979 self.updateConfigLayout(
2980 'tests/fixtures/layout-idle.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002981 self.sched.reconfigure(self.config)
2982 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08002983 self.waitUntilSettled()
James E. Blair4f6033c2014-03-27 15:49:09 -07002984
Clark Boylan3ee090a2014-04-03 20:55:09 -07002985 # The pipeline triggers every second, so we should have seen
2986 # several by now.
2987 time.sleep(5)
Clark Boylan3ee090a2014-04-03 20:55:09 -07002988
2989 # Stop queuing timer triggered jobs so that the assertions
2990 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08002991 self.updateConfigLayout(
2992 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002993 self.sched.reconfigure(self.config)
2994 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08002995 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002996
2997 self.assertEqual(len(self.builds), 2)
2998 self.worker.release('.*')
2999 self.waitUntilSettled()
3000 self.assertEqual(len(self.builds), 0)
3001 self.assertEqual(len(self.history), x * 2)
James E. Blair4f6033c2014-03-27 15:49:09 -07003002
James E. Blairec056492016-07-22 09:45:56 -07003003 @skip("Disabled for early v3 development")
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003004 def test_check_smtp_pool(self):
James E. Blairf84026c2015-12-08 16:11:46 -08003005 self.updateConfigLayout(
3006 'tests/fixtures/layout-smtp.yaml')
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003007 self.sched.reconfigure(self.config)
3008
3009 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3010 self.waitUntilSettled()
3011
3012 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
3013 self.waitUntilSettled()
3014
James E. Blairff80a2f2013-12-27 13:24:06 -08003015 self.assertEqual(len(self.smtp_messages), 2)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003016
3017 # A.messages only holds what FakeGerrit places in it. Thus we
3018 # work on the knowledge of what the first message should be as
3019 # it is only configured to go to SMTP.
3020
3021 self.assertEqual('zuul@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003022 self.smtp_messages[0]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003023 self.assertEqual(['you@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003024 self.smtp_messages[0]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003025 self.assertEqual('Starting check jobs.',
James E. Blairff80a2f2013-12-27 13:24:06 -08003026 self.smtp_messages[0]['body'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003027
3028 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003029 self.smtp_messages[1]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003030 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003031 self.smtp_messages[1]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003032 self.assertEqual(A.messages[0],
James E. Blairff80a2f2013-12-27 13:24:06 -08003033 self.smtp_messages[1]['body'])
James E. Blairad28e912013-11-27 10:43:22 -08003034
James E. Blairec056492016-07-22 09:45:56 -07003035 @skip("Disabled for early v3 development")
James E. Blaire5910202013-12-27 09:50:31 -08003036 def test_timer_smtp(self):
3037 "Test that a periodic job is triggered"
Clark Boylan3ee090a2014-04-03 20:55:09 -07003038 self.worker.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08003039 self.updateConfigLayout(
3040 'tests/fixtures/layout-timer-smtp.yaml')
James E. Blaire5910202013-12-27 09:50:31 -08003041 self.sched.reconfigure(self.config)
3042 self.registerJobs()
3043
Clark Boylan3ee090a2014-04-03 20:55:09 -07003044 # The pipeline triggers every second, so we should have seen
3045 # several by now.
3046 time.sleep(5)
James E. Blaire5910202013-12-27 09:50:31 -08003047 self.waitUntilSettled()
3048
Clark Boylan3ee090a2014-04-03 20:55:09 -07003049 self.assertEqual(len(self.builds), 2)
3050 self.worker.release('.*')
3051 self.waitUntilSettled()
3052 self.assertEqual(len(self.history), 2)
3053
James E. Blaire5910202013-12-27 09:50:31 -08003054 self.assertEqual(self.getJobFromHistory(
3055 'project-bitrot-stable-old').result, 'SUCCESS')
3056 self.assertEqual(self.getJobFromHistory(
3057 'project-bitrot-stable-older').result, 'SUCCESS')
3058
James E. Blairff80a2f2013-12-27 13:24:06 -08003059 self.assertEqual(len(self.smtp_messages), 1)
James E. Blaire5910202013-12-27 09:50:31 -08003060
3061 # A.messages only holds what FakeGerrit places in it. Thus we
3062 # work on the knowledge of what the first message should be as
3063 # it is only configured to go to SMTP.
3064
3065 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003066 self.smtp_messages[0]['from_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003067 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003068 self.smtp_messages[0]['to_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003069 self.assertIn('Subject: Periodic check for org/project succeeded',
James E. Blairff80a2f2013-12-27 13:24:06 -08003070 self.smtp_messages[0]['headers'])
James E. Blaire5910202013-12-27 09:50:31 -08003071
Clark Boylan3ee090a2014-04-03 20:55:09 -07003072 # Stop queuing timer triggered jobs and let any that may have
3073 # queued through so that end of test assertions pass.
James E. Blairf84026c2015-12-08 16:11:46 -08003074 self.updateConfigLayout(
3075 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07003076 self.sched.reconfigure(self.config)
3077 self.registerJobs()
James E. Blairf8058972014-08-15 16:09:16 -07003078 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07003079 self.worker.release('.*')
3080 self.waitUntilSettled()
3081
James E. Blairec056492016-07-22 09:45:56 -07003082 @skip("Disabled for early v3 development")
James E. Blair91e34592015-07-31 16:45:59 -07003083 def test_client_enqueue_change(self):
James E. Blairad28e912013-11-27 10:43:22 -08003084 "Test that the RPC client can enqueue a change"
3085 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3086 A.addApproval('CRVW', 2)
3087 A.addApproval('APRV', 1)
3088
3089 client = zuul.rpcclient.RPCClient('127.0.0.1',
3090 self.gearman_server.port)
3091 r = client.enqueue(pipeline='gate',
3092 project='org/project',
3093 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003094 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003095 self.waitUntilSettled()
3096 self.assertEqual(self.getJobFromHistory('project-merge').result,
3097 'SUCCESS')
3098 self.assertEqual(self.getJobFromHistory('project-test1').result,
3099 'SUCCESS')
3100 self.assertEqual(self.getJobFromHistory('project-test2').result,
3101 'SUCCESS')
3102 self.assertEqual(A.data['status'], 'MERGED')
3103 self.assertEqual(A.reported, 2)
3104 self.assertEqual(r, True)
3105
James E. Blairec056492016-07-22 09:45:56 -07003106 @skip("Disabled for early v3 development")
James E. Blair91e34592015-07-31 16:45:59 -07003107 def test_client_enqueue_ref(self):
3108 "Test that the RPC client can enqueue a ref"
3109
3110 client = zuul.rpcclient.RPCClient('127.0.0.1',
3111 self.gearman_server.port)
3112 r = client.enqueue_ref(
3113 pipeline='post',
3114 project='org/project',
3115 trigger='gerrit',
3116 ref='master',
3117 oldrev='90f173846e3af9154517b88543ffbd1691f31366',
3118 newrev='d479a0bfcb34da57a31adb2a595c0cf687812543')
3119 self.waitUntilSettled()
3120 job_names = [x.name for x in self.history]
3121 self.assertEqual(len(self.history), 1)
3122 self.assertIn('project-post', job_names)
3123 self.assertEqual(r, True)
3124
James E. Blairec056492016-07-22 09:45:56 -07003125 @skip("Disabled for early v3 development")
James E. Blairad28e912013-11-27 10:43:22 -08003126 def test_client_enqueue_negative(self):
3127 "Test that the RPC client returns errors"
3128 client = zuul.rpcclient.RPCClient('127.0.0.1',
3129 self.gearman_server.port)
3130 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3131 "Invalid project"):
3132 r = client.enqueue(pipeline='gate',
3133 project='project-does-not-exist',
3134 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003135 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003136 client.shutdown()
3137 self.assertEqual(r, False)
3138
3139 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3140 "Invalid pipeline"):
3141 r = client.enqueue(pipeline='pipeline-does-not-exist',
3142 project='org/project',
3143 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003144 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003145 client.shutdown()
3146 self.assertEqual(r, False)
3147
3148 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3149 "Invalid trigger"):
3150 r = client.enqueue(pipeline='gate',
3151 project='org/project',
3152 trigger='trigger-does-not-exist',
James E. Blair36658cf2013-12-06 17:53:48 -08003153 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003154 client.shutdown()
3155 self.assertEqual(r, False)
3156
3157 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3158 "Invalid change"):
3159 r = client.enqueue(pipeline='gate',
3160 project='org/project',
3161 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003162 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003163 client.shutdown()
3164 self.assertEqual(r, False)
3165
3166 self.waitUntilSettled()
3167 self.assertEqual(len(self.history), 0)
3168 self.assertEqual(len(self.builds), 0)
James E. Blair36658cf2013-12-06 17:53:48 -08003169
James E. Blairec056492016-07-22 09:45:56 -07003170 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003171 def test_client_promote(self):
3172 "Test that the RPC client can promote a change"
3173 self.worker.hold_jobs_in_build = True
3174 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3175 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3176 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3177 A.addApproval('CRVW', 2)
3178 B.addApproval('CRVW', 2)
3179 C.addApproval('CRVW', 2)
3180
3181 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3182 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3183 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3184
3185 self.waitUntilSettled()
3186
Sean Daguef39b9ca2014-01-10 21:34:35 -05003187 items = self.sched.layout.pipelines['gate'].getAllItems()
3188 enqueue_times = {}
3189 for item in items:
3190 enqueue_times[str(item.change)] = item.enqueue_time
3191
James E. Blair36658cf2013-12-06 17:53:48 -08003192 client = zuul.rpcclient.RPCClient('127.0.0.1',
3193 self.gearman_server.port)
3194 r = client.promote(pipeline='gate',
3195 change_ids=['2,1', '3,1'])
3196
Sean Daguef39b9ca2014-01-10 21:34:35 -05003197 # ensure that enqueue times are durable
3198 items = self.sched.layout.pipelines['gate'].getAllItems()
3199 for item in items:
3200 self.assertEqual(
3201 enqueue_times[str(item.change)], item.enqueue_time)
3202
James E. Blair78acec92014-02-06 07:11:32 -08003203 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08003204 self.worker.release('.*-merge')
3205 self.waitUntilSettled()
3206 self.worker.release('.*-merge')
3207 self.waitUntilSettled()
3208 self.worker.release('.*-merge')
3209 self.waitUntilSettled()
3210
3211 self.assertEqual(len(self.builds), 6)
3212 self.assertEqual(self.builds[0].name, 'project-test1')
3213 self.assertEqual(self.builds[1].name, 'project-test2')
3214 self.assertEqual(self.builds[2].name, 'project-test1')
3215 self.assertEqual(self.builds[3].name, 'project-test2')
3216 self.assertEqual(self.builds[4].name, 'project-test1')
3217 self.assertEqual(self.builds[5].name, 'project-test2')
3218
3219 self.assertTrue(self.job_has_changes(self.builds[0], B))
3220 self.assertFalse(self.job_has_changes(self.builds[0], A))
3221 self.assertFalse(self.job_has_changes(self.builds[0], C))
3222
3223 self.assertTrue(self.job_has_changes(self.builds[2], B))
3224 self.assertTrue(self.job_has_changes(self.builds[2], C))
3225 self.assertFalse(self.job_has_changes(self.builds[2], A))
3226
3227 self.assertTrue(self.job_has_changes(self.builds[4], B))
3228 self.assertTrue(self.job_has_changes(self.builds[4], C))
3229 self.assertTrue(self.job_has_changes(self.builds[4], A))
3230
3231 self.worker.release()
3232 self.waitUntilSettled()
3233
3234 self.assertEqual(A.data['status'], 'MERGED')
3235 self.assertEqual(A.reported, 2)
3236 self.assertEqual(B.data['status'], 'MERGED')
3237 self.assertEqual(B.reported, 2)
3238 self.assertEqual(C.data['status'], 'MERGED')
3239 self.assertEqual(C.reported, 2)
3240
3241 client.shutdown()
3242 self.assertEqual(r, True)
3243
James E. Blairec056492016-07-22 09:45:56 -07003244 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003245 def test_client_promote_dependent(self):
3246 "Test that the RPC client can promote a dependent change"
3247 # C (depends on B) -> B -> A ; then promote C to get:
3248 # A -> C (depends on B) -> B
3249 self.worker.hold_jobs_in_build = True
3250 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3251 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3252 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3253
3254 C.setDependsOn(B, 1)
3255
3256 A.addApproval('CRVW', 2)
3257 B.addApproval('CRVW', 2)
3258 C.addApproval('CRVW', 2)
3259
3260 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3261 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3262 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3263
3264 self.waitUntilSettled()
3265
3266 client = zuul.rpcclient.RPCClient('127.0.0.1',
3267 self.gearman_server.port)
3268 r = client.promote(pipeline='gate',
3269 change_ids=['3,1'])
3270
James E. Blair78acec92014-02-06 07:11:32 -08003271 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08003272 self.worker.release('.*-merge')
3273 self.waitUntilSettled()
3274 self.worker.release('.*-merge')
3275 self.waitUntilSettled()
3276 self.worker.release('.*-merge')
3277 self.waitUntilSettled()
3278
3279 self.assertEqual(len(self.builds), 6)
3280 self.assertEqual(self.builds[0].name, 'project-test1')
3281 self.assertEqual(self.builds[1].name, 'project-test2')
3282 self.assertEqual(self.builds[2].name, 'project-test1')
3283 self.assertEqual(self.builds[3].name, 'project-test2')
3284 self.assertEqual(self.builds[4].name, 'project-test1')
3285 self.assertEqual(self.builds[5].name, 'project-test2')
3286
3287 self.assertTrue(self.job_has_changes(self.builds[0], B))
3288 self.assertFalse(self.job_has_changes(self.builds[0], A))
3289 self.assertFalse(self.job_has_changes(self.builds[0], C))
3290
3291 self.assertTrue(self.job_has_changes(self.builds[2], B))
3292 self.assertTrue(self.job_has_changes(self.builds[2], C))
3293 self.assertFalse(self.job_has_changes(self.builds[2], A))
3294
3295 self.assertTrue(self.job_has_changes(self.builds[4], B))
3296 self.assertTrue(self.job_has_changes(self.builds[4], C))
3297 self.assertTrue(self.job_has_changes(self.builds[4], A))
3298
3299 self.worker.release()
3300 self.waitUntilSettled()
3301
3302 self.assertEqual(A.data['status'], 'MERGED')
3303 self.assertEqual(A.reported, 2)
3304 self.assertEqual(B.data['status'], 'MERGED')
3305 self.assertEqual(B.reported, 2)
3306 self.assertEqual(C.data['status'], 'MERGED')
3307 self.assertEqual(C.reported, 2)
3308
3309 client.shutdown()
3310 self.assertEqual(r, True)
3311
James E. Blairec056492016-07-22 09:45:56 -07003312 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003313 def test_client_promote_negative(self):
3314 "Test that the RPC client returns errors for promotion"
3315 self.worker.hold_jobs_in_build = True
3316 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3317 A.addApproval('CRVW', 2)
3318 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3319 self.waitUntilSettled()
3320
3321 client = zuul.rpcclient.RPCClient('127.0.0.1',
3322 self.gearman_server.port)
3323
3324 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
3325 r = client.promote(pipeline='nonexistent',
3326 change_ids=['2,1', '3,1'])
3327 client.shutdown()
3328 self.assertEqual(r, False)
3329
3330 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
3331 r = client.promote(pipeline='gate',
3332 change_ids=['4,1'])
3333 client.shutdown()
3334 self.assertEqual(r, False)
3335
3336 self.worker.hold_jobs_in_build = False
3337 self.worker.release()
3338 self.waitUntilSettled()
Clark Boylan7603a372014-01-21 11:43:20 -08003339
James E. Blairec056492016-07-22 09:45:56 -07003340 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003341 def test_queue_rate_limiting(self):
3342 "Test that DependentPipelines are rate limited with dep across window"
James E. Blairf84026c2015-12-08 16:11:46 -08003343 self.updateConfigLayout(
3344 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003345 self.sched.reconfigure(self.config)
3346 self.worker.hold_jobs_in_build = True
3347 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3348 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3349 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3350
3351 C.setDependsOn(B, 1)
3352 self.worker.addFailTest('project-test1', A)
3353
3354 A.addApproval('CRVW', 2)
3355 B.addApproval('CRVW', 2)
3356 C.addApproval('CRVW', 2)
3357
3358 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3359 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3360 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3361 self.waitUntilSettled()
3362
3363 # Only A and B will have their merge jobs queued because
3364 # window is 2.
3365 self.assertEqual(len(self.builds), 2)
3366 self.assertEqual(self.builds[0].name, 'project-merge')
3367 self.assertEqual(self.builds[1].name, 'project-merge')
3368
3369 self.worker.release('.*-merge')
3370 self.waitUntilSettled()
3371 self.worker.release('.*-merge')
3372 self.waitUntilSettled()
3373
3374 # Only A and B will have their test jobs queued because
3375 # window is 2.
3376 self.assertEqual(len(self.builds), 4)
3377 self.assertEqual(self.builds[0].name, 'project-test1')
3378 self.assertEqual(self.builds[1].name, 'project-test2')
3379 self.assertEqual(self.builds[2].name, 'project-test1')
3380 self.assertEqual(self.builds[3].name, 'project-test2')
3381
3382 self.worker.release('project-.*')
3383 self.waitUntilSettled()
3384
3385 queue = self.sched.layout.pipelines['gate'].queues[0]
3386 # A failed so window is reduced by 1 to 1.
3387 self.assertEqual(queue.window, 1)
3388 self.assertEqual(queue.window_floor, 1)
3389 self.assertEqual(A.data['status'], 'NEW')
3390
3391 # Gate is reset and only B's merge job is queued because
3392 # window shrunk to 1.
3393 self.assertEqual(len(self.builds), 1)
3394 self.assertEqual(self.builds[0].name, 'project-merge')
3395
3396 self.worker.release('.*-merge')
3397 self.waitUntilSettled()
3398
3399 # Only B's test jobs are queued because window is still 1.
3400 self.assertEqual(len(self.builds), 2)
3401 self.assertEqual(self.builds[0].name, 'project-test1')
3402 self.assertEqual(self.builds[1].name, 'project-test2')
3403
3404 self.worker.release('project-.*')
3405 self.waitUntilSettled()
3406
3407 # B was successfully merged so window is increased to 2.
3408 self.assertEqual(queue.window, 2)
3409 self.assertEqual(queue.window_floor, 1)
3410 self.assertEqual(B.data['status'], 'MERGED')
3411
3412 # Only C is left and its merge job is queued.
3413 self.assertEqual(len(self.builds), 1)
3414 self.assertEqual(self.builds[0].name, 'project-merge')
3415
3416 self.worker.release('.*-merge')
3417 self.waitUntilSettled()
3418
3419 # After successful merge job the test jobs for C are queued.
3420 self.assertEqual(len(self.builds), 2)
3421 self.assertEqual(self.builds[0].name, 'project-test1')
3422 self.assertEqual(self.builds[1].name, 'project-test2')
3423
3424 self.worker.release('project-.*')
3425 self.waitUntilSettled()
3426
3427 # C successfully merged so window is bumped to 3.
3428 self.assertEqual(queue.window, 3)
3429 self.assertEqual(queue.window_floor, 1)
3430 self.assertEqual(C.data['status'], 'MERGED')
3431
James E. Blairec056492016-07-22 09:45:56 -07003432 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003433 def test_queue_rate_limiting_dependent(self):
3434 "Test that DependentPipelines are rate limited with dep in window"
James E. Blairf84026c2015-12-08 16:11:46 -08003435 self.updateConfigLayout(
3436 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003437 self.sched.reconfigure(self.config)
3438 self.worker.hold_jobs_in_build = True
3439 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3440 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3441 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3442
3443 B.setDependsOn(A, 1)
3444
3445 self.worker.addFailTest('project-test1', A)
3446
3447 A.addApproval('CRVW', 2)
3448 B.addApproval('CRVW', 2)
3449 C.addApproval('CRVW', 2)
3450
3451 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3452 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3453 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3454 self.waitUntilSettled()
3455
3456 # Only A and B will have their merge jobs queued because
3457 # window is 2.
3458 self.assertEqual(len(self.builds), 2)
3459 self.assertEqual(self.builds[0].name, 'project-merge')
3460 self.assertEqual(self.builds[1].name, 'project-merge')
3461
3462 self.worker.release('.*-merge')
3463 self.waitUntilSettled()
3464 self.worker.release('.*-merge')
3465 self.waitUntilSettled()
3466
3467 # Only A and B will have their test jobs queued because
3468 # window is 2.
3469 self.assertEqual(len(self.builds), 4)
3470 self.assertEqual(self.builds[0].name, 'project-test1')
3471 self.assertEqual(self.builds[1].name, 'project-test2')
3472 self.assertEqual(self.builds[2].name, 'project-test1')
3473 self.assertEqual(self.builds[3].name, 'project-test2')
3474
3475 self.worker.release('project-.*')
3476 self.waitUntilSettled()
3477
3478 queue = self.sched.layout.pipelines['gate'].queues[0]
3479 # A failed so window is reduced by 1 to 1.
3480 self.assertEqual(queue.window, 1)
3481 self.assertEqual(queue.window_floor, 1)
3482 self.assertEqual(A.data['status'], 'NEW')
3483 self.assertEqual(B.data['status'], 'NEW')
3484
3485 # Gate is reset and only C's merge job is queued because
3486 # window shrunk to 1 and A and B were dequeued.
3487 self.assertEqual(len(self.builds), 1)
3488 self.assertEqual(self.builds[0].name, 'project-merge')
3489
3490 self.worker.release('.*-merge')
3491 self.waitUntilSettled()
3492
3493 # Only C's test jobs are queued because window is still 1.
3494 self.assertEqual(len(self.builds), 2)
3495 self.assertEqual(self.builds[0].name, 'project-test1')
3496 self.assertEqual(self.builds[1].name, 'project-test2')
3497
3498 self.worker.release('project-.*')
3499 self.waitUntilSettled()
3500
3501 # C was successfully merged so window is increased to 2.
3502 self.assertEqual(queue.window, 2)
3503 self.assertEqual(queue.window_floor, 1)
3504 self.assertEqual(C.data['status'], 'MERGED')
Joshua Heskethba8776a2014-01-12 14:35:40 +08003505
James E. Blairec056492016-07-22 09:45:56 -07003506 @skip("Disabled for early v3 development")
Joshua Heskethba8776a2014-01-12 14:35:40 +08003507 def test_worker_update_metadata(self):
3508 "Test if a worker can send back metadata about itself"
3509 self.worker.hold_jobs_in_build = True
3510
3511 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3512 A.addApproval('CRVW', 2)
3513 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3514 self.waitUntilSettled()
3515
3516 self.assertEqual(len(self.launcher.builds), 1)
3517
3518 self.log.debug('Current builds:')
3519 self.log.debug(self.launcher.builds)
3520
3521 start = time.time()
3522 while True:
3523 if time.time() - start > 10:
3524 raise Exception("Timeout waiting for gearman server to report "
3525 + "back to the client")
3526 build = self.launcher.builds.values()[0]
3527 if build.worker.name == "My Worker":
3528 break
3529 else:
3530 time.sleep(0)
3531
3532 self.log.debug(build)
3533 self.assertEqual("My Worker", build.worker.name)
3534 self.assertEqual("localhost", build.worker.hostname)
3535 self.assertEqual(['127.0.0.1', '192.168.1.1'], build.worker.ips)
3536 self.assertEqual("zuul.example.org", build.worker.fqdn)
3537 self.assertEqual("FakeBuilder", build.worker.program)
3538 self.assertEqual("v1.1", build.worker.version)
3539 self.assertEqual({'something': 'else'}, build.worker.extra)
3540
3541 self.worker.hold_jobs_in_build = False
3542 self.worker.release()
3543 self.waitUntilSettled()
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003544
James E. Blairec056492016-07-22 09:45:56 -07003545 @skip("Disabled for early v3 development")
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003546 def test_footer_message(self):
3547 "Test a pipeline's footer message is correctly added to the report."
James E. Blairf84026c2015-12-08 16:11:46 -08003548 self.updateConfigLayout(
3549 'tests/fixtures/layout-footer-message.yaml')
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003550 self.sched.reconfigure(self.config)
3551 self.registerJobs()
3552
3553 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3554 A.addApproval('CRVW', 2)
3555 self.worker.addFailTest('test1', A)
3556 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3557 self.waitUntilSettled()
3558
3559 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3560 B.addApproval('CRVW', 2)
3561 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3562 self.waitUntilSettled()
3563
3564 self.assertEqual(2, len(self.smtp_messages))
3565
3566 failure_body = """\
3567Build failed. For information on how to proceed, see \
3568http://wiki.example.org/Test_Failures
3569
3570- test1 http://logs.example.com/1/1/gate/test1/0 : FAILURE in 0s
3571- test2 http://logs.example.com/1/1/gate/test2/1 : SUCCESS in 0s
3572
3573For CI problems and help debugging, contact ci@example.org"""
3574
3575 success_body = """\
3576Build succeeded.
3577
3578- test1 http://logs.example.com/2/1/gate/test1/2 : SUCCESS in 0s
3579- test2 http://logs.example.com/2/1/gate/test2/3 : SUCCESS in 0s
3580
3581For CI problems and help debugging, contact ci@example.org"""
3582
3583 self.assertEqual(failure_body, self.smtp_messages[0]['body'])
3584 self.assertEqual(success_body, self.smtp_messages[1]['body'])
Joshua Heskethb7179772014-01-30 23:30:46 +11003585
James E. Blairec056492016-07-22 09:45:56 -07003586 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003587 def test_merge_failure_reporters(self):
3588 """Check that the config is set up correctly"""
3589
James E. Blairf84026c2015-12-08 16:11:46 -08003590 self.updateConfigLayout(
3591 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003592 self.sched.reconfigure(self.config)
3593 self.registerJobs()
3594
3595 self.assertEqual(
Jeremy Stanley1c2c3c22015-06-15 21:23:19 +00003596 "Merge Failed.\n\nThis change or one of its cross-repo "
3597 "dependencies was unable to be automatically merged with the "
3598 "current state of its repository. Please rebase the change and "
3599 "upload a new patchset.",
Joshua Heskethb7179772014-01-30 23:30:46 +11003600 self.sched.layout.pipelines['check'].merge_failure_message)
3601 self.assertEqual(
3602 "The merge failed! For more information...",
3603 self.sched.layout.pipelines['gate'].merge_failure_message)
3604
3605 self.assertEqual(
3606 len(self.sched.layout.pipelines['check'].merge_failure_actions), 1)
3607 self.assertEqual(
3608 len(self.sched.layout.pipelines['gate'].merge_failure_actions), 2)
3609
3610 self.assertTrue(isinstance(
Joshua Heskethde958652015-11-10 19:19:50 +11003611 self.sched.layout.pipelines['check'].merge_failure_actions[0],
3612 zuul.reporter.gerrit.GerritReporter))
Joshua Heskethb7179772014-01-30 23:30:46 +11003613
3614 self.assertTrue(
3615 (
3616 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003617 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003618 zuul.reporter.smtp.SMTPReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003619 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003620 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003621 zuul.reporter.gerrit.GerritReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003622 ) or (
3623 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003624 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003625 zuul.reporter.gerrit.GerritReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003626 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003627 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003628 zuul.reporter.smtp.SMTPReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003629 )
3630 )
3631
James E. Blairec056492016-07-22 09:45:56 -07003632 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003633 def test_merge_failure_reports(self):
3634 """Check that when a change fails to merge the correct message is sent
3635 to the correct reporter"""
James E. Blairf84026c2015-12-08 16:11:46 -08003636 self.updateConfigLayout(
3637 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003638 self.sched.reconfigure(self.config)
3639 self.registerJobs()
3640
3641 # Check a test failure isn't reported to SMTP
3642 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3643 A.addApproval('CRVW', 2)
3644 self.worker.addFailTest('project-test1', A)
3645 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3646 self.waitUntilSettled()
3647
3648 self.assertEqual(3, len(self.history)) # 3 jobs
3649 self.assertEqual(0, len(self.smtp_messages))
3650
3651 # Check a merge failure is reported to SMTP
3652 # B should be merged, but C will conflict with B
3653 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3654 B.addPatchset(['conflict'])
3655 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3656 C.addPatchset(['conflict'])
3657 B.addApproval('CRVW', 2)
3658 C.addApproval('CRVW', 2)
3659 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3660 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3661 self.waitUntilSettled()
3662
3663 self.assertEqual(6, len(self.history)) # A and B jobs
3664 self.assertEqual(1, len(self.smtp_messages))
3665 self.assertEqual('The merge failed! For more information...',
3666 self.smtp_messages[0]['body'])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003667
James E. Blairec056492016-07-22 09:45:56 -07003668 @skip("Disabled for early v3 development")
James E. Blairf760f0e2016-02-09 08:44:52 -08003669 def test_default_merge_failure_reports(self):
3670 """Check that the default merge failure reports are correct."""
3671
3672 # A should report success, B should report merge failure.
3673 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3674 A.addPatchset(['conflict'])
3675 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3676 B.addPatchset(['conflict'])
3677 A.addApproval('CRVW', 2)
3678 B.addApproval('CRVW', 2)
3679 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3680 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3681 self.waitUntilSettled()
3682
3683 self.assertEqual(3, len(self.history)) # A jobs
3684 self.assertEqual(A.reported, 2)
3685 self.assertEqual(B.reported, 2)
3686 self.assertEqual(A.data['status'], 'MERGED')
3687 self.assertEqual(B.data['status'], 'NEW')
3688 self.assertIn('Build succeeded', A.messages[1])
3689 self.assertIn('Merge Failed', B.messages[1])
3690 self.assertIn('automatically merged', B.messages[1])
3691 self.assertNotIn('logs.example.com', B.messages[1])
3692 self.assertNotIn('SKIPPED', B.messages[1])
3693
James E. Blairec056492016-07-22 09:45:56 -07003694 @skip("Disabled for early v3 development")
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003695 def test_swift_instructions(self):
3696 "Test that the correct swift instructions are sent to the workers"
James E. Blairf84026c2015-12-08 16:11:46 -08003697 self.updateConfigLayout(
3698 'tests/fixtures/layout-swift.yaml')
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003699 self.sched.reconfigure(self.config)
3700 self.registerJobs()
3701
3702 self.worker.hold_jobs_in_build = True
3703 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3704
3705 A.addApproval('CRVW', 2)
3706 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3707 self.waitUntilSettled()
3708
3709 self.assertEqual(
3710 "https://storage.example.org/V1/AUTH_account/merge_logs/1/1/1/"
3711 "gate/test-merge/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003712 self.builds[0].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003713 self.assertEqual(5,
3714 len(self.builds[0].parameters['SWIFT_logs_HMAC_BODY'].
3715 split('\n')))
3716 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[0].parameters)
3717
3718 self.assertEqual(
3719 "https://storage.example.org/V1/AUTH_account/logs/1/1/1/"
3720 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003721 self.builds[1].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003722 self.assertEqual(5,
3723 len(self.builds[1].parameters['SWIFT_logs_HMAC_BODY'].
3724 split('\n')))
3725 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[1].parameters)
3726
3727 self.assertEqual(
3728 "https://storage.example.org/V1/AUTH_account/stash/1/1/1/"
3729 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003730 self.builds[1].parameters['SWIFT_MOSTLY_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003731 self.assertEqual(5,
3732 len(self.builds[1].
3733 parameters['SWIFT_MOSTLY_HMAC_BODY'].split('\n')))
3734 self.assertIn('SWIFT_MOSTLY_SIGNATURE', self.builds[1].parameters)
3735
3736 self.worker.hold_jobs_in_build = False
3737 self.worker.release()
3738 self.waitUntilSettled()
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003739
James E. Blairec056492016-07-22 09:45:56 -07003740 @skip("Disabled for early v3 development")
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003741 def test_client_get_running_jobs(self):
3742 "Test that the RPC client can get a list of running jobs"
3743 self.worker.hold_jobs_in_build = True
3744 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3745 A.addApproval('CRVW', 2)
3746 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3747 self.waitUntilSettled()
3748
3749 client = zuul.rpcclient.RPCClient('127.0.0.1',
3750 self.gearman_server.port)
3751
3752 # Wait for gearman server to send the initial workData back to zuul
3753 start = time.time()
3754 while True:
3755 if time.time() - start > 10:
3756 raise Exception("Timeout waiting for gearman server to report "
3757 + "back to the client")
3758 build = self.launcher.builds.values()[0]
3759 if build.worker.name == "My Worker":
3760 break
3761 else:
3762 time.sleep(0)
3763
3764 running_items = client.get_running_jobs()
3765
3766 self.assertEqual(1, len(running_items))
3767 running_item = running_items[0]
3768 self.assertEqual([], running_item['failing_reasons'])
3769 self.assertEqual([], running_item['items_behind'])
3770 self.assertEqual('https://hostname/1', running_item['url'])
3771 self.assertEqual(None, running_item['item_ahead'])
3772 self.assertEqual('org/project', running_item['project'])
3773 self.assertEqual(None, running_item['remaining_time'])
3774 self.assertEqual(True, running_item['active'])
3775 self.assertEqual('1,1', running_item['id'])
3776
3777 self.assertEqual(3, len(running_item['jobs']))
3778 for job in running_item['jobs']:
3779 if job['name'] == 'project-merge':
3780 self.assertEqual('project-merge', job['name'])
3781 self.assertEqual('gate', job['pipeline'])
3782 self.assertEqual(False, job['retry'])
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003783 self.assertEqual('https://server/job/project-merge/0/',
3784 job['url'])
3785 self.assertEqual(7, len(job['worker']))
3786 self.assertEqual(False, job['canceled'])
3787 self.assertEqual(True, job['voting'])
3788 self.assertEqual(None, job['result'])
3789 self.assertEqual('gate', job['pipeline'])
3790 break
3791
3792 self.worker.hold_jobs_in_build = False
3793 self.worker.release()
3794 self.waitUntilSettled()
3795
3796 running_items = client.get_running_jobs()
3797 self.assertEqual(0, len(running_items))
James E. Blairbadc1ad2014-04-28 13:55:14 -07003798
James E. Blairec056492016-07-22 09:45:56 -07003799 @skip("Disabled for early v3 development")
James E. Blairbadc1ad2014-04-28 13:55:14 -07003800 def test_nonvoting_pipeline(self):
3801 "Test that a nonvoting pipeline (experimental) can still report"
3802
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003803 A = self.fake_gerrit.addFakeChange('org/experimental-project',
3804 'master', 'A')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003805 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
3806 self.waitUntilSettled()
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003807 self.assertEqual(
3808 self.getJobFromHistory('experimental-project-test').result,
3809 'SUCCESS')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003810 self.assertEqual(A.reported, 1)
James E. Blair5ee24252014-12-30 10:12:29 -08003811
James E. Blairec056492016-07-22 09:45:56 -07003812 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08003813 def test_crd_gate(self):
3814 "Test cross-repo dependencies"
3815 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3816 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3817 A.addApproval('CRVW', 2)
3818 B.addApproval('CRVW', 2)
3819
3820 AM2 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM2')
3821 AM1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM1')
3822 AM2.setMerged()
3823 AM1.setMerged()
3824
3825 BM2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM2')
3826 BM1 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM1')
3827 BM2.setMerged()
3828 BM1.setMerged()
3829
3830 # A -> AM1 -> AM2
3831 # B -> BM1 -> BM2
3832 # A Depends-On: B
3833 # M2 is here to make sure it is never queried. If it is, it
3834 # means zuul is walking down the entire history of merged
3835 # changes.
3836
3837 B.setDependsOn(BM1, 1)
3838 BM1.setDependsOn(BM2, 1)
3839
3840 A.setDependsOn(AM1, 1)
3841 AM1.setDependsOn(AM2, 1)
3842
3843 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3844 A.subject, B.data['id'])
3845
3846 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3847 self.waitUntilSettled()
3848
3849 self.assertEqual(A.data['status'], 'NEW')
3850 self.assertEqual(B.data['status'], 'NEW')
3851
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11003852 for connection in self.connections.values():
3853 connection.maintainCache([])
James E. Blair5ee24252014-12-30 10:12:29 -08003854
3855 self.worker.hold_jobs_in_build = True
3856 B.addApproval('APRV', 1)
3857 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3858 self.waitUntilSettled()
3859
3860 self.worker.release('.*-merge')
3861 self.waitUntilSettled()
3862 self.worker.release('.*-merge')
3863 self.waitUntilSettled()
3864 self.worker.hold_jobs_in_build = False
3865 self.worker.release()
3866 self.waitUntilSettled()
3867
3868 self.assertEqual(AM2.queried, 0)
3869 self.assertEqual(BM2.queried, 0)
3870 self.assertEqual(A.data['status'], 'MERGED')
3871 self.assertEqual(B.data['status'], 'MERGED')
3872 self.assertEqual(A.reported, 2)
3873 self.assertEqual(B.reported, 2)
3874
James E. Blair8f78d882015-02-05 08:51:37 -08003875 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3876 '2,1 1,1')
3877
James E. Blairec056492016-07-22 09:45:56 -07003878 @skip("Disabled for early v3 development")
James E. Blair8f78d882015-02-05 08:51:37 -08003879 def test_crd_branch(self):
3880 "Test cross-repo dependencies in multiple branches"
3881 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3882 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3883 C = self.fake_gerrit.addFakeChange('org/project2', 'mp', 'C')
3884 C.data['id'] = B.data['id']
3885 A.addApproval('CRVW', 2)
3886 B.addApproval('CRVW', 2)
3887 C.addApproval('CRVW', 2)
3888
3889 # A Depends-On: B+C
3890 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3891 A.subject, B.data['id'])
3892
3893 self.worker.hold_jobs_in_build = True
3894 B.addApproval('APRV', 1)
3895 C.addApproval('APRV', 1)
3896 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3897 self.waitUntilSettled()
3898
3899 self.worker.release('.*-merge')
3900 self.waitUntilSettled()
3901 self.worker.release('.*-merge')
3902 self.waitUntilSettled()
3903 self.worker.release('.*-merge')
3904 self.waitUntilSettled()
3905 self.worker.hold_jobs_in_build = False
3906 self.worker.release()
3907 self.waitUntilSettled()
3908
3909 self.assertEqual(A.data['status'], 'MERGED')
3910 self.assertEqual(B.data['status'], 'MERGED')
3911 self.assertEqual(C.data['status'], 'MERGED')
3912 self.assertEqual(A.reported, 2)
3913 self.assertEqual(B.reported, 2)
3914 self.assertEqual(C.reported, 2)
3915
3916 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3917 '2,1 3,1 1,1')
3918
James E. Blairec056492016-07-22 09:45:56 -07003919 @skip("Disabled for early v3 development")
James E. Blair8f78d882015-02-05 08:51:37 -08003920 def test_crd_multiline(self):
3921 "Test multiple depends-on lines in commit"
3922 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3923 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3924 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
3925 A.addApproval('CRVW', 2)
3926 B.addApproval('CRVW', 2)
3927 C.addApproval('CRVW', 2)
3928
3929 # A Depends-On: B+C
3930 A.data['commitMessage'] = '%s\n\nDepends-On: %s\nDepends-On: %s\n' % (
3931 A.subject, B.data['id'], C.data['id'])
3932
3933 self.worker.hold_jobs_in_build = True
3934 B.addApproval('APRV', 1)
3935 C.addApproval('APRV', 1)
3936 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3937 self.waitUntilSettled()
3938
3939 self.worker.release('.*-merge')
3940 self.waitUntilSettled()
3941 self.worker.release('.*-merge')
3942 self.waitUntilSettled()
3943 self.worker.release('.*-merge')
3944 self.waitUntilSettled()
3945 self.worker.hold_jobs_in_build = False
3946 self.worker.release()
3947 self.waitUntilSettled()
3948
3949 self.assertEqual(A.data['status'], 'MERGED')
3950 self.assertEqual(B.data['status'], 'MERGED')
3951 self.assertEqual(C.data['status'], 'MERGED')
3952 self.assertEqual(A.reported, 2)
3953 self.assertEqual(B.reported, 2)
3954 self.assertEqual(C.reported, 2)
3955
3956 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3957 '2,1 3,1 1,1')
James E. Blair5ee24252014-12-30 10:12:29 -08003958
James E. Blairec056492016-07-22 09:45:56 -07003959 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08003960 def test_crd_unshared_gate(self):
3961 "Test cross-repo dependencies in unshared gate queues"
3962 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3963 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3964 A.addApproval('CRVW', 2)
3965 B.addApproval('CRVW', 2)
3966
3967 # A Depends-On: B
3968 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3969 A.subject, B.data['id'])
3970
3971 # A and B do not share a queue, make sure that A is unable to
3972 # enqueue B (and therefore, A is unable to be enqueued).
3973 B.addApproval('APRV', 1)
3974 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3975 self.waitUntilSettled()
3976
3977 self.assertEqual(A.data['status'], 'NEW')
3978 self.assertEqual(B.data['status'], 'NEW')
3979 self.assertEqual(A.reported, 0)
3980 self.assertEqual(B.reported, 0)
3981 self.assertEqual(len(self.history), 0)
3982
3983 # Enqueue and merge B alone.
3984 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3985 self.waitUntilSettled()
3986
3987 self.assertEqual(B.data['status'], 'MERGED')
3988 self.assertEqual(B.reported, 2)
3989
3990 # Now that B is merged, A should be able to be enqueued and
3991 # merged.
3992 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3993 self.waitUntilSettled()
3994
3995 self.assertEqual(A.data['status'], 'MERGED')
3996 self.assertEqual(A.reported, 2)
3997
James E. Blairec056492016-07-22 09:45:56 -07003998 @skip("Disabled for early v3 development")
James E. Blair96698e22015-04-02 07:48:21 -07003999 def test_crd_gate_reverse(self):
4000 "Test reverse cross-repo dependencies"
4001 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4002 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4003 A.addApproval('CRVW', 2)
4004 B.addApproval('CRVW', 2)
4005
4006 # A Depends-On: B
4007
4008 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4009 A.subject, B.data['id'])
4010
4011 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4012 self.waitUntilSettled()
4013
4014 self.assertEqual(A.data['status'], 'NEW')
4015 self.assertEqual(B.data['status'], 'NEW')
4016
4017 self.worker.hold_jobs_in_build = True
4018 A.addApproval('APRV', 1)
4019 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
4020 self.waitUntilSettled()
4021
4022 self.worker.release('.*-merge')
4023 self.waitUntilSettled()
4024 self.worker.release('.*-merge')
4025 self.waitUntilSettled()
4026 self.worker.hold_jobs_in_build = False
4027 self.worker.release()
4028 self.waitUntilSettled()
4029
4030 self.assertEqual(A.data['status'], 'MERGED')
4031 self.assertEqual(B.data['status'], 'MERGED')
4032 self.assertEqual(A.reported, 2)
4033 self.assertEqual(B.reported, 2)
4034
4035 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
4036 '2,1 1,1')
4037
James E. Blairec056492016-07-22 09:45:56 -07004038 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08004039 def test_crd_cycle(self):
4040 "Test cross-repo dependency cycles"
4041 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4042 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4043 A.addApproval('CRVW', 2)
4044 B.addApproval('CRVW', 2)
4045
4046 # A -> B -> A (via commit-depends)
4047
4048 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4049 A.subject, B.data['id'])
4050 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4051 B.subject, A.data['id'])
4052
4053 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4054 self.waitUntilSettled()
4055
4056 self.assertEqual(A.reported, 0)
4057 self.assertEqual(B.reported, 0)
4058 self.assertEqual(A.data['status'], 'NEW')
4059 self.assertEqual(B.data['status'], 'NEW')
James E. Blairbfb8e042014-12-30 17:01:44 -08004060
James E. Blairec056492016-07-22 09:45:56 -07004061 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004062 def test_crd_gate_unknown(self):
4063 "Test unknown projects in dependent pipeline"
4064 self.init_repo("org/unknown")
4065 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4066 B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'B')
4067 A.addApproval('CRVW', 2)
4068 B.addApproval('CRVW', 2)
4069
4070 # A Depends-On: B
4071 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4072 A.subject, B.data['id'])
4073
4074 B.addApproval('APRV', 1)
4075 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4076 self.waitUntilSettled()
4077
4078 # Unknown projects cannot share a queue with any other
4079 # since they don't have common jobs with any other (they have no jobs).
4080 # Changes which depend on unknown project changes
4081 # should not be processed in dependent pipeline
4082 self.assertEqual(A.data['status'], 'NEW')
4083 self.assertEqual(B.data['status'], 'NEW')
4084 self.assertEqual(A.reported, 0)
4085 self.assertEqual(B.reported, 0)
4086 self.assertEqual(len(self.history), 0)
4087
4088 # Simulate change B being gated outside this layout
4089 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
4090 B.setMerged()
4091 self.waitUntilSettled()
4092 self.assertEqual(len(self.history), 0)
4093
4094 # Now that B is merged, A should be able to be enqueued and
4095 # merged.
4096 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4097 self.waitUntilSettled()
4098
4099 self.assertEqual(A.data['status'], 'MERGED')
4100 self.assertEqual(A.reported, 2)
4101 self.assertEqual(B.data['status'], 'MERGED')
4102 self.assertEqual(B.reported, 0)
4103
James E. Blairec056492016-07-22 09:45:56 -07004104 @skip("Disabled for early v3 development")
James E. Blairbfb8e042014-12-30 17:01:44 -08004105 def test_crd_check(self):
4106 "Test cross-repo dependencies in independent pipelines"
4107
4108 self.gearman_server.hold_jobs_in_queue = True
4109 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4110 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4111
4112 # A Depends-On: B
4113 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4114 A.subject, B.data['id'])
4115
4116 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4117 self.waitUntilSettled()
4118
4119 queue = self.gearman_server.getQueue()
4120 ref = self.getParameter(queue[-1], 'ZUUL_REF')
4121 self.gearman_server.hold_jobs_in_queue = False
4122 self.gearman_server.release()
4123 self.waitUntilSettled()
4124
4125 path = os.path.join(self.git_root, "org/project1")
4126 repo = git.Repo(path)
4127 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4128 repo_messages.reverse()
4129 correct_messages = ['initial commit', 'A-1']
4130 self.assertEqual(repo_messages, correct_messages)
4131
4132 path = os.path.join(self.git_root, "org/project2")
4133 repo = git.Repo(path)
4134 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4135 repo_messages.reverse()
4136 correct_messages = ['initial commit', 'B-1']
4137 self.assertEqual(repo_messages, correct_messages)
4138
4139 self.assertEqual(A.data['status'], 'NEW')
4140 self.assertEqual(B.data['status'], 'NEW')
4141 self.assertEqual(A.reported, 1)
4142 self.assertEqual(B.reported, 0)
4143
4144 self.assertEqual(self.history[0].changes, '2,1 1,1')
4145 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
James E. Blair8f78d882015-02-05 08:51:37 -08004146
James E. Blairec056492016-07-22 09:45:56 -07004147 @skip("Disabled for early v3 development")
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004148 def test_crd_check_git_depends(self):
4149 "Test single-repo dependencies in independent pipelines"
James E. Blairb8c16472015-05-05 14:55:26 -07004150 self.gearman_server.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004151 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4152 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4153
4154 # Add two git-dependent changes and make sure they both report
4155 # success.
4156 B.setDependsOn(A, 1)
4157 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4158 self.waitUntilSettled()
4159 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4160 self.waitUntilSettled()
4161
James E. Blairb8c16472015-05-05 14:55:26 -07004162 self.orderedRelease()
4163 self.gearman_server.hold_jobs_in_build = False
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004164 self.waitUntilSettled()
4165
4166 self.assertEqual(A.data['status'], 'NEW')
4167 self.assertEqual(B.data['status'], 'NEW')
4168 self.assertEqual(A.reported, 1)
4169 self.assertEqual(B.reported, 1)
4170
4171 self.assertEqual(self.history[0].changes, '1,1')
4172 self.assertEqual(self.history[-1].changes, '1,1 2,1')
4173 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
4174
4175 self.assertIn('Build succeeded', A.messages[0])
4176 self.assertIn('Build succeeded', B.messages[0])
4177
James E. Blairec056492016-07-22 09:45:56 -07004178 @skip("Disabled for early v3 development")
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004179 def test_crd_check_duplicate(self):
4180 "Test duplicate check in independent pipelines"
James E. Blair1e263032015-05-07 14:35:34 -07004181 self.worker.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004182 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4183 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4184 check_pipeline = self.sched.layout.pipelines['check']
4185
4186 # Add two git-dependent changes...
4187 B.setDependsOn(A, 1)
4188 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4189 self.waitUntilSettled()
4190 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4191
4192 # ...make sure the live one is not duplicated...
4193 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4194 self.waitUntilSettled()
4195 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4196
4197 # ...but the non-live one is able to be.
4198 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4199 self.waitUntilSettled()
4200 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4201
Clark Boylandd849822015-03-02 12:38:14 -08004202 # Release jobs in order to avoid races with change A jobs
4203 # finishing before change B jobs.
James E. Blaird7650852015-05-07 15:47:37 -07004204 self.orderedRelease()
James E. Blair1e263032015-05-07 14:35:34 -07004205 self.worker.hold_jobs_in_build = False
4206 self.worker.release()
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004207 self.waitUntilSettled()
4208
4209 self.assertEqual(A.data['status'], 'NEW')
4210 self.assertEqual(B.data['status'], 'NEW')
4211 self.assertEqual(A.reported, 1)
4212 self.assertEqual(B.reported, 1)
4213
4214 self.assertEqual(self.history[0].changes, '1,1 2,1')
4215 self.assertEqual(self.history[1].changes, '1,1')
4216 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
4217
4218 self.assertIn('Build succeeded', A.messages[0])
4219 self.assertIn('Build succeeded', B.messages[0])
4220
James E. Blairec056492016-07-22 09:45:56 -07004221 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004222 def _test_crd_check_reconfiguration(self, project1, project2):
James E. Blair8f78d882015-02-05 08:51:37 -08004223 "Test cross-repo dependencies re-enqueued in independent pipelines"
4224
4225 self.gearman_server.hold_jobs_in_queue = True
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004226 A = self.fake_gerrit.addFakeChange(project1, 'master', 'A')
4227 B = self.fake_gerrit.addFakeChange(project2, 'master', 'B')
James E. Blair8f78d882015-02-05 08:51:37 -08004228
4229 # A Depends-On: B
4230 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4231 A.subject, B.data['id'])
4232
4233 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4234 self.waitUntilSettled()
4235
4236 self.sched.reconfigure(self.config)
4237
4238 # Make sure the items still share a change queue, and the
4239 # first one is not live.
4240 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 1)
4241 queue = self.sched.layout.pipelines['check'].queues[0]
4242 first_item = queue.queue[0]
4243 for item in queue.queue:
4244 self.assertEqual(item.queue, first_item.queue)
4245 self.assertFalse(first_item.live)
4246 self.assertTrue(queue.queue[1].live)
4247
4248 self.gearman_server.hold_jobs_in_queue = False
4249 self.gearman_server.release()
4250 self.waitUntilSettled()
4251
4252 self.assertEqual(A.data['status'], 'NEW')
4253 self.assertEqual(B.data['status'], 'NEW')
4254 self.assertEqual(A.reported, 1)
4255 self.assertEqual(B.reported, 0)
4256
4257 self.assertEqual(self.history[0].changes, '2,1 1,1')
4258 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
James E. Blair17dd6772015-02-09 14:45:18 -08004259
James E. Blairec056492016-07-22 09:45:56 -07004260 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004261 def test_crd_check_reconfiguration(self):
4262 self._test_crd_check_reconfiguration('org/project1', 'org/project2')
4263
James E. Blairec056492016-07-22 09:45:56 -07004264 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004265 def test_crd_undefined_project(self):
4266 """Test that undefined projects in dependencies are handled for
4267 independent pipelines"""
4268 # It's a hack for fake gerrit,
4269 # as it implies repo creation upon the creation of any change
4270 self.init_repo("org/unknown")
4271 self._test_crd_check_reconfiguration('org/project1', 'org/unknown')
4272
James E. Blairec056492016-07-22 09:45:56 -07004273 @skip("Disabled for early v3 development")
James E. Blair17dd6772015-02-09 14:45:18 -08004274 def test_crd_check_ignore_dependencies(self):
4275 "Test cross-repo dependencies can be ignored"
James E. Blairf84026c2015-12-08 16:11:46 -08004276 self.updateConfigLayout(
4277 'tests/fixtures/layout-ignore-dependencies.yaml')
James E. Blair17dd6772015-02-09 14:45:18 -08004278 self.sched.reconfigure(self.config)
4279 self.registerJobs()
4280
4281 self.gearman_server.hold_jobs_in_queue = True
4282 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4283 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4284 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
4285
4286 # A Depends-On: B
4287 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4288 A.subject, B.data['id'])
4289 # C git-depends on B
4290 C.setDependsOn(B, 1)
4291 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4292 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4293 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4294 self.waitUntilSettled()
4295
4296 # Make sure none of the items share a change queue, and all
4297 # are live.
4298 check_pipeline = self.sched.layout.pipelines['check']
4299 self.assertEqual(len(check_pipeline.queues), 3)
4300 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4301 for item in check_pipeline.getAllItems():
4302 self.assertTrue(item.live)
4303
4304 self.gearman_server.hold_jobs_in_queue = False
4305 self.gearman_server.release()
4306 self.waitUntilSettled()
4307
4308 self.assertEqual(A.data['status'], 'NEW')
4309 self.assertEqual(B.data['status'], 'NEW')
4310 self.assertEqual(C.data['status'], 'NEW')
4311 self.assertEqual(A.reported, 1)
4312 self.assertEqual(B.reported, 1)
4313 self.assertEqual(C.reported, 1)
4314
4315 # Each job should have tested exactly one change
4316 for job in self.history:
4317 self.assertEqual(len(job.changes.split()), 1)
James E. Blair96698e22015-04-02 07:48:21 -07004318
James E. Blairec056492016-07-22 09:45:56 -07004319 @skip("Disabled for early v3 development")
James E. Blair96698e22015-04-02 07:48:21 -07004320 def test_crd_check_transitive(self):
4321 "Test transitive cross-repo dependencies"
4322 # Specifically, if A -> B -> C, and C gets a new patchset and
4323 # A gets a new patchset, ensure the test of A,2 includes B,1
4324 # and C,2 (not C,1 which would indicate stale data in the
4325 # cache for B).
4326 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4327 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4328 C = self.fake_gerrit.addFakeChange('org/project3', 'master', 'C')
4329
4330 # A Depends-On: B
4331 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4332 A.subject, B.data['id'])
4333
4334 # B Depends-On: C
4335 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4336 B.subject, C.data['id'])
4337
4338 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4339 self.waitUntilSettled()
4340 self.assertEqual(self.history[-1].changes, '3,1 2,1 1,1')
4341
4342 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4343 self.waitUntilSettled()
4344 self.assertEqual(self.history[-1].changes, '3,1 2,1')
4345
4346 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4347 self.waitUntilSettled()
4348 self.assertEqual(self.history[-1].changes, '3,1')
4349
4350 C.addPatchset()
4351 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(2))
4352 self.waitUntilSettled()
4353 self.assertEqual(self.history[-1].changes, '3,2')
4354
4355 A.addPatchset()
4356 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
4357 self.waitUntilSettled()
4358 self.assertEqual(self.history[-1].changes, '3,2 2,1 1,2')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004359
James E. Blairec056492016-07-22 09:45:56 -07004360 @skip("Disabled for early v3 development")
James E. Blair92464a22016-04-05 10:21:26 -07004361 def test_crd_cycle_join(self):
4362 "Test an updated change creates a cycle"
4363 A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A')
4364
4365 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4366 self.waitUntilSettled()
4367
4368 # Create B->A
4369 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4370 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4371 B.subject, A.data['id'])
4372 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4373 self.waitUntilSettled()
4374
4375 # Update A to add A->B (a cycle).
4376 A.addPatchset()
4377 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4378 A.subject, B.data['id'])
4379 # Normally we would submit the patchset-created event for
4380 # processing here, however, we have no way of noting whether
4381 # the dependency cycle detection correctly raised an
4382 # exception, so instead, we reach into the source driver and
4383 # call the method that would ultimately be called by the event
4384 # processing.
4385
4386 source = self.sched.layout.pipelines['gate'].source
4387 with testtools.ExpectedException(
4388 Exception, "Dependency cycle detected"):
4389 source._getChange(u'1', u'2', True)
4390 self.log.debug("Got expected dependency cycle exception")
4391
4392 # Now if we update B to remove the depends-on, everything
4393 # should be okay. B; A->B
4394
4395 B.addPatchset()
4396 B.data['commitMessage'] = '%s\n' % (B.subject,)
4397 source._getChange(u'1', u'2', True)
4398 source._getChange(u'2', u'2', True)
4399
James E. Blairec056492016-07-22 09:45:56 -07004400 @skip("Disabled for early v3 development")
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004401 def test_disable_at(self):
4402 "Test a pipeline will only report to the disabled trigger when failing"
4403
James E. Blairf84026c2015-12-08 16:11:46 -08004404 self.updateConfigLayout(
4405 'tests/fixtures/layout-disable-at.yaml')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004406 self.sched.reconfigure(self.config)
4407
4408 self.assertEqual(3, self.sched.layout.pipelines['check'].disable_at)
4409 self.assertEqual(
4410 0, self.sched.layout.pipelines['check']._consecutive_failures)
4411 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4412
4413 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4414 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
4415 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
4416 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
4417 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
4418 F = self.fake_gerrit.addFakeChange('org/project', 'master', 'F')
4419 G = self.fake_gerrit.addFakeChange('org/project', 'master', 'G')
4420 H = self.fake_gerrit.addFakeChange('org/project', 'master', 'H')
4421 I = self.fake_gerrit.addFakeChange('org/project', 'master', 'I')
4422 J = self.fake_gerrit.addFakeChange('org/project', 'master', 'J')
4423 K = self.fake_gerrit.addFakeChange('org/project', 'master', 'K')
4424
4425 self.worker.addFailTest('project-test1', A)
4426 self.worker.addFailTest('project-test1', B)
4427 # Let C pass, resetting the counter
4428 self.worker.addFailTest('project-test1', D)
4429 self.worker.addFailTest('project-test1', E)
4430 self.worker.addFailTest('project-test1', F)
4431 self.worker.addFailTest('project-test1', G)
4432 self.worker.addFailTest('project-test1', H)
4433 # I also passes but should only report to the disabled reporters
4434 self.worker.addFailTest('project-test1', J)
4435 self.worker.addFailTest('project-test1', K)
4436
4437 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4438 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4439 self.waitUntilSettled()
4440
4441 self.assertEqual(
4442 2, self.sched.layout.pipelines['check']._consecutive_failures)
4443 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4444
4445 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4446 self.waitUntilSettled()
4447
4448 self.assertEqual(
4449 0, self.sched.layout.pipelines['check']._consecutive_failures)
4450 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4451
4452 self.fake_gerrit.addEvent(D.getPatchsetCreatedEvent(1))
4453 self.fake_gerrit.addEvent(E.getPatchsetCreatedEvent(1))
4454 self.fake_gerrit.addEvent(F.getPatchsetCreatedEvent(1))
4455 self.waitUntilSettled()
4456
4457 # We should be disabled now
4458 self.assertEqual(
4459 3, self.sched.layout.pipelines['check']._consecutive_failures)
4460 self.assertTrue(self.sched.layout.pipelines['check']._disabled)
4461
4462 # We need to wait between each of these patches to make sure the
4463 # smtp messages come back in an expected order
4464 self.fake_gerrit.addEvent(G.getPatchsetCreatedEvent(1))
4465 self.waitUntilSettled()
4466 self.fake_gerrit.addEvent(H.getPatchsetCreatedEvent(1))
4467 self.waitUntilSettled()
4468 self.fake_gerrit.addEvent(I.getPatchsetCreatedEvent(1))
4469 self.waitUntilSettled()
4470
4471 # The first 6 (ABCDEF) jobs should have reported back to gerrt thus
4472 # leaving a message on each change
4473 self.assertEqual(1, len(A.messages))
4474 self.assertIn('Build failed.', A.messages[0])
4475 self.assertEqual(1, len(B.messages))
4476 self.assertIn('Build failed.', B.messages[0])
4477 self.assertEqual(1, len(C.messages))
4478 self.assertIn('Build succeeded.', C.messages[0])
4479 self.assertEqual(1, len(D.messages))
4480 self.assertIn('Build failed.', D.messages[0])
4481 self.assertEqual(1, len(E.messages))
4482 self.assertIn('Build failed.', E.messages[0])
4483 self.assertEqual(1, len(F.messages))
4484 self.assertIn('Build failed.', F.messages[0])
4485
4486 # The last 3 (GHI) would have only reported via smtp.
4487 self.assertEqual(3, len(self.smtp_messages))
4488 self.assertEqual(0, len(G.messages))
4489 self.assertIn('Build failed.', self.smtp_messages[0]['body'])
4490 self.assertIn('/7/1/check', self.smtp_messages[0]['body'])
4491 self.assertEqual(0, len(H.messages))
4492 self.assertIn('Build failed.', self.smtp_messages[1]['body'])
4493 self.assertIn('/8/1/check', self.smtp_messages[1]['body'])
4494 self.assertEqual(0, len(I.messages))
4495 self.assertIn('Build succeeded.', self.smtp_messages[2]['body'])
4496 self.assertIn('/9/1/check', self.smtp_messages[2]['body'])
4497
4498 # Now reload the configuration (simulate a HUP) to check the pipeline
4499 # comes out of disabled
4500 self.sched.reconfigure(self.config)
4501
4502 self.assertEqual(3, self.sched.layout.pipelines['check'].disable_at)
4503 self.assertEqual(
4504 0, self.sched.layout.pipelines['check']._consecutive_failures)
4505 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4506
4507 self.fake_gerrit.addEvent(J.getPatchsetCreatedEvent(1))
4508 self.fake_gerrit.addEvent(K.getPatchsetCreatedEvent(1))
4509 self.waitUntilSettled()
4510
4511 self.assertEqual(
4512 2, self.sched.layout.pipelines['check']._consecutive_failures)
4513 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4514
4515 # J and K went back to gerrit
4516 self.assertEqual(1, len(J.messages))
4517 self.assertIn('Build failed.', J.messages[0])
4518 self.assertEqual(1, len(K.messages))
4519 self.assertIn('Build failed.', K.messages[0])
4520 # No more messages reported via smtp
4521 self.assertEqual(3, len(self.smtp_messages))
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004522
James E. Blairec056492016-07-22 09:45:56 -07004523 @skip("Disabled for early v3 development")
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004524 def test_success_pattern(self):
4525 "Ensure bad build params are ignored"
4526
4527 # Use SMTP reporter to grab the result message easier
4528 self.init_repo("org/docs")
4529 self.config.set('zuul', 'layout_config',
4530 'tests/fixtures/layout-success-pattern.yaml')
4531 self.sched.reconfigure(self.config)
4532 self.worker.hold_jobs_in_build = True
4533 self.registerJobs()
4534
4535 A = self.fake_gerrit.addFakeChange('org/docs', 'master', 'A')
4536 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4537 self.waitUntilSettled()
4538
4539 # Grab build id
4540 self.assertEqual(len(self.builds), 1)
4541 uuid = self.builds[0].unique[:7]
4542
4543 self.worker.hold_jobs_in_build = False
4544 self.worker.release()
4545 self.waitUntilSettled()
4546
4547 self.assertEqual(len(self.smtp_messages), 1)
4548 body = self.smtp_messages[0]['body'].splitlines()
4549 self.assertEqual('Build succeeded.', body[0])
4550
4551 self.assertIn(
4552 '- docs-draft-test http://docs-draft.example.org/1/1/1/check/'
4553 'docs-draft-test/%s/publish-docs/' % uuid,
4554 body[2])
4555 self.assertIn(
4556 '- docs-draft-test2 https://server/job/docs-draft-test2/1/',
4557 body[3])