blob: 716ec9ebd3790b3de7ce6bb8d8f662cf96c239bd [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. Blair3cb10702013-08-24 08:56:03 -070084 def test_initial_pipeline_gauges(self):
85 "Test that each pipeline reported its length on start"
James E. Blair7da51b72016-07-25 15:29:43 -070086 self.assertReportedStat('zuul.pipeline.gate.current_changes',
87 value='0|g')
88 self.assertReportedStat('zuul.pipeline.check.current_changes',
89 value='0|g')
James E. Blair3cb10702013-08-24 08:56:03 -070090
James E. Blairec056492016-07-22 09:45:56 -070091 @skip("Disabled for early v3 development")
James E. Blair42f74822013-05-14 15:18:03 -070092 def test_duplicate_pipelines(self):
93 "Test that a change matching multiple pipelines works"
James E. Blair1b4d9722013-05-21 10:32:04 -070094
James E. Blair42f74822013-05-14 15:18:03 -070095 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
96 self.fake_gerrit.addEvent(A.getChangeRestoredEvent())
97 self.waitUntilSettled()
James E. Blair42f74822013-05-14 15:18:03 -070098
Monty Taylor98f0f3e2013-07-06 16:02:31 -040099 self.assertEqual(len(self.history), 2)
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400100 self.history[0].name == 'project-test1'
101 self.history[1].name == 'project-test1'
James E. Blair42f74822013-05-14 15:18:03 -0700102
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400103 self.assertEqual(len(A.messages), 2)
James E. Blair42f74822013-05-14 15:18:03 -0700104 if 'dup1/project-test1' in A.messages[0]:
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400105 self.assertIn('dup1/project-test1', A.messages[0])
106 self.assertNotIn('dup2/project-test1', A.messages[0])
107 self.assertNotIn('dup1/project-test1', A.messages[1])
108 self.assertIn('dup2/project-test1', A.messages[1])
James E. Blair42f74822013-05-14 15:18:03 -0700109 else:
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400110 self.assertIn('dup1/project-test1', A.messages[1])
111 self.assertNotIn('dup2/project-test1', A.messages[1])
112 self.assertNotIn('dup1/project-test1', A.messages[0])
113 self.assertIn('dup2/project-test1', A.messages[0])
James E. Blair42f74822013-05-14 15:18:03 -0700114
James E. Blairec056492016-07-22 09:45:56 -0700115 @skip("Disabled for early v3 development")
James E. Blairb0fcae42012-07-17 11:12:10 -0700116 def test_parallel_changes(self):
117 "Test that changes are tested in parallel and merged in series"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700118
119 self.worker.hold_jobs_in_build = True
James E. Blairb0fcae42012-07-17 11:12:10 -0700120 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
121 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
122 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700123 A.addApproval('CRVW', 2)
124 B.addApproval('CRVW', 2)
125 C.addApproval('CRVW', 2)
James E. Blairb0fcae42012-07-17 11:12:10 -0700126
127 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
128 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
129 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
130
131 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400132 self.assertEqual(len(self.builds), 1)
133 self.assertEqual(self.builds[0].name, 'project-merge')
134 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700135
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700136 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700137 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400138 self.assertEqual(len(self.builds), 3)
139 self.assertEqual(self.builds[0].name, 'project-test1')
140 self.assertTrue(self.job_has_changes(self.builds[0], A))
141 self.assertEqual(self.builds[1].name, 'project-test2')
142 self.assertTrue(self.job_has_changes(self.builds[1], A))
143 self.assertEqual(self.builds[2].name, 'project-merge')
144 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700145
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700146 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700147 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400148 self.assertEqual(len(self.builds), 5)
149 self.assertEqual(self.builds[0].name, 'project-test1')
150 self.assertTrue(self.job_has_changes(self.builds[0], A))
151 self.assertEqual(self.builds[1].name, 'project-test2')
152 self.assertTrue(self.job_has_changes(self.builds[1], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700153
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400154 self.assertEqual(self.builds[2].name, 'project-test1')
155 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
156 self.assertEqual(self.builds[3].name, 'project-test2')
157 self.assertTrue(self.job_has_changes(self.builds[3], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700158
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400159 self.assertEqual(self.builds[4].name, 'project-merge')
160 self.assertTrue(self.job_has_changes(self.builds[4], A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700161
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700162 self.worker.release('.*-merge')
James E. Blairb0fcae42012-07-17 11:12:10 -0700163 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400164 self.assertEqual(len(self.builds), 6)
165 self.assertEqual(self.builds[0].name, 'project-test1')
166 self.assertTrue(self.job_has_changes(self.builds[0], A))
167 self.assertEqual(self.builds[1].name, 'project-test2')
168 self.assertTrue(self.job_has_changes(self.builds[1], A))
James E. Blairb0fcae42012-07-17 11:12:10 -0700169
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400170 self.assertEqual(self.builds[2].name, 'project-test1')
171 self.assertTrue(self.job_has_changes(self.builds[2], A, B))
172 self.assertEqual(self.builds[3].name, 'project-test2')
173 self.assertTrue(self.job_has_changes(self.builds[3], A, B))
James E. Blairb0fcae42012-07-17 11:12:10 -0700174
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400175 self.assertEqual(self.builds[4].name, 'project-test1')
176 self.assertTrue(self.job_has_changes(self.builds[4], A, B, C))
177 self.assertEqual(self.builds[5].name, 'project-test2')
178 self.assertTrue(self.job_has_changes(self.builds[5], A, B, C))
James E. Blairb0fcae42012-07-17 11:12:10 -0700179
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700180 self.worker.hold_jobs_in_build = False
181 self.worker.release()
James E. Blairb0fcae42012-07-17 11:12:10 -0700182 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400183 self.assertEqual(len(self.builds), 0)
James E. Blairb0fcae42012-07-17 11:12:10 -0700184
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400185 self.assertEqual(len(self.history), 9)
186 self.assertEqual(A.data['status'], 'MERGED')
187 self.assertEqual(B.data['status'], 'MERGED')
188 self.assertEqual(C.data['status'], 'MERGED')
189 self.assertEqual(A.reported, 2)
190 self.assertEqual(B.reported, 2)
191 self.assertEqual(C.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700192
James E. Blairec056492016-07-22 09:45:56 -0700193 @skip("Disabled for early v3 development")
James E. Blairb02a3bb2012-07-30 17:49:55 -0700194 def test_failed_changes(self):
195 "Test that a change behind a failed change is retested"
James E. Blaire2819012013-06-28 17:17:26 -0400196 self.worker.hold_jobs_in_build = True
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700197
James E. Blairb02a3bb2012-07-30 17:49:55 -0700198 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
199 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
James E. Blair8c803f82012-07-31 16:25:42 -0700200 A.addApproval('CRVW', 2)
201 B.addApproval('CRVW', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700202
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700203 self.worker.addFailTest('project-test1', A)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700204
James E. Blaire2819012013-06-28 17:17:26 -0400205 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
206 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700207 self.waitUntilSettled()
James E. Blaire2819012013-06-28 17:17:26 -0400208
209 self.worker.release('.*-merge')
210 self.waitUntilSettled()
211
212 self.worker.hold_jobs_in_build = False
213 self.worker.release()
214
215 self.waitUntilSettled()
216 # It's certain that the merge job for change 2 will run, but
217 # the test1 and test2 jobs may or may not run.
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400218 self.assertTrue(len(self.history) > 6)
219 self.assertEqual(A.data['status'], 'NEW')
220 self.assertEqual(B.data['status'], 'MERGED')
221 self.assertEqual(A.reported, 2)
222 self.assertEqual(B.reported, 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700223
James E. Blairec056492016-07-22 09:45:56 -0700224 @skip("Disabled for early v3 development")
James E. Blairb02a3bb2012-07-30 17:49:55 -0700225 def test_independent_queues(self):
226 "Test that changes end up in the right queues"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700227
228 self.worker.hold_jobs_in_build = True
Zhongyue Luo5d556072012-09-21 02:00:47 +0900229 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700230 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
231 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700232 A.addApproval('CRVW', 2)
233 B.addApproval('CRVW', 2)
234 C.addApproval('CRVW', 2)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700235
236 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
237 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
238 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
239
James E. Blairb02a3bb2012-07-30 17:49:55 -0700240 self.waitUntilSettled()
241
242 # There should be one merge job at the head of each queue running
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400243 self.assertEqual(len(self.builds), 2)
244 self.assertEqual(self.builds[0].name, 'project-merge')
245 self.assertTrue(self.job_has_changes(self.builds[0], A))
246 self.assertEqual(self.builds[1].name, 'project1-merge')
247 self.assertTrue(self.job_has_changes(self.builds[1], B))
James E. Blairb02a3bb2012-07-30 17:49:55 -0700248
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700249 # Release the current merge builds
250 self.worker.release('.*-merge')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700251 self.waitUntilSettled()
252 # Release the merge job for project2 which is behind project1
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700253 self.worker.release('.*-merge')
James E. Blairb02a3bb2012-07-30 17:49:55 -0700254 self.waitUntilSettled()
255
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700256 # All the test builds should be running:
James E. Blairb02a3bb2012-07-30 17:49:55 -0700257 # project1 (3) + project2 (3) + project (2) = 8
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400258 self.assertEqual(len(self.builds), 8)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700259
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700260 self.worker.release()
James E. Blairb02a3bb2012-07-30 17:49:55 -0700261 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400262 self.assertEqual(len(self.builds), 0)
James E. Blairb02a3bb2012-07-30 17:49:55 -0700263
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400264 self.assertEqual(len(self.history), 11)
265 self.assertEqual(A.data['status'], 'MERGED')
266 self.assertEqual(B.data['status'], 'MERGED')
267 self.assertEqual(C.data['status'], 'MERGED')
268 self.assertEqual(A.reported, 2)
269 self.assertEqual(B.reported, 2)
270 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700271
James E. Blairec056492016-07-22 09:45:56 -0700272 @skip("Disabled for early v3 development")
James E. Blaird466dc42012-07-31 10:42:56 -0700273 def test_failed_change_at_head(self):
274 "Test that if a change at the head fails, jobs behind it are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700275
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700276 self.worker.hold_jobs_in_build = True
James E. Blaird466dc42012-07-31 10:42:56 -0700277 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
278 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
279 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700280 A.addApproval('CRVW', 2)
281 B.addApproval('CRVW', 2)
282 C.addApproval('CRVW', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700283
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700284 self.worker.addFailTest('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700285
286 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
287 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
288 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
289
290 self.waitUntilSettled()
James E. Blaird466dc42012-07-31 10:42:56 -0700291
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400292 self.assertEqual(len(self.builds), 1)
293 self.assertEqual(self.builds[0].name, 'project-merge')
294 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blaird466dc42012-07-31 10:42:56 -0700295
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700296 self.worker.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700297 self.waitUntilSettled()
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()
302
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400303 self.assertEqual(len(self.builds), 6)
304 self.assertEqual(self.builds[0].name, 'project-test1')
305 self.assertEqual(self.builds[1].name, 'project-test2')
306 self.assertEqual(self.builds[2].name, 'project-test1')
307 self.assertEqual(self.builds[3].name, 'project-test2')
308 self.assertEqual(self.builds[4].name, 'project-test1')
309 self.assertEqual(self.builds[5].name, 'project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700310
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400311 self.release(self.builds[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700312 self.waitUntilSettled()
313
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400314 # project-test2, project-merge for B
315 self.assertEqual(len(self.builds), 2)
316 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 4)
James E. Blaird466dc42012-07-31 10:42:56 -0700317
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700318 self.worker.hold_jobs_in_build = False
319 self.worker.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700320 self.waitUntilSettled()
321
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400322 self.assertEqual(len(self.builds), 0)
323 self.assertEqual(len(self.history), 15)
324 self.assertEqual(A.data['status'], 'NEW')
325 self.assertEqual(B.data['status'], 'MERGED')
326 self.assertEqual(C.data['status'], 'MERGED')
327 self.assertEqual(A.reported, 2)
328 self.assertEqual(B.reported, 2)
329 self.assertEqual(C.reported, 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700330
James E. Blairec056492016-07-22 09:45:56 -0700331 @skip("Disabled for early v3 development")
James E. Blair0aac4872013-08-23 14:02:38 -0700332 def test_failed_change_in_middle(self):
333 "Test a failed change in the middle of the queue"
334
335 self.worker.hold_jobs_in_build = True
336 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
337 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
338 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
339 A.addApproval('CRVW', 2)
340 B.addApproval('CRVW', 2)
341 C.addApproval('CRVW', 2)
342
343 self.worker.addFailTest('project-test1', B)
344
345 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
346 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
347 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
348
349 self.waitUntilSettled()
350
351 self.worker.release('.*-merge')
352 self.waitUntilSettled()
353 self.worker.release('.*-merge')
354 self.waitUntilSettled()
355 self.worker.release('.*-merge')
356 self.waitUntilSettled()
357
358 self.assertEqual(len(self.builds), 6)
359 self.assertEqual(self.builds[0].name, 'project-test1')
360 self.assertEqual(self.builds[1].name, 'project-test2')
361 self.assertEqual(self.builds[2].name, 'project-test1')
362 self.assertEqual(self.builds[3].name, 'project-test2')
363 self.assertEqual(self.builds[4].name, 'project-test1')
364 self.assertEqual(self.builds[5].name, 'project-test2')
365
366 self.release(self.builds[2])
367 self.waitUntilSettled()
368
James E. Blair972e3c72013-08-29 12:04:55 -0700369 # project-test1 and project-test2 for A
370 # project-test2 for B
371 # project-merge for C (without B)
372 self.assertEqual(len(self.builds), 4)
James E. Blair0aac4872013-08-23 14:02:38 -0700373 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 2)
374
James E. Blair972e3c72013-08-29 12:04:55 -0700375 self.worker.release('.*-merge')
376 self.waitUntilSettled()
377
378 # project-test1 and project-test2 for A
379 # project-test2 for B
380 # project-test1 and project-test2 for C
381 self.assertEqual(len(self.builds), 5)
382
James E. Blair0aac4872013-08-23 14:02:38 -0700383 items = self.sched.layout.pipelines['gate'].getAllItems()
384 builds = items[0].current_build_set.getBuilds()
385 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
386 self.assertEqual(self.countJobResults(builds, None), 2)
387 builds = items[1].current_build_set.getBuilds()
388 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
389 self.assertEqual(self.countJobResults(builds, 'FAILURE'), 1)
390 self.assertEqual(self.countJobResults(builds, None), 1)
391 builds = items[2].current_build_set.getBuilds()
392 self.assertEqual(self.countJobResults(builds, 'SUCCESS'), 1)
James E. Blair972e3c72013-08-29 12:04:55 -0700393 self.assertEqual(self.countJobResults(builds, None), 2)
James E. Blair0aac4872013-08-23 14:02:38 -0700394
395 self.worker.hold_jobs_in_build = False
396 self.worker.release()
397 self.waitUntilSettled()
398
399 self.assertEqual(len(self.builds), 0)
400 self.assertEqual(len(self.history), 12)
401 self.assertEqual(A.data['status'], 'MERGED')
402 self.assertEqual(B.data['status'], 'NEW')
403 self.assertEqual(C.data['status'], 'MERGED')
404 self.assertEqual(A.reported, 2)
405 self.assertEqual(B.reported, 2)
406 self.assertEqual(C.reported, 2)
407
James E. Blairec056492016-07-22 09:45:56 -0700408 @skip("Disabled for early v3 development")
James E. Blaird466dc42012-07-31 10:42:56 -0700409 def test_failed_change_at_head_with_queue(self):
410 "Test that if a change at the head fails, queued jobs are canceled"
James E. Blaird466dc42012-07-31 10:42:56 -0700411
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700412 self.gearman_server.hold_jobs_in_queue = True
James E. Blaird466dc42012-07-31 10:42:56 -0700413 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
414 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
415 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
James E. Blair8c803f82012-07-31 16:25:42 -0700416 A.addApproval('CRVW', 2)
417 B.addApproval('CRVW', 2)
418 C.addApproval('CRVW', 2)
James E. Blaird466dc42012-07-31 10:42:56 -0700419
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700420 self.worker.addFailTest('project-test1', A)
James E. Blaird466dc42012-07-31 10:42:56 -0700421
422 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
423 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
424 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
425
426 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -0700427 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400428 self.assertEqual(len(self.builds), 0)
429 self.assertEqual(len(queue), 1)
430 self.assertEqual(queue[0].name, 'build:project-merge')
431 self.assertTrue(self.job_has_changes(queue[0], A))
James E. Blaird466dc42012-07-31 10:42:56 -0700432
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700433 self.gearman_server.release('.*-merge')
James E. Blaird466dc42012-07-31 10:42:56 -0700434 self.waitUntilSettled()
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. Blair701c5b42013-06-06 09:34:59 -0700439 queue = self.gearman_server.getQueue()
James E. Blaird466dc42012-07-31 10:42:56 -0700440
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400441 self.assertEqual(len(self.builds), 0)
442 self.assertEqual(len(queue), 6)
443 self.assertEqual(queue[0].name, 'build:project-test1')
444 self.assertEqual(queue[1].name, 'build:project-test2')
445 self.assertEqual(queue[2].name, 'build:project-test1')
446 self.assertEqual(queue[3].name, 'build:project-test2')
447 self.assertEqual(queue[4].name, 'build:project-test1')
448 self.assertEqual(queue[5].name, 'build:project-test2')
James E. Blaird466dc42012-07-31 10:42:56 -0700449
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700450 self.release(queue[0])
James E. Blaird466dc42012-07-31 10:42:56 -0700451 self.waitUntilSettled()
452
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400453 self.assertEqual(len(self.builds), 0)
James E. Blair701c5b42013-06-06 09:34:59 -0700454 queue = self.gearman_server.getQueue()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400455 self.assertEqual(len(queue), 2) # project-test2, project-merge for B
456 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 0)
James E. Blaird466dc42012-07-31 10:42:56 -0700457
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700458 self.gearman_server.hold_jobs_in_queue = False
459 self.gearman_server.release()
James E. Blaird466dc42012-07-31 10:42:56 -0700460 self.waitUntilSettled()
461
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400462 self.assertEqual(len(self.builds), 0)
463 self.assertEqual(len(self.history), 11)
464 self.assertEqual(A.data['status'], 'NEW')
465 self.assertEqual(B.data['status'], 'MERGED')
466 self.assertEqual(C.data['status'], 'MERGED')
467 self.assertEqual(A.reported, 2)
468 self.assertEqual(B.reported, 2)
469 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700470
James E. Blairec056492016-07-22 09:45:56 -0700471 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700472 def _test_time_database(self, iteration):
473 self.worker.hold_jobs_in_build = True
474 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
475 A.addApproval('CRVW', 2)
476 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
477 self.waitUntilSettled()
478 time.sleep(2)
479
480 data = json.loads(self.sched.formatStatusJSON())
481 found_job = None
482 for pipeline in data['pipelines']:
483 if pipeline['name'] != 'gate':
484 continue
485 for queue in pipeline['change_queues']:
486 for head in queue['heads']:
487 for item in head:
488 for job in item['jobs']:
489 if job['name'] == 'project-merge':
490 found_job = job
491 break
492
493 self.assertIsNotNone(found_job)
494 if iteration == 1:
495 self.assertIsNotNone(found_job['estimated_time'])
496 self.assertIsNone(found_job['remaining_time'])
497 else:
498 self.assertIsNotNone(found_job['estimated_time'])
499 self.assertTrue(found_job['estimated_time'] >= 2)
500 self.assertIsNotNone(found_job['remaining_time'])
501
502 self.worker.hold_jobs_in_build = False
503 self.worker.release()
504 self.waitUntilSettled()
505
James E. Blairec056492016-07-22 09:45:56 -0700506 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700507 def test_time_database(self):
508 "Test the time database"
509
510 self._test_time_database(1)
511 self._test_time_database(2)
512
James E. Blairec056492016-07-22 09:45:56 -0700513 @skip("Disabled for early v3 development")
James E. Blairfef71632013-09-23 11:15:47 -0700514 def test_two_failed_changes_at_head(self):
515 "Test that changes are reparented correctly if 2 fail at head"
516
517 self.worker.hold_jobs_in_build = True
518 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
519 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
520 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
521 A.addApproval('CRVW', 2)
522 B.addApproval('CRVW', 2)
523 C.addApproval('CRVW', 2)
524
525 self.worker.addFailTest('project-test1', A)
526 self.worker.addFailTest('project-test1', B)
527
528 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
529 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
530 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
531 self.waitUntilSettled()
532
533 self.worker.release('.*-merge')
534 self.waitUntilSettled()
535 self.worker.release('.*-merge')
536 self.waitUntilSettled()
537 self.worker.release('.*-merge')
538 self.waitUntilSettled()
539
540 self.assertEqual(len(self.builds), 6)
541 self.assertEqual(self.builds[0].name, 'project-test1')
542 self.assertEqual(self.builds[1].name, 'project-test2')
543 self.assertEqual(self.builds[2].name, 'project-test1')
544 self.assertEqual(self.builds[3].name, 'project-test2')
545 self.assertEqual(self.builds[4].name, 'project-test1')
546 self.assertEqual(self.builds[5].name, 'project-test2')
547
548 self.assertTrue(self.job_has_changes(self.builds[0], A))
549 self.assertTrue(self.job_has_changes(self.builds[2], A))
550 self.assertTrue(self.job_has_changes(self.builds[2], B))
551 self.assertTrue(self.job_has_changes(self.builds[4], A))
552 self.assertTrue(self.job_has_changes(self.builds[4], B))
553 self.assertTrue(self.job_has_changes(self.builds[4], C))
554
555 # Fail change B first
556 self.release(self.builds[2])
557 self.waitUntilSettled()
558
559 # restart of C after B failure
560 self.worker.release('.*-merge')
561 self.waitUntilSettled()
562
563 self.assertEqual(len(self.builds), 5)
564 self.assertEqual(self.builds[0].name, 'project-test1')
565 self.assertEqual(self.builds[1].name, 'project-test2')
566 self.assertEqual(self.builds[2].name, 'project-test2')
567 self.assertEqual(self.builds[3].name, 'project-test1')
568 self.assertEqual(self.builds[4].name, 'project-test2')
569
570 self.assertTrue(self.job_has_changes(self.builds[1], A))
571 self.assertTrue(self.job_has_changes(self.builds[2], A))
572 self.assertTrue(self.job_has_changes(self.builds[2], B))
573 self.assertTrue(self.job_has_changes(self.builds[4], A))
574 self.assertFalse(self.job_has_changes(self.builds[4], B))
575 self.assertTrue(self.job_has_changes(self.builds[4], C))
576
577 # Finish running all passing jobs for change A
578 self.release(self.builds[1])
579 self.waitUntilSettled()
580 # Fail and report change A
581 self.release(self.builds[0])
582 self.waitUntilSettled()
583
584 # restart of B,C after A failure
585 self.worker.release('.*-merge')
586 self.waitUntilSettled()
587 self.worker.release('.*-merge')
588 self.waitUntilSettled()
589
590 self.assertEqual(len(self.builds), 4)
591 self.assertEqual(self.builds[0].name, 'project-test1') # B
592 self.assertEqual(self.builds[1].name, 'project-test2') # B
593 self.assertEqual(self.builds[2].name, 'project-test1') # C
594 self.assertEqual(self.builds[3].name, 'project-test2') # C
595
596 self.assertFalse(self.job_has_changes(self.builds[1], A))
597 self.assertTrue(self.job_has_changes(self.builds[1], B))
598 self.assertFalse(self.job_has_changes(self.builds[1], C))
599
600 self.assertFalse(self.job_has_changes(self.builds[2], A))
601 # After A failed and B and C restarted, B should be back in
602 # C's tests because it has not failed yet.
603 self.assertTrue(self.job_has_changes(self.builds[2], B))
604 self.assertTrue(self.job_has_changes(self.builds[2], C))
605
606 self.worker.hold_jobs_in_build = False
607 self.worker.release()
608 self.waitUntilSettled()
609
610 self.assertEqual(len(self.builds), 0)
611 self.assertEqual(len(self.history), 21)
612 self.assertEqual(A.data['status'], 'NEW')
613 self.assertEqual(B.data['status'], 'NEW')
614 self.assertEqual(C.data['status'], 'MERGED')
615 self.assertEqual(A.reported, 2)
616 self.assertEqual(B.reported, 2)
617 self.assertEqual(C.reported, 2)
618
James E. Blairec056492016-07-22 09:45:56 -0700619 @skip("Disabled for early v3 development")
James E. Blairce8a2132016-05-19 15:21:52 -0700620 def test_parse_skip_if(self):
621 job_yaml = """
622jobs:
623 - name: job_name
624 skip-if:
625 - project: ^project_name$
626 branch: ^stable/icehouse$
627 all-files-match-any:
628 - ^filename$
629 - project: ^project2_name$
630 all-files-match-any:
631 - ^filename2$
632 """.strip()
633 data = yaml.load(job_yaml)
634 config_job = data.get('jobs')[0]
635 cm = zuul.change_matcher
636 expected = cm.MatchAny([
637 cm.MatchAll([
638 cm.ProjectMatcher('^project_name$'),
639 cm.BranchMatcher('^stable/icehouse$'),
640 cm.MatchAllFiles([cm.FileMatcher('^filename$')]),
641 ]),
642 cm.MatchAll([
643 cm.ProjectMatcher('^project2_name$'),
644 cm.MatchAllFiles([cm.FileMatcher('^filename2$')]),
645 ]),
646 ])
647 matcher = self.sched._parseSkipIf(config_job)
648 self.assertEqual(expected, matcher)
649
James E. Blairec056492016-07-22 09:45:56 -0700650 @skip("Disabled for early v3 development")
James E. Blair8c803f82012-07-31 16:25:42 -0700651 def test_patch_order(self):
652 "Test that dependent patches are tested in the right order"
653 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
654 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
655 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
656 A.addApproval('CRVW', 2)
657 B.addApproval('CRVW', 2)
658 C.addApproval('CRVW', 2)
659
660 M2 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M2')
661 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
662 M2.setMerged()
663 M1.setMerged()
664
665 # C -> B -> A -> M1 -> M2
666 # M2 is here to make sure it is never queried. If it is, it
667 # means zuul is walking down the entire history of merged
668 # changes.
669
670 C.setDependsOn(B, 1)
671 B.setDependsOn(A, 1)
672 A.setDependsOn(M1, 1)
673 M1.setDependsOn(M2, 1)
674
675 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
676
677 self.waitUntilSettled()
678
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400679 self.assertEqual(A.data['status'], 'NEW')
680 self.assertEqual(B.data['status'], 'NEW')
681 self.assertEqual(C.data['status'], 'NEW')
James E. Blair8c803f82012-07-31 16:25:42 -0700682
683 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
684 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
685
686 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400687 self.assertEqual(M2.queried, 0)
688 self.assertEqual(A.data['status'], 'MERGED')
689 self.assertEqual(B.data['status'], 'MERGED')
690 self.assertEqual(C.data['status'], 'MERGED')
691 self.assertEqual(A.reported, 2)
692 self.assertEqual(B.reported, 2)
693 self.assertEqual(C.reported, 2)
James E. Blair8c803f82012-07-31 16:25:42 -0700694
James E. Blairec056492016-07-22 09:45:56 -0700695 @skip("Disabled for early v3 development")
James E. Blair063672f2015-01-29 13:09:12 -0800696 def test_needed_changes_enqueue(self):
697 "Test that a needed change is enqueued ahead"
698 # A Given a git tree like this, if we enqueue
699 # / \ change C, we should walk up and down the tree
700 # B G and enqueue changes in the order ABCDEFG.
701 # /|\ This is also the order that you would get if
702 # *C E F you enqueued changes in the order ABCDEFG, so
703 # / the ordering is stable across re-enqueue events.
704 # D
705
706 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
707 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
708 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
709 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
710 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
711 F = self.fake_gerrit.addFakeChange('org/project', 'master', 'F')
712 G = self.fake_gerrit.addFakeChange('org/project', 'master', 'G')
713 B.setDependsOn(A, 1)
714 C.setDependsOn(B, 1)
715 D.setDependsOn(C, 1)
716 E.setDependsOn(B, 1)
717 F.setDependsOn(B, 1)
718 G.setDependsOn(A, 1)
719
720 A.addApproval('CRVW', 2)
721 B.addApproval('CRVW', 2)
722 C.addApproval('CRVW', 2)
723 D.addApproval('CRVW', 2)
724 E.addApproval('CRVW', 2)
725 F.addApproval('CRVW', 2)
726 G.addApproval('CRVW', 2)
727 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
728
729 self.waitUntilSettled()
730
731 self.assertEqual(A.data['status'], 'NEW')
732 self.assertEqual(B.data['status'], 'NEW')
733 self.assertEqual(C.data['status'], 'NEW')
734 self.assertEqual(D.data['status'], 'NEW')
735 self.assertEqual(E.data['status'], 'NEW')
736 self.assertEqual(F.data['status'], 'NEW')
737 self.assertEqual(G.data['status'], 'NEW')
738
739 # We're about to add approvals to changes without adding the
740 # triggering events to Zuul, so that we can be sure that it is
741 # enqueing the changes based on dependencies, not because of
742 # triggering events. Since it will have the changes cached
743 # already (without approvals), we need to clear the cache
744 # first.
Joshua Hesketh4bd7da32016-02-17 20:58:47 +1100745 for connection in self.connections.values():
746 connection.maintainCache([])
James E. Blair063672f2015-01-29 13:09:12 -0800747
748 self.worker.hold_jobs_in_build = True
749 A.addApproval('APRV', 1)
750 B.addApproval('APRV', 1)
751 D.addApproval('APRV', 1)
752 E.addApproval('APRV', 1)
753 F.addApproval('APRV', 1)
754 G.addApproval('APRV', 1)
755 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
756
757 for x in range(8):
758 self.worker.release('.*-merge')
759 self.waitUntilSettled()
760 self.worker.hold_jobs_in_build = False
761 self.worker.release()
762 self.waitUntilSettled()
763
764 self.assertEqual(A.data['status'], 'MERGED')
765 self.assertEqual(B.data['status'], 'MERGED')
766 self.assertEqual(C.data['status'], 'MERGED')
767 self.assertEqual(D.data['status'], 'MERGED')
768 self.assertEqual(E.data['status'], 'MERGED')
769 self.assertEqual(F.data['status'], 'MERGED')
770 self.assertEqual(G.data['status'], 'MERGED')
771 self.assertEqual(A.reported, 2)
772 self.assertEqual(B.reported, 2)
773 self.assertEqual(C.reported, 2)
774 self.assertEqual(D.reported, 2)
775 self.assertEqual(E.reported, 2)
776 self.assertEqual(F.reported, 2)
777 self.assertEqual(G.reported, 2)
778 self.assertEqual(self.history[6].changes,
779 '1,1 2,1 3,1 4,1 5,1 6,1 7,1')
780
James E. Blairec056492016-07-22 09:45:56 -0700781 @skip("Disabled for early v3 development")
Joshua Hesketh850ccb62014-11-27 11:31:02 +1100782 def test_source_cache(self):
783 "Test that the source cache operates correctly"
James E. Blair0e933c52013-07-11 10:18:52 -0700784 self.worker.hold_jobs_in_build = True
785
786 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
787 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
788 X = self.fake_gerrit.addFakeChange('org/project', 'master', 'X')
789 A.addApproval('CRVW', 2)
790 B.addApproval('CRVW', 2)
791
792 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
793 M1.setMerged()
794
795 B.setDependsOn(A, 1)
796 A.setDependsOn(M1, 1)
797
798 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
799 self.fake_gerrit.addEvent(X.getPatchsetCreatedEvent(1))
800
801 self.waitUntilSettled()
802
803 for build in self.builds:
804 if build.parameters['ZUUL_PIPELINE'] == 'check':
805 build.release()
806 self.waitUntilSettled()
807 for build in self.builds:
808 if build.parameters['ZUUL_PIPELINE'] == 'check':
809 build.release()
810 self.waitUntilSettled()
811
812 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
813 self.waitUntilSettled()
814
Joshua Hesketh352264b2015-08-11 23:42:08 +1000815 self.log.debug("len %s" % self.fake_gerrit._change_cache.keys())
James E. Blair0e933c52013-07-11 10:18:52 -0700816 # there should still be changes in the cache
Joshua Hesketh352264b2015-08-11 23:42:08 +1000817 self.assertNotEqual(len(self.fake_gerrit._change_cache.keys()), 0)
James E. Blair0e933c52013-07-11 10:18:52 -0700818
819 self.worker.hold_jobs_in_build = False
820 self.worker.release()
821 self.waitUntilSettled()
822
823 self.assertEqual(A.data['status'], 'MERGED')
824 self.assertEqual(B.data['status'], 'MERGED')
825 self.assertEqual(A.queried, 2) # Initial and isMerged
826 self.assertEqual(B.queried, 3) # Initial A, refresh from B, isMerged
827
James E. Blairec056492016-07-22 09:45:56 -0700828 @skip("Disabled for early v3 development")
James E. Blair8c803f82012-07-31 16:25:42 -0700829 def test_can_merge(self):
James E. Blair4886cc12012-07-18 15:39:41 -0700830 "Test whether a change is ready to merge"
James E. Blair8c803f82012-07-31 16:25:42 -0700831 # TODO: move to test_gerrit (this is a unit test!)
832 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairc0dedf82014-08-06 09:37:52 -0700833 source = self.sched.layout.pipelines['gate'].source
834 a = source._getChange(1, 2)
James E. Blaireff88162013-07-01 12:44:14 -0400835 mgr = self.sched.layout.pipelines['gate'].manager
James E. Blairc0dedf82014-08-06 09:37:52 -0700836 self.assertFalse(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700837
838 A.addApproval('CRVW', 2)
James E. Blairc0dedf82014-08-06 09:37:52 -0700839 a = source._getChange(1, 2, refresh=True)
840 self.assertFalse(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair8c803f82012-07-31 16:25:42 -0700841
842 A.addApproval('APRV', 1)
James E. Blairc0dedf82014-08-06 09:37:52 -0700843 a = source._getChange(1, 2, refresh=True)
844 self.assertTrue(source.canMerge(a, mgr.getSubmitAllowNeeds()))
James E. Blair4886cc12012-07-18 15:39:41 -0700845
James E. Blairec056492016-07-22 09:45:56 -0700846 @skip("Disabled for early v3 development")
James E. Blair4886cc12012-07-18 15:39:41 -0700847 def test_build_configuration(self):
848 "Test that zuul merges the right commits for testing"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700849
850 self.gearman_server.hold_jobs_in_queue = True
James E. Blair4886cc12012-07-18 15:39:41 -0700851 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
852 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
853 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
854 A.addApproval('CRVW', 2)
855 B.addApproval('CRVW', 2)
856 C.addApproval('CRVW', 2)
857 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
858 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
859 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
860 self.waitUntilSettled()
861
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700862 self.gearman_server.release('.*-merge')
James E. Blair4886cc12012-07-18 15:39:41 -0700863 self.waitUntilSettled()
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. Blair701c5b42013-06-06 09:34:59 -0700868 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700869 ref = self.getParameter(queue[-1], 'ZUUL_REF')
870 self.gearman_server.hold_jobs_in_queue = False
871 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700872 self.waitUntilSettled()
James E. Blair4886cc12012-07-18 15:39:41 -0700873
Monty Taylorbc758832013-06-17 17:22:42 -0400874 path = os.path.join(self.git_root, "org/project")
James E. Blair4886cc12012-07-18 15:39:41 -0700875 repo = git.Repo(path)
876 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
877 repo_messages.reverse()
James E. Blair4886cc12012-07-18 15:39:41 -0700878 correct_messages = ['initial commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400879 self.assertEqual(repo_messages, correct_messages)
James E. Blair973721f2012-08-15 10:19:43 -0700880
James E. Blairec056492016-07-22 09:45:56 -0700881 @skip("Disabled for early v3 development")
James E. Blair973721f2012-08-15 10:19:43 -0700882 def test_build_configuration_conflict(self):
883 "Test that merge conflicts are handled"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700884
885 self.gearman_server.hold_jobs_in_queue = True
James E. Blair6736beb2013-07-11 15:18:15 -0700886 A = self.fake_gerrit.addFakeChange('org/conflict-project',
887 'master', 'A')
James E. Blair973721f2012-08-15 10:19:43 -0700888 A.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700889 B = self.fake_gerrit.addFakeChange('org/conflict-project',
890 'master', 'B')
James E. Blair973721f2012-08-15 10:19:43 -0700891 B.addPatchset(['conflict'])
James E. Blair6736beb2013-07-11 15:18:15 -0700892 C = self.fake_gerrit.addFakeChange('org/conflict-project',
893 'master', 'C')
James E. Blair973721f2012-08-15 10:19:43 -0700894 A.addApproval('CRVW', 2)
895 B.addApproval('CRVW', 2)
896 C.addApproval('CRVW', 2)
897 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
898 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
899 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
900 self.waitUntilSettled()
901
James E. Blair6736beb2013-07-11 15:18:15 -0700902 self.assertEqual(A.reported, 1)
903 self.assertEqual(B.reported, 1)
904 self.assertEqual(C.reported, 1)
905
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700906 self.gearman_server.release('.*-merge')
James E. Blair973721f2012-08-15 10:19:43 -0700907 self.waitUntilSettled()
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. Blair972e3c72013-08-29 12:04:55 -0700912
913 self.assertEqual(len(self.history), 2) # A and C merge jobs
914
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700915 self.gearman_server.hold_jobs_in_queue = False
916 self.gearman_server.release()
James E. Blair973721f2012-08-15 10:19:43 -0700917 self.waitUntilSettled()
918
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400919 self.assertEqual(A.data['status'], 'MERGED')
920 self.assertEqual(B.data['status'], 'NEW')
921 self.assertEqual(C.data['status'], 'MERGED')
922 self.assertEqual(A.reported, 2)
923 self.assertEqual(B.reported, 2)
924 self.assertEqual(C.reported, 2)
James E. Blair972e3c72013-08-29 12:04:55 -0700925 self.assertEqual(len(self.history), 6)
James E. Blair6736beb2013-07-11 15:18:15 -0700926
James E. Blairec056492016-07-22 09:45:56 -0700927 @skip("Disabled for early v3 development")
James E. Blairdaabed22012-08-15 15:38:57 -0700928 def test_post(self):
929 "Test that post jobs run"
James E. Blair1f4c2bb2013-04-26 08:40:46 -0700930
Zhongyue Luo5d556072012-09-21 02:00:47 +0900931 e = {
932 "type": "ref-updated",
933 "submitter": {
934 "name": "User Name",
935 },
936 "refUpdate": {
937 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
938 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
939 "refName": "master",
940 "project": "org/project",
941 }
942 }
James E. Blairdaabed22012-08-15 15:38:57 -0700943 self.fake_gerrit.addEvent(e)
944 self.waitUntilSettled()
945
Monty Taylor6bef8ef2013-06-02 08:17:12 -0400946 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -0400947 self.assertEqual(len(self.history), 1)
948 self.assertIn('project-post', job_names)
James E. Blairc6294a52012-08-17 10:19:48 -0700949
James E. Blairec056492016-07-22 09:45:56 -0700950 @skip("Disabled for early v3 development")
K Jonathan Harkerf95e7232015-04-29 13:33:16 -0700951 def test_post_ignore_deletes(self):
952 "Test that deleting refs does not trigger post jobs"
953
954 e = {
955 "type": "ref-updated",
956 "submitter": {
957 "name": "User Name",
958 },
959 "refUpdate": {
960 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
961 "newRev": "0000000000000000000000000000000000000000",
962 "refName": "master",
963 "project": "org/project",
964 }
965 }
966 self.fake_gerrit.addEvent(e)
967 self.waitUntilSettled()
968
969 job_names = [x.name for x in self.history]
970 self.assertEqual(len(self.history), 0)
971 self.assertNotIn('project-post', job_names)
972
James E. Blairec056492016-07-22 09:45:56 -0700973 @skip("Disabled for early v3 development")
K Jonathan Harkerf95e7232015-04-29 13:33:16 -0700974 def test_post_ignore_deletes_negative(self):
975 "Test that deleting refs does trigger post jobs"
976
James E. Blairf84026c2015-12-08 16:11:46 -0800977 self.updateConfigLayout(
978 'tests/fixtures/layout-dont-ignore-deletes.yaml')
K Jonathan Harkerf95e7232015-04-29 13:33:16 -0700979 self.sched.reconfigure(self.config)
980
981 e = {
982 "type": "ref-updated",
983 "submitter": {
984 "name": "User Name",
985 },
986 "refUpdate": {
987 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
988 "newRev": "0000000000000000000000000000000000000000",
989 "refName": "master",
990 "project": "org/project",
991 }
992 }
993 self.fake_gerrit.addEvent(e)
994 self.waitUntilSettled()
995
996 job_names = [x.name for x in self.history]
997 self.assertEqual(len(self.history), 1)
998 self.assertIn('project-post', job_names)
999
James E. Blairec056492016-07-22 09:45:56 -07001000 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001001 def test_build_configuration_branch(self):
1002 "Test that the right commits are on alternate branches"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001003
1004 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -07001005 A = self.fake_gerrit.addFakeChange('org/project', 'mp', 'A')
1006 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
1007 C = self.fake_gerrit.addFakeChange('org/project', 'mp', 'C')
1008 A.addApproval('CRVW', 2)
1009 B.addApproval('CRVW', 2)
1010 C.addApproval('CRVW', 2)
1011 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1012 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1013 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1014 self.waitUntilSettled()
1015
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001016 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001017 self.waitUntilSettled()
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. Blair701c5b42013-06-06 09:34:59 -07001022 queue = self.gearman_server.getQueue()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001023 ref = self.getParameter(queue[-1], 'ZUUL_REF')
1024 self.gearman_server.hold_jobs_in_queue = False
1025 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -07001026 self.waitUntilSettled()
1027
Monty Taylorbc758832013-06-17 17:22:42 -04001028 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001029 repo = git.Repo(path)
1030 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
1031 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001032 correct_messages = ['initial commit', 'mp commit', 'A-1', 'B-1', 'C-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001033 self.assertEqual(repo_messages, correct_messages)
James E. Blairc6294a52012-08-17 10:19:48 -07001034
James E. Blairec056492016-07-22 09:45:56 -07001035 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001036 def test_build_configuration_branch_interaction(self):
1037 "Test that switching between branches works"
1038 self.test_build_configuration()
1039 self.test_build_configuration_branch()
1040 # C has been merged, undo that
Monty Taylorbc758832013-06-17 17:22:42 -04001041 path = os.path.join(self.upstream_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001042 repo = git.Repo(path)
1043 repo.heads.master.commit = repo.commit('init')
1044 self.test_build_configuration()
1045
James E. Blairec056492016-07-22 09:45:56 -07001046 @skip("Disabled for early v3 development")
James E. Blairc6294a52012-08-17 10:19:48 -07001047 def test_build_configuration_multi_branch(self):
1048 "Test that dependent changes on multiple branches are merged"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001049
1050 self.gearman_server.hold_jobs_in_queue = True
James E. Blairc6294a52012-08-17 10:19:48 -07001051 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1052 B = self.fake_gerrit.addFakeChange('org/project', 'mp', 'B')
1053 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1054 A.addApproval('CRVW', 2)
1055 B.addApproval('CRVW', 2)
1056 C.addApproval('CRVW', 2)
1057 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1058 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1059 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1060 self.waitUntilSettled()
James E. Blairbb1fe502014-03-04 10:15:06 -08001061 queue = self.gearman_server.getQueue()
1062 job_A = None
1063 for job in queue:
1064 if 'project-merge' in job.name:
1065 job_A = job
1066 ref_A = self.getParameter(job_A, 'ZUUL_REF')
1067 commit_A = self.getParameter(job_A, 'ZUUL_COMMIT')
1068 self.log.debug("Got Zuul ref for change A: %s" % ref_A)
1069 self.log.debug("Got Zuul commit for change A: %s" % commit_A)
James E. Blairc6294a52012-08-17 10:19:48 -07001070
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001071 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001072 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001073 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -07001074 job_B = None
1075 for job in queue:
1076 if 'project-merge' in job.name:
1077 job_B = job
1078 ref_B = self.getParameter(job_B, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -08001079 commit_B = self.getParameter(job_B, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -07001080 self.log.debug("Got Zuul ref for change B: %s" % ref_B)
James E. Blairbb1fe502014-03-04 10:15:06 -08001081 self.log.debug("Got Zuul commit for change B: %s" % commit_B)
1082
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001083 self.gearman_server.release('.*-merge')
James E. Blairc6294a52012-08-17 10:19:48 -07001084 self.waitUntilSettled()
James E. Blair701c5b42013-06-06 09:34:59 -07001085 queue = self.gearman_server.getQueue()
James E. Blaird320d7e2013-07-30 16:36:20 -07001086 for job in queue:
1087 if 'project-merge' in job.name:
1088 job_C = job
1089 ref_C = self.getParameter(job_C, 'ZUUL_REF')
James E. Blairbb1fe502014-03-04 10:15:06 -08001090 commit_C = self.getParameter(job_C, 'ZUUL_COMMIT')
James E. Blairf750aa02013-07-15 14:11:24 -07001091 self.log.debug("Got Zuul ref for change C: %s" % ref_C)
James E. Blairbb1fe502014-03-04 10:15:06 -08001092 self.log.debug("Got Zuul commit for change C: %s" % commit_C)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001093 self.gearman_server.hold_jobs_in_queue = False
1094 self.gearman_server.release()
James E. Blairc6294a52012-08-17 10:19:48 -07001095 self.waitUntilSettled()
1096
Monty Taylorbc758832013-06-17 17:22:42 -04001097 path = os.path.join(self.git_root, "org/project")
James E. Blairc6294a52012-08-17 10:19:48 -07001098 repo = git.Repo(path)
1099
1100 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -07001101 for c in repo.iter_commits(ref_C)]
James E. Blairbb1fe502014-03-04 10:15:06 -08001102 repo_shas = [c.hexsha for c in repo.iter_commits(ref_C)]
James E. Blairc6294a52012-08-17 10:19:48 -07001103 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001104 correct_messages = ['initial commit', 'A-1', 'C-1']
James E. Blairbb1fe502014-03-04 10:15:06 -08001105 # Ensure the right commits are in the history for this ref
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001106 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -08001107 # Ensure ZUUL_REF -> ZUUL_COMMIT
1108 self.assertEqual(repo_shas[0], commit_C)
James E. Blairc6294a52012-08-17 10:19:48 -07001109
1110 repo_messages = [c.message.strip()
James E. Blairf750aa02013-07-15 14:11:24 -07001111 for c in repo.iter_commits(ref_B)]
James E. Blairbb1fe502014-03-04 10:15:06 -08001112 repo_shas = [c.hexsha for c in repo.iter_commits(ref_B)]
James E. Blairc6294a52012-08-17 10:19:48 -07001113 repo_messages.reverse()
James E. Blairc6294a52012-08-17 10:19:48 -07001114 correct_messages = ['initial commit', 'mp commit', 'B-1']
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001115 self.assertEqual(repo_messages, correct_messages)
James E. Blairbb1fe502014-03-04 10:15:06 -08001116 self.assertEqual(repo_shas[0], commit_B)
1117
1118 repo_messages = [c.message.strip()
1119 for c in repo.iter_commits(ref_A)]
1120 repo_shas = [c.hexsha for c in repo.iter_commits(ref_A)]
1121 repo_messages.reverse()
1122 correct_messages = ['initial commit', 'A-1']
1123 self.assertEqual(repo_messages, correct_messages)
1124 self.assertEqual(repo_shas[0], commit_A)
1125
1126 self.assertNotEqual(ref_A, ref_B, ref_C)
1127 self.assertNotEqual(commit_A, commit_B, commit_C)
James E. Blair7f71c802012-08-22 13:04:32 -07001128
James E. Blairec056492016-07-22 09:45:56 -07001129 @skip("Disabled for early v3 development")
James E. Blair7f71c802012-08-22 13:04:32 -07001130 def test_one_job_project(self):
1131 "Test that queueing works with one job"
1132 A = self.fake_gerrit.addFakeChange('org/one-job-project',
1133 'master', 'A')
1134 B = self.fake_gerrit.addFakeChange('org/one-job-project',
1135 'master', 'B')
1136 A.addApproval('CRVW', 2)
1137 B.addApproval('CRVW', 2)
1138 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1139 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1140 self.waitUntilSettled()
1141
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001142 self.assertEqual(A.data['status'], 'MERGED')
1143 self.assertEqual(A.reported, 2)
1144 self.assertEqual(B.data['status'], 'MERGED')
1145 self.assertEqual(B.reported, 2)
James E. Blaircaec0c52012-08-22 14:52:22 -07001146
James E. Blairec056492016-07-22 09:45:56 -07001147 @skip("Disabled for early v3 development")
Antoine Musso80edd5a2013-02-13 15:37:53 +01001148 def test_job_from_templates_launched(self):
1149 "Test whether a job generated via a template can be launched"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001150
Antoine Musso80edd5a2013-02-13 15:37:53 +01001151 A = self.fake_gerrit.addFakeChange(
1152 'org/templated-project', 'master', 'A')
1153 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1154 self.waitUntilSettled()
Antoine Musso80edd5a2013-02-13 15:37:53 +01001155
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001156 self.assertEqual(self.getJobFromHistory('project-test1').result,
1157 'SUCCESS')
1158 self.assertEqual(self.getJobFromHistory('project-test2').result,
1159 'SUCCESS')
Antoine Musso80edd5a2013-02-13 15:37:53 +01001160
James E. Blairec056492016-07-22 09:45:56 -07001161 @skip("Disabled for early v3 development")
James E. Blair3e98c022013-12-16 15:25:38 -08001162 def test_layered_templates(self):
1163 "Test whether a job generated via a template can be launched"
1164
1165 A = self.fake_gerrit.addFakeChange(
1166 'org/layered-project', 'master', 'A')
1167 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1168 self.waitUntilSettled()
1169
1170 self.assertEqual(self.getJobFromHistory('project-test1').result,
1171 'SUCCESS')
1172 self.assertEqual(self.getJobFromHistory('project-test2').result,
1173 'SUCCESS')
James E. Blairaea6cf62013-12-16 15:38:12 -08001174 self.assertEqual(self.getJobFromHistory('layered-project-test3'
1175 ).result, 'SUCCESS')
1176 self.assertEqual(self.getJobFromHistory('layered-project-test4'
1177 ).result, 'SUCCESS')
James E. Blair12a92b12014-03-26 11:54:53 -07001178 self.assertEqual(self.getJobFromHistory('layered-project-foo-test5'
1179 ).result, 'SUCCESS')
James E. Blair3e98c022013-12-16 15:25:38 -08001180 self.assertEqual(self.getJobFromHistory('project-test6').result,
1181 'SUCCESS')
1182
James E. Blairec056492016-07-22 09:45:56 -07001183 @skip("Disabled for early v3 development")
James E. Blaircaec0c52012-08-22 14:52:22 -07001184 def test_dependent_changes_dequeue(self):
1185 "Test that dependent patches are not needlessly tested"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001186
James E. Blaircaec0c52012-08-22 14:52:22 -07001187 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1188 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1189 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1190 A.addApproval('CRVW', 2)
1191 B.addApproval('CRVW', 2)
1192 C.addApproval('CRVW', 2)
1193
1194 M1 = self.fake_gerrit.addFakeChange('org/project', 'master', 'M1')
1195 M1.setMerged()
1196
1197 # C -> B -> A -> M1
1198
1199 C.setDependsOn(B, 1)
1200 B.setDependsOn(A, 1)
1201 A.setDependsOn(M1, 1)
1202
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001203 self.worker.addFailTest('project-merge', A)
James E. Blaircaec0c52012-08-22 14:52:22 -07001204
1205 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1206 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1207 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1208
1209 self.waitUntilSettled()
1210
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001211 self.assertEqual(A.data['status'], 'NEW')
1212 self.assertEqual(A.reported, 2)
1213 self.assertEqual(B.data['status'], 'NEW')
1214 self.assertEqual(B.reported, 2)
1215 self.assertEqual(C.data['status'], 'NEW')
1216 self.assertEqual(C.reported, 2)
1217 self.assertEqual(len(self.history), 1)
James E. Blairec590122012-08-22 15:19:31 -07001218
James E. Blairec056492016-07-22 09:45:56 -07001219 @skip("Disabled for early v3 development")
James E. Blair972e3c72013-08-29 12:04:55 -07001220 def test_failing_dependent_changes(self):
1221 "Test that failing dependent patches are taken out of stream"
1222 self.worker.hold_jobs_in_build = True
1223 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1224 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1225 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1226 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1227 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
1228 A.addApproval('CRVW', 2)
1229 B.addApproval('CRVW', 2)
1230 C.addApproval('CRVW', 2)
1231 D.addApproval('CRVW', 2)
1232 E.addApproval('CRVW', 2)
1233
1234 # E, D -> C -> B, A
1235
1236 D.setDependsOn(C, 1)
1237 C.setDependsOn(B, 1)
1238
1239 self.worker.addFailTest('project-test1', B)
1240
1241 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1242 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1243 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1244 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1245 self.fake_gerrit.addEvent(E.addApproval('APRV', 1))
1246
1247 self.waitUntilSettled()
1248 self.worker.release('.*-merge')
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
1259 self.worker.hold_jobs_in_build = False
1260 for build in self.builds:
1261 if build.parameters['ZUUL_CHANGE'] != '1':
1262 build.release()
1263 self.waitUntilSettled()
1264
1265 self.worker.release()
1266 self.waitUntilSettled()
1267
1268 self.assertEqual(A.data['status'], 'MERGED')
1269 self.assertEqual(A.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001270 self.assertIn('Build succeeded', A.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001271 self.assertEqual(B.data['status'], 'NEW')
1272 self.assertEqual(B.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001273 self.assertIn('Build failed', B.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001274 self.assertEqual(C.data['status'], 'NEW')
1275 self.assertEqual(C.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001276 self.assertIn('depends on a change', C.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001277 self.assertEqual(D.data['status'], 'NEW')
1278 self.assertEqual(D.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001279 self.assertIn('depends on a change', D.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001280 self.assertEqual(E.data['status'], 'MERGED')
1281 self.assertEqual(E.reported, 2)
Jeremy Stanley10837132014-08-02 16:10:56 +00001282 self.assertIn('Build succeeded', E.messages[1])
James E. Blair972e3c72013-08-29 12:04:55 -07001283 self.assertEqual(len(self.history), 18)
1284
James E. Blairec056492016-07-22 09:45:56 -07001285 @skip("Disabled for early v3 development")
James E. Blairec590122012-08-22 15:19:31 -07001286 def test_head_is_dequeued_once(self):
James E. Blair2fa50962013-01-30 21:50:41 -08001287 "Test that if a change at the head fails it is dequeued only once"
James E. Blairec590122012-08-22 15:19:31 -07001288 # If it's dequeued more than once, we should see extra
1289 # aborted jobs.
James E. Blairec590122012-08-22 15:19:31 -07001290
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001291 self.worker.hold_jobs_in_build = True
James E. Blairec590122012-08-22 15:19:31 -07001292 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1293 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1294 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
1295 A.addApproval('CRVW', 2)
1296 B.addApproval('CRVW', 2)
1297 C.addApproval('CRVW', 2)
1298
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001299 self.worker.addFailTest('project1-test1', A)
1300 self.worker.addFailTest('project1-test2', A)
1301 self.worker.addFailTest('project1-project2-integration', A)
James E. Blairec590122012-08-22 15:19:31 -07001302
1303 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1304 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1305 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1306
1307 self.waitUntilSettled()
James E. Blairec590122012-08-22 15:19:31 -07001308
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001309 self.assertEqual(len(self.builds), 1)
1310 self.assertEqual(self.builds[0].name, 'project1-merge')
1311 self.assertTrue(self.job_has_changes(self.builds[0], A))
James E. Blairec590122012-08-22 15:19:31 -07001312
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001313 self.worker.release('.*-merge')
James E. Blairec590122012-08-22 15:19:31 -07001314 self.waitUntilSettled()
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()
1319
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001320 self.assertEqual(len(self.builds), 9)
1321 self.assertEqual(self.builds[0].name, 'project1-test1')
1322 self.assertEqual(self.builds[1].name, 'project1-test2')
1323 self.assertEqual(self.builds[2].name, 'project1-project2-integration')
1324 self.assertEqual(self.builds[3].name, 'project1-test1')
1325 self.assertEqual(self.builds[4].name, 'project1-test2')
1326 self.assertEqual(self.builds[5].name, 'project1-project2-integration')
1327 self.assertEqual(self.builds[6].name, 'project1-test1')
1328 self.assertEqual(self.builds[7].name, 'project1-test2')
1329 self.assertEqual(self.builds[8].name, 'project1-project2-integration')
James E. Blairec590122012-08-22 15:19:31 -07001330
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001331 self.release(self.builds[0])
James E. Blairec590122012-08-22 15:19:31 -07001332 self.waitUntilSettled()
1333
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001334 self.assertEqual(len(self.builds), 3) # test2,integration, merge for B
1335 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 6)
James E. Blairec590122012-08-22 15:19:31 -07001336
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001337 self.worker.hold_jobs_in_build = False
1338 self.worker.release()
James E. Blairec590122012-08-22 15:19:31 -07001339 self.waitUntilSettled()
1340
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001341 self.assertEqual(len(self.builds), 0)
1342 self.assertEqual(len(self.history), 20)
James E. Blaircaec0c52012-08-22 14:52:22 -07001343
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001344 self.assertEqual(A.data['status'], 'NEW')
1345 self.assertEqual(B.data['status'], 'MERGED')
1346 self.assertEqual(C.data['status'], 'MERGED')
1347 self.assertEqual(A.reported, 2)
1348 self.assertEqual(B.reported, 2)
1349 self.assertEqual(C.reported, 2)
James E. Blair4ec821f2012-08-23 15:28:28 -07001350
James E. Blairec056492016-07-22 09:45:56 -07001351 @skip("Disabled for early v3 development")
James E. Blair4ec821f2012-08-23 15:28:28 -07001352 def test_nonvoting_job(self):
1353 "Test that non-voting jobs don't vote."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001354
James E. Blair4ec821f2012-08-23 15:28:28 -07001355 A = self.fake_gerrit.addFakeChange('org/nonvoting-project',
1356 'master', 'A')
1357 A.addApproval('CRVW', 2)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001358 self.worker.addFailTest('nonvoting-project-test2', A)
James E. Blair4ec821f2012-08-23 15:28:28 -07001359 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1360
1361 self.waitUntilSettled()
James E. Blair4ec821f2012-08-23 15:28:28 -07001362
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001363 self.assertEqual(A.data['status'], 'MERGED')
1364 self.assertEqual(A.reported, 2)
1365 self.assertEqual(
1366 self.getJobFromHistory('nonvoting-project-merge').result,
1367 'SUCCESS')
1368 self.assertEqual(
1369 self.getJobFromHistory('nonvoting-project-test1').result,
1370 'SUCCESS')
1371 self.assertEqual(
1372 self.getJobFromHistory('nonvoting-project-test2').result,
1373 'FAILURE')
James E. Blaire0487072012-08-29 17:38:31 -07001374
James E. Blair5821bd92015-09-16 08:48:15 -07001375 for build in self.builds:
1376 self.assertEqual(build.parameters['ZUUL_VOTING'], '0')
1377
James E. Blairec056492016-07-22 09:45:56 -07001378 @skip("Disabled for early v3 development")
James E. Blaire0487072012-08-29 17:38:31 -07001379 def test_check_queue_success(self):
1380 "Test successful check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001381
James E. Blaire0487072012-08-29 17:38:31 -07001382 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1383 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1384
1385 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001386
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001387 self.assertEqual(A.data['status'], 'NEW')
1388 self.assertEqual(A.reported, 1)
1389 self.assertEqual(self.getJobFromHistory('project-merge').result,
1390 'SUCCESS')
1391 self.assertEqual(self.getJobFromHistory('project-test1').result,
1392 'SUCCESS')
1393 self.assertEqual(self.getJobFromHistory('project-test2').result,
1394 'SUCCESS')
James E. Blaire0487072012-08-29 17:38:31 -07001395
James E. Blairec056492016-07-22 09:45:56 -07001396 @skip("Disabled for early v3 development")
James E. Blaire0487072012-08-29 17:38:31 -07001397 def test_check_queue_failure(self):
1398 "Test failed check queue jobs."
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001399
James E. Blaire0487072012-08-29 17:38:31 -07001400 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001401 self.worker.addFailTest('project-test2', A)
James E. Blaire0487072012-08-29 17:38:31 -07001402 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1403
1404 self.waitUntilSettled()
James E. Blaire0487072012-08-29 17:38:31 -07001405
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001406 self.assertEqual(A.data['status'], 'NEW')
1407 self.assertEqual(A.reported, 1)
1408 self.assertEqual(self.getJobFromHistory('project-merge').result,
James E. Blair78e31b32013-07-09 09:11:34 -07001409 'SUCCESS')
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001410 self.assertEqual(self.getJobFromHistory('project-test1').result,
1411 'SUCCESS')
1412 self.assertEqual(self.getJobFromHistory('project-test2').result,
1413 'FAILURE')
James E. Blair127bc182012-08-28 15:55:15 -07001414
James E. Blairec056492016-07-22 09:45:56 -07001415 @skip("Disabled for early v3 development")
James E. Blair127bc182012-08-28 15:55:15 -07001416 def test_dependent_behind_dequeue(self):
1417 "test that dependent changes behind dequeued changes work"
1418 # This complicated test is a reproduction of a real life bug
1419 self.sched.reconfigure(self.config)
James E. Blair127bc182012-08-28 15:55:15 -07001420
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001421 self.worker.hold_jobs_in_build = True
James E. Blair127bc182012-08-28 15:55:15 -07001422 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1423 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
1424 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
1425 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
1426 E = self.fake_gerrit.addFakeChange('org/project2', 'master', 'E')
1427 F = self.fake_gerrit.addFakeChange('org/project3', 'master', 'F')
1428 D.setDependsOn(C, 1)
1429 E.setDependsOn(D, 1)
1430 A.addApproval('CRVW', 2)
1431 B.addApproval('CRVW', 2)
1432 C.addApproval('CRVW', 2)
1433 D.addApproval('CRVW', 2)
1434 E.addApproval('CRVW', 2)
1435 F.addApproval('CRVW', 2)
1436
1437 A.fail_merge = True
James E. Blair127bc182012-08-28 15:55:15 -07001438
1439 # Change object re-use in the gerrit trigger is hidden if
1440 # changes are added in quick succession; waiting makes it more
1441 # like real life.
1442 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1443 self.waitUntilSettled()
1444 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1445 self.waitUntilSettled()
1446
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001447 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001448 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001449 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001450 self.waitUntilSettled()
1451
1452 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1453 self.waitUntilSettled()
1454 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1455 self.waitUntilSettled()
1456 self.fake_gerrit.addEvent(E.addApproval('APRV', 1))
1457 self.waitUntilSettled()
1458 self.fake_gerrit.addEvent(F.addApproval('APRV', 1))
1459 self.waitUntilSettled()
1460
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001461 self.worker.release('.*-merge')
James E. Blair127bc182012-08-28 15:55:15 -07001462 self.waitUntilSettled()
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()
1469
1470 # all jobs running
James E. Blaire955e062012-10-08 09:49:03 -07001471
1472 # Grab pointers to the jobs we want to release before
1473 # releasing any, because list indexes may change as
1474 # the jobs complete.
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001475 a, b, c = self.builds[:3]
James E. Blaire955e062012-10-08 09:49:03 -07001476 a.release()
1477 b.release()
1478 c.release()
James E. Blair127bc182012-08-28 15:55:15 -07001479 self.waitUntilSettled()
1480
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001481 self.worker.hold_jobs_in_build = False
1482 self.worker.release()
James E. Blair127bc182012-08-28 15:55:15 -07001483 self.waitUntilSettled()
1484
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001485 self.assertEqual(A.data['status'], 'NEW')
1486 self.assertEqual(B.data['status'], 'MERGED')
1487 self.assertEqual(C.data['status'], 'MERGED')
1488 self.assertEqual(D.data['status'], 'MERGED')
1489 self.assertEqual(E.data['status'], 'MERGED')
1490 self.assertEqual(F.data['status'], 'MERGED')
James E. Blair127bc182012-08-28 15:55:15 -07001491
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001492 self.assertEqual(A.reported, 2)
1493 self.assertEqual(B.reported, 2)
1494 self.assertEqual(C.reported, 2)
1495 self.assertEqual(D.reported, 2)
1496 self.assertEqual(E.reported, 2)
1497 self.assertEqual(F.reported, 2)
James E. Blair127bc182012-08-28 15:55:15 -07001498
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001499 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 15)
1500 self.assertEqual(len(self.history), 44)
James E. Blair05fed602012-09-07 12:45:24 -07001501
James E. Blairec056492016-07-22 09:45:56 -07001502 @skip("Disabled for early v3 development")
James E. Blair05fed602012-09-07 12:45:24 -07001503 def test_merger_repack(self):
1504 "Test that the merger works after a repack"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001505
James E. Blair05fed602012-09-07 12:45:24 -07001506 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1507 A.addApproval('CRVW', 2)
1508 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1509 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001510 self.assertEqual(self.getJobFromHistory('project-merge').result,
1511 'SUCCESS')
1512 self.assertEqual(self.getJobFromHistory('project-test1').result,
1513 'SUCCESS')
1514 self.assertEqual(self.getJobFromHistory('project-test2').result,
1515 'SUCCESS')
1516 self.assertEqual(A.data['status'], 'MERGED')
1517 self.assertEqual(A.reported, 2)
James E. Blair05fed602012-09-07 12:45:24 -07001518 self.assertEmptyQueues()
James E. Blair4ca985f2013-05-30 12:27:43 -07001519 self.worker.build_history = []
James E. Blair05fed602012-09-07 12:45:24 -07001520
Monty Taylorbc758832013-06-17 17:22:42 -04001521 path = os.path.join(self.git_root, "org/project")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001522 print(repack_repo(path))
James E. Blair05fed602012-09-07 12:45:24 -07001523
1524 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1525 A.addApproval('CRVW', 2)
1526 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1527 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001528 self.assertEqual(self.getJobFromHistory('project-merge').result,
1529 'SUCCESS')
1530 self.assertEqual(self.getJobFromHistory('project-test1').result,
1531 'SUCCESS')
1532 self.assertEqual(self.getJobFromHistory('project-test2').result,
1533 'SUCCESS')
1534 self.assertEqual(A.data['status'], 'MERGED')
1535 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001536
James E. Blairec056492016-07-22 09:45:56 -07001537 @skip("Disabled for early v3 development")
James E. Blair4886f282012-11-15 09:27:33 -08001538 def test_merger_repack_large_change(self):
1539 "Test that the merger works with large changes after a repack"
1540 # https://bugs.launchpad.net/zuul/+bug/1078946
James E. Blairac2c3242014-01-24 13:38:51 -08001541 # This test assumes the repo is already cloned; make sure it is
Joshua Hesketh352264b2015-08-11 23:42:08 +10001542 url = self.fake_gerrit.getGitUrl(
James E. Blairac2c3242014-01-24 13:38:51 -08001543 self.sched.layout.projects['org/project1'])
James E. Blair4076e2b2014-01-28 12:42:20 -08001544 self.merge_server.merger.addProject('org/project1', url)
James E. Blair4886f282012-11-15 09:27:33 -08001545 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
1546 A.addPatchset(large=True)
Monty Taylorbc758832013-06-17 17:22:42 -04001547 path = os.path.join(self.upstream_root, "org/project1")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001548 print(repack_repo(path))
Monty Taylorbc758832013-06-17 17:22:42 -04001549 path = os.path.join(self.git_root, "org/project1")
Morgan Fainberg4c6a7742016-05-27 08:42:17 -07001550 print(repack_repo(path))
James E. Blair4886f282012-11-15 09:27:33 -08001551
1552 A.addApproval('CRVW', 2)
1553 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1554 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001555 self.assertEqual(self.getJobFromHistory('project1-merge').result,
1556 'SUCCESS')
1557 self.assertEqual(self.getJobFromHistory('project1-test1').result,
1558 'SUCCESS')
1559 self.assertEqual(self.getJobFromHistory('project1-test2').result,
1560 'SUCCESS')
1561 self.assertEqual(A.data['status'], 'MERGED')
1562 self.assertEqual(A.reported, 2)
James E. Blair4886f282012-11-15 09:27:33 -08001563
James E. Blairec056492016-07-22 09:45:56 -07001564 @skip("Disabled for early v3 development")
James E. Blair7ee88a22012-09-12 18:59:31 +02001565 def test_nonexistent_job(self):
1566 "Test launching a job that doesn't exist"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001567 # Set to the state immediately after a restart
1568 self.resetGearmanServer()
1569 self.launcher.negative_function_cache_ttl = 0
James E. Blair7ee88a22012-09-12 18:59:31 +02001570
1571 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1572 A.addApproval('CRVW', 2)
1573 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1574 # There may be a thread about to report a lost change
1575 while A.reported < 2:
1576 self.waitUntilSettled()
Monty Taylor6bef8ef2013-06-02 08:17:12 -04001577 job_names = [x.name for x in self.history]
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001578 self.assertFalse(job_names)
1579 self.assertEqual(A.data['status'], 'NEW')
1580 self.assertEqual(A.reported, 2)
James E. Blair7ee88a22012-09-12 18:59:31 +02001581 self.assertEmptyQueues()
1582
1583 # Make sure things still work:
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001584 self.registerJobs()
James E. Blair7ee88a22012-09-12 18:59:31 +02001585 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1586 A.addApproval('CRVW', 2)
1587 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1588 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001589 self.assertEqual(self.getJobFromHistory('project-merge').result,
1590 'SUCCESS')
1591 self.assertEqual(self.getJobFromHistory('project-test1').result,
1592 'SUCCESS')
1593 self.assertEqual(self.getJobFromHistory('project-test2').result,
1594 'SUCCESS')
1595 self.assertEqual(A.data['status'], 'MERGED')
1596 self.assertEqual(A.reported, 2)
James E. Blairf62d4282012-12-31 17:01:50 -08001597
James E. Blairec056492016-07-22 09:45:56 -07001598 @skip("Disabled for early v3 development")
James E. Blairf62d4282012-12-31 17:01:50 -08001599 def test_single_nonexistent_post_job(self):
1600 "Test launching a single post job that doesn't exist"
James E. Blairf62d4282012-12-31 17:01:50 -08001601 e = {
1602 "type": "ref-updated",
1603 "submitter": {
1604 "name": "User Name",
1605 },
1606 "refUpdate": {
1607 "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
1608 "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
1609 "refName": "master",
1610 "project": "org/project",
1611 }
1612 }
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001613 # Set to the state immediately after a restart
1614 self.resetGearmanServer()
1615 self.launcher.negative_function_cache_ttl = 0
1616
James E. Blairf62d4282012-12-31 17:01:50 -08001617 self.fake_gerrit.addEvent(e)
1618 self.waitUntilSettled()
1619
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001620 self.assertEqual(len(self.history), 0)
James E. Blair2fa50962013-01-30 21:50:41 -08001621
James E. Blairec056492016-07-22 09:45:56 -07001622 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001623 def test_new_patchset_dequeues_old(self):
1624 "Test that a new patchset causes the old to be dequeued"
1625 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001626 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001627 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1628 M.setMerged()
1629
1630 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1631 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1632 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1633 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1634 A.addApproval('CRVW', 2)
1635 B.addApproval('CRVW', 2)
1636 C.addApproval('CRVW', 2)
1637 D.addApproval('CRVW', 2)
1638
1639 C.setDependsOn(B, 1)
1640 B.setDependsOn(A, 1)
1641 A.setDependsOn(M, 1)
1642
1643 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1644 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1645 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1646 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1647 self.waitUntilSettled()
1648
1649 B.addPatchset()
1650 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1651 self.waitUntilSettled()
1652
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001653 self.worker.hold_jobs_in_build = False
1654 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001655 self.waitUntilSettled()
1656
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001657 self.assertEqual(A.data['status'], 'MERGED')
1658 self.assertEqual(A.reported, 2)
1659 self.assertEqual(B.data['status'], 'NEW')
1660 self.assertEqual(B.reported, 2)
1661 self.assertEqual(C.data['status'], 'NEW')
1662 self.assertEqual(C.reported, 2)
1663 self.assertEqual(D.data['status'], 'MERGED')
1664 self.assertEqual(D.reported, 2)
1665 self.assertEqual(len(self.history), 9) # 3 each for A, B, D.
James E. Blair2fa50962013-01-30 21:50:41 -08001666
James E. Blairec056492016-07-22 09:45:56 -07001667 @skip("Disabled for early v3 development")
James E. Blairba437362015-02-07 11:41:52 -08001668 def test_new_patchset_check(self):
1669 "Test a new patchset in check"
Antoine Mussobd86a312014-01-08 14:51:33 +01001670
1671 self.worker.hold_jobs_in_build = True
1672
1673 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blairba437362015-02-07 11:41:52 -08001674 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1675 check_pipeline = self.sched.layout.pipelines['check']
1676
1677 # Add two git-dependent changes
1678 B.setDependsOn(A, 1)
1679 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1680 self.waitUntilSettled()
Antoine Mussobd86a312014-01-08 14:51:33 +01001681 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1682 self.waitUntilSettled()
James E. Blairba437362015-02-07 11:41:52 -08001683
1684 # A live item, and a non-live/live pair
1685 items = check_pipeline.getAllItems()
1686 self.assertEqual(len(items), 3)
1687
1688 self.assertEqual(items[0].change.number, '1')
1689 self.assertEqual(items[0].change.patchset, '1')
1690 self.assertFalse(items[0].live)
1691
1692 self.assertEqual(items[1].change.number, '2')
1693 self.assertEqual(items[1].change.patchset, '1')
1694 self.assertTrue(items[1].live)
1695
1696 self.assertEqual(items[2].change.number, '1')
1697 self.assertEqual(items[2].change.patchset, '1')
1698 self.assertTrue(items[2].live)
1699
1700 # Add a new patchset to A
1701 A.addPatchset()
1702 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1703 self.waitUntilSettled()
1704
1705 # The live copy of A,1 should be gone, but the non-live and B
1706 # should continue, and we should have a new A,2
1707 items = check_pipeline.getAllItems()
1708 self.assertEqual(len(items), 3)
1709
1710 self.assertEqual(items[0].change.number, '1')
1711 self.assertEqual(items[0].change.patchset, '1')
1712 self.assertFalse(items[0].live)
1713
1714 self.assertEqual(items[1].change.number, '2')
1715 self.assertEqual(items[1].change.patchset, '1')
1716 self.assertTrue(items[1].live)
1717
1718 self.assertEqual(items[2].change.number, '1')
1719 self.assertEqual(items[2].change.patchset, '2')
1720 self.assertTrue(items[2].live)
1721
1722 # Add a new patchset to B
1723 B.addPatchset()
1724 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1725 self.waitUntilSettled()
1726
1727 # The live copy of B,1 should be gone, and it's non-live copy of A,1
1728 # but we should have a new B,2 (still based on A,1)
1729 items = check_pipeline.getAllItems()
1730 self.assertEqual(len(items), 3)
1731
1732 self.assertEqual(items[0].change.number, '1')
1733 self.assertEqual(items[0].change.patchset, '2')
1734 self.assertTrue(items[0].live)
1735
1736 self.assertEqual(items[1].change.number, '1')
1737 self.assertEqual(items[1].change.patchset, '1')
1738 self.assertFalse(items[1].live)
1739
1740 self.assertEqual(items[2].change.number, '2')
1741 self.assertEqual(items[2].change.patchset, '2')
1742 self.assertTrue(items[2].live)
1743
1744 self.builds[0].release()
1745 self.waitUntilSettled()
1746 self.builds[0].release()
1747 self.waitUntilSettled()
1748 self.worker.hold_jobs_in_build = False
1749 self.worker.release()
1750 self.waitUntilSettled()
1751
1752 self.assertEqual(A.reported, 1)
1753 self.assertEqual(B.reported, 1)
1754 self.assertEqual(self.history[0].result, 'ABORTED')
1755 self.assertEqual(self.history[0].changes, '1,1')
1756 self.assertEqual(self.history[1].result, 'ABORTED')
1757 self.assertEqual(self.history[1].changes, '1,1 2,1')
1758 self.assertEqual(self.history[2].result, 'SUCCESS')
1759 self.assertEqual(self.history[2].changes, '1,2')
1760 self.assertEqual(self.history[3].result, 'SUCCESS')
1761 self.assertEqual(self.history[3].changes, '1,1 2,2')
1762
James E. Blairec056492016-07-22 09:45:56 -07001763 @skip("Disabled for early v3 development")
James E. Blairba437362015-02-07 11:41:52 -08001764 def test_abandoned_gate(self):
1765 "Test that an abandoned change is dequeued from gate"
1766
1767 self.worker.hold_jobs_in_build = True
1768
1769 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1770 A.addApproval('CRVW', 2)
1771 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1772 self.waitUntilSettled()
Antoine Mussobd86a312014-01-08 14:51:33 +01001773 self.assertEqual(len(self.builds), 1, "One job being built (on hold)")
1774 self.assertEqual(self.builds[0].name, 'project-merge')
1775
1776 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1777 self.waitUntilSettled()
1778
Antoine Mussobd86a312014-01-08 14:51:33 +01001779 self.worker.release('.*-merge')
1780 self.waitUntilSettled()
1781
1782 self.assertEqual(len(self.builds), 0, "No job running")
Antoine Mussobd86a312014-01-08 14:51:33 +01001783 self.assertEqual(len(self.history), 1, "Only one build in history")
1784 self.assertEqual(self.history[0].result, 'ABORTED',
James E. Blairba437362015-02-07 11:41:52 -08001785 "Build should have been aborted")
1786 self.assertEqual(A.reported, 1,
1787 "Abandoned gate change should report only start")
1788
James E. Blairec056492016-07-22 09:45:56 -07001789 @skip("Disabled for early v3 development")
James E. Blairba437362015-02-07 11:41:52 -08001790 def test_abandoned_check(self):
1791 "Test that an abandoned change is dequeued from check"
1792
1793 self.worker.hold_jobs_in_build = True
1794
1795 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1796 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1797 check_pipeline = self.sched.layout.pipelines['check']
1798
1799 # Add two git-dependent changes
1800 B.setDependsOn(A, 1)
1801 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1802 self.waitUntilSettled()
1803 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1804 self.waitUntilSettled()
1805 # A live item, and a non-live/live pair
1806 items = check_pipeline.getAllItems()
1807 self.assertEqual(len(items), 3)
1808
1809 self.assertEqual(items[0].change.number, '1')
1810 self.assertFalse(items[0].live)
1811
1812 self.assertEqual(items[1].change.number, '2')
1813 self.assertTrue(items[1].live)
1814
1815 self.assertEqual(items[2].change.number, '1')
1816 self.assertTrue(items[2].live)
1817
1818 # Abandon A
1819 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1820 self.waitUntilSettled()
1821
1822 # The live copy of A should be gone, but the non-live and B
1823 # should continue
1824 items = check_pipeline.getAllItems()
1825 self.assertEqual(len(items), 2)
1826
1827 self.assertEqual(items[0].change.number, '1')
1828 self.assertFalse(items[0].live)
1829
1830 self.assertEqual(items[1].change.number, '2')
1831 self.assertTrue(items[1].live)
1832
1833 self.worker.hold_jobs_in_build = False
1834 self.worker.release()
1835 self.waitUntilSettled()
1836
1837 self.assertEqual(len(self.history), 4)
1838 self.assertEqual(self.history[0].result, 'ABORTED',
Antoine Mussobd86a312014-01-08 14:51:33 +01001839 'Build should have been aborted')
1840 self.assertEqual(A.reported, 0, "Abandoned change should not report")
James E. Blairba437362015-02-07 11:41:52 -08001841 self.assertEqual(B.reported, 1, "Change should report")
Antoine Mussobd86a312014-01-08 14:51:33 +01001842
James E. Blairec056492016-07-22 09:45:56 -07001843 @skip("Disabled for early v3 development")
Steve Varnau7b78b312015-04-03 14:49:46 -07001844 def test_abandoned_not_timer(self):
1845 "Test that an abandoned change does not cancel timer jobs"
1846
1847 self.worker.hold_jobs_in_build = True
1848
1849 # Start timer trigger - also org/project
James E. Blairf84026c2015-12-08 16:11:46 -08001850 self.updateConfigLayout(
1851 'tests/fixtures/layout-idle.yaml')
Steve Varnau7b78b312015-04-03 14:49:46 -07001852 self.sched.reconfigure(self.config)
1853 self.registerJobs()
1854 # The pipeline triggers every second, so we should have seen
1855 # several by now.
1856 time.sleep(5)
1857 self.waitUntilSettled()
1858 # Stop queuing timer triggered jobs so that the assertions
1859 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08001860 self.updateConfigLayout(
1861 'tests/fixtures/layout-no-timer.yaml')
Steve Varnau7b78b312015-04-03 14:49:46 -07001862 self.sched.reconfigure(self.config)
1863 self.registerJobs()
1864 self.assertEqual(len(self.builds), 2, "Two timer jobs")
1865
1866 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1867 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1868 self.waitUntilSettled()
1869 self.assertEqual(len(self.builds), 3, "One change plus two timer jobs")
1870
1871 self.fake_gerrit.addEvent(A.getChangeAbandonedEvent())
1872 self.waitUntilSettled()
1873
1874 self.assertEqual(len(self.builds), 2, "Two timer jobs remain")
1875
1876 self.worker.release()
1877 self.waitUntilSettled()
1878
James E. Blairec056492016-07-22 09:45:56 -07001879 @skip("Disabled for early v3 development")
Arx Cruzb1b010d2013-10-28 19:49:59 -02001880 def test_zuul_url_return(self):
1881 "Test if ZUUL_URL is returning when zuul_url is set in zuul.conf"
James E. Blair4076e2b2014-01-28 12:42:20 -08001882 self.assertTrue(self.sched.config.has_option('merger', 'zuul_url'))
Arx Cruzb1b010d2013-10-28 19:49:59 -02001883 self.worker.hold_jobs_in_build = True
1884
1885 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1886 A.addApproval('CRVW', 2)
1887 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1888 self.waitUntilSettled()
1889
1890 self.assertEqual(len(self.builds), 1)
1891 for build in self.builds:
1892 self.assertTrue('ZUUL_URL' in build.parameters)
1893
1894 self.worker.hold_jobs_in_build = False
1895 self.worker.release()
1896 self.waitUntilSettled()
1897
James E. Blairec056492016-07-22 09:45:56 -07001898 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001899 def test_new_patchset_dequeues_old_on_head(self):
1900 "Test that a new patchset causes the old to be dequeued (at head)"
1901 # D -> C (depends on B) -> B (depends on A) -> A -> M
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001902 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001903 M = self.fake_gerrit.addFakeChange('org/project', 'master', 'M')
1904 M.setMerged()
1905 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1906 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1907 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1908 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
1909 A.addApproval('CRVW', 2)
1910 B.addApproval('CRVW', 2)
1911 C.addApproval('CRVW', 2)
1912 D.addApproval('CRVW', 2)
1913
1914 C.setDependsOn(B, 1)
1915 B.setDependsOn(A, 1)
1916 A.setDependsOn(M, 1)
1917
1918 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1919 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1920 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1921 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
1922 self.waitUntilSettled()
1923
1924 A.addPatchset()
1925 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
1926 self.waitUntilSettled()
1927
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001928 self.worker.hold_jobs_in_build = False
1929 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001930 self.waitUntilSettled()
1931
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001932 self.assertEqual(A.data['status'], 'NEW')
1933 self.assertEqual(A.reported, 2)
1934 self.assertEqual(B.data['status'], 'NEW')
1935 self.assertEqual(B.reported, 2)
1936 self.assertEqual(C.data['status'], 'NEW')
1937 self.assertEqual(C.reported, 2)
1938 self.assertEqual(D.data['status'], 'MERGED')
1939 self.assertEqual(D.reported, 2)
1940 self.assertEqual(len(self.history), 7)
James E. Blair2fa50962013-01-30 21:50:41 -08001941
James E. Blairec056492016-07-22 09:45:56 -07001942 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001943 def test_new_patchset_dequeues_old_without_dependents(self):
1944 "Test that a new patchset causes only the old to be dequeued"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001945 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001946 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1947 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1948 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1949 A.addApproval('CRVW', 2)
1950 B.addApproval('CRVW', 2)
1951 C.addApproval('CRVW', 2)
1952
1953 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
1954 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
1955 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
1956 self.waitUntilSettled()
1957
1958 B.addPatchset()
1959 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1960 self.waitUntilSettled()
1961
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001962 self.worker.hold_jobs_in_build = False
1963 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001964 self.waitUntilSettled()
1965
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001966 self.assertEqual(A.data['status'], 'MERGED')
1967 self.assertEqual(A.reported, 2)
1968 self.assertEqual(B.data['status'], 'NEW')
1969 self.assertEqual(B.reported, 2)
1970 self.assertEqual(C.data['status'], 'MERGED')
1971 self.assertEqual(C.reported, 2)
1972 self.assertEqual(len(self.history), 9)
James E. Blair2fa50962013-01-30 21:50:41 -08001973
James E. Blairec056492016-07-22 09:45:56 -07001974 @skip("Disabled for early v3 development")
James E. Blair2fa50962013-01-30 21:50:41 -08001975 def test_new_patchset_dequeues_old_independent_queue(self):
1976 "Test that a new patchset causes the old to be dequeued (independent)"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001977 self.worker.hold_jobs_in_build = True
James E. Blair2fa50962013-01-30 21:50:41 -08001978 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1979 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1980 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
1981 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1982 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1983 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
1984 self.waitUntilSettled()
1985
1986 B.addPatchset()
1987 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(2))
1988 self.waitUntilSettled()
1989
James E. Blair1f4c2bb2013-04-26 08:40:46 -07001990 self.worker.hold_jobs_in_build = False
1991 self.worker.release()
James E. Blair2fa50962013-01-30 21:50:41 -08001992 self.waitUntilSettled()
1993
Monty Taylor98f0f3e2013-07-06 16:02:31 -04001994 self.assertEqual(A.data['status'], 'NEW')
1995 self.assertEqual(A.reported, 1)
1996 self.assertEqual(B.data['status'], 'NEW')
1997 self.assertEqual(B.reported, 1)
1998 self.assertEqual(C.data['status'], 'NEW')
1999 self.assertEqual(C.reported, 1)
2000 self.assertEqual(len(self.history), 10)
2001 self.assertEqual(self.countJobResults(self.history, 'ABORTED'), 1)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002002
James E. Blairec056492016-07-22 09:45:56 -07002003 @skip("Disabled for early v3 development")
James E. Blair18c64442014-03-18 10:14:45 -07002004 def test_noop_job(self):
2005 "Test that the internal noop job works"
2006 A = self.fake_gerrit.addFakeChange('org/noop-project', 'master', 'A')
2007 A.addApproval('CRVW', 2)
2008 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2009 self.waitUntilSettled()
2010
2011 self.assertEqual(len(self.gearman_server.getQueue()), 0)
2012 self.assertTrue(self.sched._areAllBuildsComplete())
2013 self.assertEqual(len(self.history), 0)
2014 self.assertEqual(A.data['status'], 'MERGED')
2015 self.assertEqual(A.reported, 2)
2016
James E. Blairec056492016-07-22 09:45:56 -07002017 @skip("Disabled for early v3 development")
Evgeny Antyshevd6e546c2015-06-11 15:13:57 +00002018 def test_no_job_project(self):
2019 "Test that reports with no jobs don't get sent"
2020 A = self.fake_gerrit.addFakeChange('org/no-jobs-project',
2021 'master', 'A')
2022 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2023 self.waitUntilSettled()
2024
2025 # Change wasn't reported to
2026 self.assertEqual(A.reported, False)
2027
2028 # Check queue is empty afterwards
2029 check_pipeline = self.sched.layout.pipelines['check']
2030 items = check_pipeline.getAllItems()
2031 self.assertEqual(len(items), 0)
2032
2033 self.assertEqual(len(self.history), 0)
2034
James E. Blairec056492016-07-22 09:45:56 -07002035 @skip("Disabled for early v3 development")
James E. Blair7d0dedc2013-02-21 17:26:09 -08002036 def test_zuul_refs(self):
2037 "Test that zuul refs exist and have the right changes"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002038 self.worker.hold_jobs_in_build = True
James E. Blair7d0dedc2013-02-21 17:26:09 -08002039 M1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'M1')
2040 M1.setMerged()
2041 M2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'M2')
2042 M2.setMerged()
2043
2044 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2045 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2046 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
2047 D = self.fake_gerrit.addFakeChange('org/project2', 'master', 'D')
2048 A.addApproval('CRVW', 2)
2049 B.addApproval('CRVW', 2)
2050 C.addApproval('CRVW', 2)
2051 D.addApproval('CRVW', 2)
2052 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2053 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2054 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
2055 self.fake_gerrit.addEvent(D.addApproval('APRV', 1))
2056
2057 self.waitUntilSettled()
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002058 self.worker.release('.*-merge')
James E. Blair7d0dedc2013-02-21 17:26:09 -08002059 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()
2066
James E. Blair7d0dedc2013-02-21 17:26:09 -08002067 a_zref = b_zref = c_zref = d_zref = None
Monty Taylor6bef8ef2013-06-02 08:17:12 -04002068 for x in self.builds:
James E. Blair7d0dedc2013-02-21 17:26:09 -08002069 if x.parameters['ZUUL_CHANGE'] == '3':
2070 a_zref = x.parameters['ZUUL_REF']
2071 if x.parameters['ZUUL_CHANGE'] == '4':
2072 b_zref = x.parameters['ZUUL_REF']
2073 if x.parameters['ZUUL_CHANGE'] == '5':
2074 c_zref = x.parameters['ZUUL_REF']
2075 if x.parameters['ZUUL_CHANGE'] == '6':
2076 d_zref = x.parameters['ZUUL_REF']
2077
2078 # There are... four... refs.
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002079 self.assertIsNotNone(a_zref)
2080 self.assertIsNotNone(b_zref)
2081 self.assertIsNotNone(c_zref)
2082 self.assertIsNotNone(d_zref)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002083
2084 # And they should all be different
2085 refs = set([a_zref, b_zref, c_zref, d_zref])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002086 self.assertEqual(len(refs), 4)
James E. Blair7d0dedc2013-02-21 17:26:09 -08002087
2088 # a ref should have a, not b, and should not be in project2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002089 self.assertTrue(self.ref_has_change(a_zref, A))
2090 self.assertFalse(self.ref_has_change(a_zref, B))
2091 self.assertFalse(self.ref_has_change(a_zref, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002092
2093 # b ref should have a and b, and should not be in project2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002094 self.assertTrue(self.ref_has_change(b_zref, A))
2095 self.assertTrue(self.ref_has_change(b_zref, B))
2096 self.assertFalse(self.ref_has_change(b_zref, M2))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002097
2098 # c ref should have a and b in 1, c in 2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002099 self.assertTrue(self.ref_has_change(c_zref, A))
2100 self.assertTrue(self.ref_has_change(c_zref, B))
2101 self.assertTrue(self.ref_has_change(c_zref, C))
2102 self.assertFalse(self.ref_has_change(c_zref, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002103
2104 # d ref should have a and b in 1, c and d in 2
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002105 self.assertTrue(self.ref_has_change(d_zref, A))
2106 self.assertTrue(self.ref_has_change(d_zref, B))
2107 self.assertTrue(self.ref_has_change(d_zref, C))
2108 self.assertTrue(self.ref_has_change(d_zref, D))
James E. Blair7d0dedc2013-02-21 17:26:09 -08002109
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002110 self.worker.hold_jobs_in_build = False
2111 self.worker.release()
James E. Blair7d0dedc2013-02-21 17:26:09 -08002112 self.waitUntilSettled()
2113
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002114 self.assertEqual(A.data['status'], 'MERGED')
2115 self.assertEqual(A.reported, 2)
2116 self.assertEqual(B.data['status'], 'MERGED')
2117 self.assertEqual(B.reported, 2)
2118 self.assertEqual(C.data['status'], 'MERGED')
2119 self.assertEqual(C.reported, 2)
2120 self.assertEqual(D.data['status'], 'MERGED')
2121 self.assertEqual(D.reported, 2)
James E. Blair70c71582013-03-06 08:50:50 -08002122
James E. Blairec056492016-07-22 09:45:56 -07002123 @skip("Disabled for early v3 development")
James E. Blair4a28a882013-08-23 15:17:33 -07002124 def test_rerun_on_error(self):
2125 "Test that if a worker fails to run a job, it is run again"
2126 self.worker.hold_jobs_in_build = True
2127 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2128 A.addApproval('CRVW', 2)
2129 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2130 self.waitUntilSettled()
2131
2132 self.builds[0].run_error = True
2133 self.worker.hold_jobs_in_build = False
2134 self.worker.release()
2135 self.waitUntilSettled()
2136 self.assertEqual(self.countJobResults(self.history, 'RUN_ERROR'), 1)
2137 self.assertEqual(self.countJobResults(self.history, 'SUCCESS'), 3)
2138
James E. Blairec056492016-07-22 09:45:56 -07002139 @skip("Disabled for early v3 development")
James E. Blair412e5582013-04-22 15:50:12 -07002140 def test_statsd(self):
2141 "Test each of the statsd methods used in the scheduler"
2142 import extras
2143 statsd = extras.try_import('statsd.statsd')
2144 statsd.incr('test-incr')
2145 statsd.timing('test-timing', 3)
Alex Gaynor813d39b2014-05-17 16:17:16 -07002146 statsd.gauge('test-gauge', 12)
James E. Blair412e5582013-04-22 15:50:12 -07002147 self.assertReportedStat('test-incr', '1|c')
2148 self.assertReportedStat('test-timing', '3|ms')
Alex Gaynor813d39b2014-05-17 16:17:16 -07002149 self.assertReportedStat('test-gauge', '12|g')
James E. Blair412e5582013-04-22 15:50:12 -07002150
James E. Blairec056492016-07-22 09:45:56 -07002151 @skip("Disabled for early v3 development")
James E. Blairdad52252014-02-07 16:59:17 -08002152 def test_stuck_job_cleanup(self):
2153 "Test that pending jobs are cleaned up if removed from layout"
James E. Blair18c64442014-03-18 10:14:45 -07002154 # This job won't be registered at startup because it is not in
2155 # the standard layout, but we need it to already be registerd
2156 # for when we reconfigure, as that is when Zuul will attempt
2157 # to run the new job.
2158 self.worker.registerFunction('build:gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002159 self.gearman_server.hold_jobs_in_queue = True
2160 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2161 A.addApproval('CRVW', 2)
2162 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2163 self.waitUntilSettled()
2164 self.assertEqual(len(self.gearman_server.getQueue()), 1)
2165
James E. Blairf84026c2015-12-08 16:11:46 -08002166 self.updateConfigLayout(
2167 'tests/fixtures/layout-no-jobs.yaml')
James E. Blairdad52252014-02-07 16:59:17 -08002168 self.sched.reconfigure(self.config)
2169 self.waitUntilSettled()
2170
James E. Blair18c64442014-03-18 10:14:45 -07002171 self.gearman_server.release('gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002172 self.waitUntilSettled()
2173 self.assertEqual(len(self.gearman_server.getQueue()), 0)
2174 self.assertTrue(self.sched._areAllBuildsComplete())
2175
2176 self.assertEqual(len(self.history), 1)
James E. Blair18c64442014-03-18 10:14:45 -07002177 self.assertEqual(self.history[0].name, 'gate-noop')
James E. Blairdad52252014-02-07 16:59:17 -08002178 self.assertEqual(self.history[0].result, 'SUCCESS')
2179
James E. Blairec056492016-07-22 09:45:56 -07002180 @skip("Disabled for early v3 development")
James E. Blair879dafb2015-07-17 14:04:49 -07002181 def test_file_head(self):
2182 # This is a regression test for an observed bug. A change
2183 # with a file named "HEAD" in the root directory of the repo
2184 # was processed by a merger. It then was unable to reset the
2185 # repo because of:
2186 # GitCommandError: 'git reset --hard HEAD' returned
2187 # with exit code 128
2188 # stderr: 'fatal: ambiguous argument 'HEAD': both revision
2189 # and filename
2190 # Use '--' to separate filenames from revisions'
2191
2192 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2193 A.addPatchset(['HEAD'])
2194 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2195
2196 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
2197 self.waitUntilSettled()
2198
2199 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2200 self.waitUntilSettled()
2201
2202 self.assertIn('Build succeeded', A.messages[0])
2203 self.assertIn('Build succeeded', B.messages[0])
2204
James E. Blairec056492016-07-22 09:45:56 -07002205 @skip("Disabled for early v3 development")
James E. Blair70c71582013-03-06 08:50:50 -08002206 def test_file_jobs(self):
2207 "Test that file jobs run only when appropriate"
2208 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2209 A.addPatchset(['pip-requires'])
2210 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2211 A.addApproval('CRVW', 2)
2212 B.addApproval('CRVW', 2)
2213 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2214 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2215 self.waitUntilSettled()
2216
Monty Taylor6bef8ef2013-06-02 08:17:12 -04002217 testfile_jobs = [x for x in self.history
James E. Blair70c71582013-03-06 08:50:50 -08002218 if x.name == 'project-testfile']
2219
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002220 self.assertEqual(len(testfile_jobs), 1)
2221 self.assertEqual(testfile_jobs[0].changes, '1,2')
2222 self.assertEqual(A.data['status'], 'MERGED')
2223 self.assertEqual(A.reported, 2)
2224 self.assertEqual(B.data['status'], 'MERGED')
2225 self.assertEqual(B.reported, 2)
James E. Blair3c5e5b52013-04-26 11:17:03 -07002226
James E. Blairec056492016-07-22 09:45:56 -07002227 @skip("Disabled for early v3 development")
Maru Newby3fe5f852015-01-13 04:22:14 +00002228 def _test_skip_if_jobs(self, branch, should_skip):
2229 "Test that jobs with a skip-if filter run only when appropriate"
James E. Blairf84026c2015-12-08 16:11:46 -08002230 self.updateConfigLayout(
2231 'tests/fixtures/layout-skip-if.yaml')
Maru Newby3fe5f852015-01-13 04:22:14 +00002232 self.sched.reconfigure(self.config)
2233 self.registerJobs()
2234
2235 change = self.fake_gerrit.addFakeChange('org/project',
2236 branch,
2237 'test skip-if')
2238 self.fake_gerrit.addEvent(change.getPatchsetCreatedEvent(1))
2239 self.waitUntilSettled()
2240
2241 tested_change_ids = [x.changes[0] for x in self.history
2242 if x.name == 'project-test-skip-if']
2243
2244 if should_skip:
2245 self.assertEqual([], tested_change_ids)
2246 else:
2247 self.assertIn(change.data['number'], tested_change_ids)
2248
James E. Blairec056492016-07-22 09:45:56 -07002249 @skip("Disabled for early v3 development")
Maru Newby3fe5f852015-01-13 04:22:14 +00002250 def test_skip_if_match_skips_job(self):
2251 self._test_skip_if_jobs(branch='master', should_skip=True)
2252
James E. Blairec056492016-07-22 09:45:56 -07002253 @skip("Disabled for early v3 development")
Maru Newby3fe5f852015-01-13 04:22:14 +00002254 def test_skip_if_no_match_runs_job(self):
2255 self._test_skip_if_jobs(branch='mp', should_skip=False)
2256
James E. Blairec056492016-07-22 09:45:56 -07002257 @skip("Disabled for early v3 development")
James E. Blair3c5e5b52013-04-26 11:17:03 -07002258 def test_test_config(self):
2259 "Test that we can test the config"
James E. Blairf84026c2015-12-08 16:11:46 -08002260 self.sched.testConfig(self.config.get('zuul', 'tenant_config'),
Joshua Hesketh352264b2015-08-11 23:42:08 +10002261 self.connections)
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002262
James E. Blairec056492016-07-22 09:45:56 -07002263 @skip("Disabled for early v3 development")
James E. Blairc8a1e052014-02-25 09:29:26 -08002264 def test_queue_names(self):
2265 "Test shared change queue names"
2266 project1 = self.sched.layout.projects['org/project1']
2267 project2 = self.sched.layout.projects['org/project2']
2268 q1 = self.sched.layout.pipelines['gate'].getQueue(project1)
2269 q2 = self.sched.layout.pipelines['gate'].getQueue(project2)
2270 self.assertEqual(q1.name, 'integration')
2271 self.assertEqual(q2.name, 'integration')
2272
James E. Blairf84026c2015-12-08 16:11:46 -08002273 self.updateConfigLayout(
2274 'tests/fixtures/layout-bad-queue.yaml')
James E. Blairc8a1e052014-02-25 09:29:26 -08002275 with testtools.ExpectedException(
2276 Exception, "More than one name assigned to change queue"):
2277 self.sched.reconfigure(self.config)
2278
James E. Blairec056492016-07-22 09:45:56 -07002279 @skip("Disabled for early v3 development")
James E. Blair64ed6f22013-07-10 14:07:23 -07002280 def test_queue_precedence(self):
2281 "Test that queue precedence works"
2282
2283 self.gearman_server.hold_jobs_in_queue = True
James E. Blair8de58bd2013-07-18 16:23:33 -07002284 self.worker.hold_jobs_in_build = True
James E. Blair64ed6f22013-07-10 14:07:23 -07002285 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2286 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2287 A.addApproval('CRVW', 2)
2288 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2289
2290 self.waitUntilSettled()
2291 self.gearman_server.hold_jobs_in_queue = False
2292 self.gearman_server.release()
2293 self.waitUntilSettled()
2294
James E. Blair8de58bd2013-07-18 16:23:33 -07002295 # Run one build at a time to ensure non-race order:
James E. Blairb8c16472015-05-05 14:55:26 -07002296 self.orderedRelease()
James E. Blair8de58bd2013-07-18 16:23:33 -07002297 self.worker.hold_jobs_in_build = False
2298 self.waitUntilSettled()
2299
James E. Blair64ed6f22013-07-10 14:07:23 -07002300 self.log.debug(self.history)
2301 self.assertEqual(self.history[0].pipeline, 'gate')
2302 self.assertEqual(self.history[1].pipeline, 'check')
2303 self.assertEqual(self.history[2].pipeline, 'gate')
2304 self.assertEqual(self.history[3].pipeline, 'gate')
2305 self.assertEqual(self.history[4].pipeline, 'check')
2306 self.assertEqual(self.history[5].pipeline, 'check')
2307
James E. Blairec056492016-07-22 09:45:56 -07002308 @skip("Disabled for early v3 development")
Clark Boylana5edbe42014-06-03 16:39:10 -07002309 def test_json_status(self):
James E. Blair1843a552013-07-03 14:19:52 -07002310 "Test that we can retrieve JSON status info"
2311 self.worker.hold_jobs_in_build = True
2312 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2313 A.addApproval('CRVW', 2)
2314 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2315 self.waitUntilSettled()
2316
James E. Blairb7273ef2016-04-19 08:58:51 -07002317 self.worker.release('project-merge')
2318 self.waitUntilSettled()
2319
James E. Blair1843a552013-07-03 14:19:52 -07002320 port = self.webapp.server.socket.getsockname()[1]
2321
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002322 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2323 f = urllib.request.urlopen(req)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002324 headers = f.info()
2325 self.assertIn('Content-Length', headers)
2326 self.assertIn('Content-Type', headers)
Sachi Kingdc963fc2016-03-23 16:00:33 +11002327 self.assertIsNotNone(re.match('^application/json(; charset=UTF-8)?$',
2328 headers['Content-Type']))
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002329 self.assertIn('Access-Control-Allow-Origin', headers)
2330 self.assertIn('Cache-Control', headers)
Clark Boylanaa4f2e72014-06-03 21:22:40 -07002331 self.assertIn('Last-Modified', headers)
Timo Tijhof0ebd2932015-04-02 12:11:21 +01002332 self.assertIn('Expires', headers)
James E. Blair1843a552013-07-03 14:19:52 -07002333 data = f.read()
2334
2335 self.worker.hold_jobs_in_build = False
2336 self.worker.release()
2337 self.waitUntilSettled()
2338
2339 data = json.loads(data)
James E. Blairb7273ef2016-04-19 08:58:51 -07002340 status_jobs = []
James E. Blair1843a552013-07-03 14:19:52 -07002341 for p in data['pipelines']:
2342 for q in p['change_queues']:
James E. Blairbfb8e042014-12-30 17:01:44 -08002343 if p['name'] in ['gate', 'conflict']:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002344 self.assertEqual(q['window'], 20)
2345 else:
2346 self.assertEqual(q['window'], 0)
James E. Blair1843a552013-07-03 14:19:52 -07002347 for head in q['heads']:
2348 for change in head:
Clark Boylanaf2476f2014-01-23 14:47:36 -08002349 self.assertTrue(change['active'])
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002350 self.assertEqual(change['id'], '1,1')
James E. Blair1843a552013-07-03 14:19:52 -07002351 for job in change['jobs']:
James E. Blairb7273ef2016-04-19 08:58:51 -07002352 status_jobs.append(job)
2353 self.assertEqual('project-merge', status_jobs[0]['name'])
2354 self.assertEqual('https://server/job/project-merge/0/',
2355 status_jobs[0]['url'])
2356 self.assertEqual('http://logs.example.com/1/1/gate/project-merge/0',
2357 status_jobs[0]['report_url'])
2358
2359 self.assertEqual('project-test1', status_jobs[1]['name'])
2360 self.assertEqual('https://server/job/project-test1/1/',
2361 status_jobs[1]['url'])
2362 self.assertEqual('http://logs.example.com/1/1/gate/project-test1/1',
2363 status_jobs[1]['report_url'])
2364
2365 self.assertEqual('project-test2', status_jobs[2]['name'])
2366 self.assertEqual('https://server/job/project-test2/2/',
2367 status_jobs[2]['url'])
2368 self.assertEqual('http://logs.example.com/1/1/gate/project-test2/2',
2369 status_jobs[2]['report_url'])
James E. Blair1843a552013-07-03 14:19:52 -07002370
James E. Blairec056492016-07-22 09:45:56 -07002371 @skip("Disabled for early v3 development")
James E. Blairc3d428e2013-12-03 15:06:48 -08002372 def test_merging_queues(self):
2373 "Test that transitively-connected change queues are merged"
James E. Blairf84026c2015-12-08 16:11:46 -08002374 self.updateConfigLayout(
2375 'tests/fixtures/layout-merge-queues.yaml')
James E. Blairc3d428e2013-12-03 15:06:48 -08002376 self.sched.reconfigure(self.config)
2377 self.assertEqual(len(self.sched.layout.pipelines['gate'].queues), 1)
2378
James E. Blairec056492016-07-22 09:45:56 -07002379 @skip("Disabled for early v3 development")
James E. Blairaf17a972016-02-03 15:07:18 -08002380 def test_mutex(self):
2381 "Test job mutexes"
2382 self.config.set('zuul', 'layout_config',
2383 'tests/fixtures/layout-mutex.yaml')
2384 self.sched.reconfigure(self.config)
2385
2386 self.worker.hold_jobs_in_build = True
2387 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2388 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2389 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2390
2391 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2392 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2393 self.waitUntilSettled()
2394 self.assertEqual(len(self.builds), 3)
2395 self.assertEqual(self.builds[0].name, 'project-test1')
2396 self.assertEqual(self.builds[1].name, 'mutex-one')
2397 self.assertEqual(self.builds[2].name, 'project-test1')
2398
2399 self.worker.release('mutex-one')
2400 self.waitUntilSettled()
2401
2402 self.assertEqual(len(self.builds), 3)
2403 self.assertEqual(self.builds[0].name, 'project-test1')
2404 self.assertEqual(self.builds[1].name, 'project-test1')
2405 self.assertEqual(self.builds[2].name, 'mutex-two')
2406 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2407
2408 self.worker.release('mutex-two')
2409 self.waitUntilSettled()
2410
2411 self.assertEqual(len(self.builds), 3)
2412 self.assertEqual(self.builds[0].name, 'project-test1')
2413 self.assertEqual(self.builds[1].name, 'project-test1')
2414 self.assertEqual(self.builds[2].name, 'mutex-one')
2415 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2416
2417 self.worker.release('mutex-one')
2418 self.waitUntilSettled()
2419
2420 self.assertEqual(len(self.builds), 3)
2421 self.assertEqual(self.builds[0].name, 'project-test1')
2422 self.assertEqual(self.builds[1].name, 'project-test1')
2423 self.assertEqual(self.builds[2].name, 'mutex-two')
2424 self.assertTrue('test-mutex' in self.sched.mutex.mutexes)
2425
2426 self.worker.release('mutex-two')
2427 self.waitUntilSettled()
2428
2429 self.assertEqual(len(self.builds), 2)
2430 self.assertEqual(self.builds[0].name, 'project-test1')
2431 self.assertEqual(self.builds[1].name, 'project-test1')
2432 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2433
2434 self.worker.hold_jobs_in_build = False
2435 self.worker.release()
2436
2437 self.waitUntilSettled()
2438 self.assertEqual(len(self.builds), 0)
2439
2440 self.assertEqual(A.reported, 1)
2441 self.assertEqual(B.reported, 1)
2442 self.assertFalse('test-mutex' in self.sched.mutex.mutexes)
2443
James E. Blairec056492016-07-22 09:45:56 -07002444 @skip("Disabled for early v3 development")
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002445 def test_node_label(self):
2446 "Test that a job runs on a specific node label"
James E. Blair1f4c2bb2013-04-26 08:40:46 -07002447 self.worker.registerFunction('build:node-project-test1:debian')
2448
2449 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
2450 A.addApproval('CRVW', 2)
2451 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2452 self.waitUntilSettled()
James E. Blair4ca985f2013-05-30 12:27:43 -07002453
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002454 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2455 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2456 'debian')
2457 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
James E. Blaircdccd972013-07-01 12:10:22 -07002458
James E. Blairec056492016-07-22 09:45:56 -07002459 @skip("Disabled for early v3 development")
James E. Blaircdccd972013-07-01 12:10:22 -07002460 def test_live_reconfiguration(self):
2461 "Test that live reconfiguration works"
2462 self.worker.hold_jobs_in_build = True
2463 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2464 A.addApproval('CRVW', 2)
2465 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2466 self.waitUntilSettled()
2467
2468 self.sched.reconfigure(self.config)
2469
2470 self.worker.hold_jobs_in_build = False
2471 self.worker.release()
2472 self.waitUntilSettled()
Monty Taylor98f0f3e2013-07-06 16:02:31 -04002473 self.assertEqual(self.getJobFromHistory('project-merge').result,
2474 'SUCCESS')
2475 self.assertEqual(self.getJobFromHistory('project-test1').result,
2476 'SUCCESS')
2477 self.assertEqual(self.getJobFromHistory('project-test2').result,
2478 'SUCCESS')
2479 self.assertEqual(A.data['status'], 'MERGED')
2480 self.assertEqual(A.reported, 2)
James E. Blair287c06d2013-07-24 10:39:30 -07002481
James E. Blairec056492016-07-22 09:45:56 -07002482 @skip("Disabled for early v3 development")
James E. Blair6bc782d2015-07-17 16:20:21 -07002483 def test_live_reconfiguration_merge_conflict(self):
2484 # A real-world bug: a change in a gate queue has a merge
2485 # conflict and a job is added to its project while it's
2486 # sitting in the queue. The job gets added to the change and
2487 # enqueued and the change gets stuck.
2488 self.worker.registerFunction('build:project-test3')
2489 self.worker.hold_jobs_in_build = True
2490
2491 # This change is fine. It's here to stop the queue long
2492 # enough for the next change to be subject to the
2493 # reconfiguration, as well as to provide a conflict for the
2494 # next change. This change will succeed and merge.
2495 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2496 A.addPatchset(['conflict'])
2497 A.addApproval('CRVW', 2)
James E. Blair6bc782d2015-07-17 16:20:21 -07002498
2499 # This change will be in merge conflict. During the
2500 # reconfiguration, we will add a job. We want to make sure
2501 # that doesn't cause it to get stuck.
2502 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2503 B.addPatchset(['conflict'])
2504 B.addApproval('CRVW', 2)
James E. Blair4eb21fa2015-07-27 14:56:47 -07002505
2506 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
James E. Blair6bc782d2015-07-17 16:20:21 -07002507 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2508
2509 self.waitUntilSettled()
2510
2511 # No jobs have run yet
2512 self.assertEqual(A.data['status'], 'NEW')
2513 self.assertEqual(A.reported, 1)
2514 self.assertEqual(B.data['status'], 'NEW')
2515 self.assertEqual(B.reported, 1)
2516 self.assertEqual(len(self.history), 0)
2517
2518 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002519 self.updateConfigLayout(
2520 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002521 self.sched.reconfigure(self.config)
2522 self.waitUntilSettled()
2523
2524 self.worker.hold_jobs_in_build = False
2525 self.worker.release()
2526 self.waitUntilSettled()
2527
2528 self.assertEqual(A.data['status'], 'MERGED')
2529 self.assertEqual(A.reported, 2)
2530 self.assertEqual(B.data['status'], 'NEW')
2531 self.assertEqual(B.reported, 2)
2532 self.assertEqual(self.getJobFromHistory('project-merge').result,
2533 'SUCCESS')
2534 self.assertEqual(self.getJobFromHistory('project-test1').result,
2535 'SUCCESS')
2536 self.assertEqual(self.getJobFromHistory('project-test2').result,
2537 'SUCCESS')
2538 self.assertEqual(self.getJobFromHistory('project-test3').result,
2539 'SUCCESS')
2540 self.assertEqual(len(self.history), 4)
2541
James E. Blairec056492016-07-22 09:45:56 -07002542 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002543 def test_live_reconfiguration_failed_root(self):
James E. Blair6bc782d2015-07-17 16:20:21 -07002544 # An extrapolation of test_live_reconfiguration_merge_conflict
2545 # that tests a job added to a job tree with a failed root does
2546 # not run.
2547 self.worker.registerFunction('build:project-test3')
2548 self.worker.hold_jobs_in_build = True
2549
2550 # This change is fine. It's here to stop the queue long
2551 # enough for the next change to be subject to the
2552 # reconfiguration. This change will succeed and merge.
2553 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2554 A.addPatchset(['conflict'])
2555 A.addApproval('CRVW', 2)
2556 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2557 self.waitUntilSettled()
2558 self.worker.release('.*-merge')
2559 self.waitUntilSettled()
2560
2561 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
2562 self.worker.addFailTest('project-merge', B)
2563 B.addApproval('CRVW', 2)
2564 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2565 self.waitUntilSettled()
2566
2567 self.worker.release('.*-merge')
2568 self.waitUntilSettled()
2569
2570 # Both -merge jobs have run, but no others.
2571 self.assertEqual(A.data['status'], 'NEW')
2572 self.assertEqual(A.reported, 1)
2573 self.assertEqual(B.data['status'], 'NEW')
2574 self.assertEqual(B.reported, 1)
2575 self.assertEqual(self.history[0].result, 'SUCCESS')
2576 self.assertEqual(self.history[0].name, 'project-merge')
2577 self.assertEqual(self.history[1].result, 'FAILURE')
2578 self.assertEqual(self.history[1].name, 'project-merge')
2579 self.assertEqual(len(self.history), 2)
2580
2581 # Add the "project-test3" job.
James E. Blairf84026c2015-12-08 16:11:46 -08002582 self.updateConfigLayout(
2583 'tests/fixtures/layout-live-reconfiguration-add-job.yaml')
James E. Blair6bc782d2015-07-17 16:20:21 -07002584 self.sched.reconfigure(self.config)
2585 self.waitUntilSettled()
2586
2587 self.worker.hold_jobs_in_build = False
2588 self.worker.release()
2589 self.waitUntilSettled()
2590
2591 self.assertEqual(A.data['status'], 'MERGED')
2592 self.assertEqual(A.reported, 2)
2593 self.assertEqual(B.data['status'], 'NEW')
2594 self.assertEqual(B.reported, 2)
2595 self.assertEqual(self.history[0].result, 'SUCCESS')
2596 self.assertEqual(self.history[0].name, 'project-merge')
2597 self.assertEqual(self.history[1].result, 'FAILURE')
2598 self.assertEqual(self.history[1].name, 'project-merge')
2599 self.assertEqual(self.history[2].result, 'SUCCESS')
2600 self.assertEqual(self.history[3].result, 'SUCCESS')
2601 self.assertEqual(self.history[4].result, 'SUCCESS')
2602 self.assertEqual(len(self.history), 5)
2603
James E. Blairec056492016-07-22 09:45:56 -07002604 @skip("Disabled for early v3 development")
James E. Blair400e8fd2015-07-30 17:44:45 -07002605 def test_live_reconfiguration_failed_job(self):
2606 # Test that a change with a removed failing job does not
2607 # disrupt reconfiguration. If a change has a failed job and
2608 # that job is removed during a reconfiguration, we observed a
2609 # bug where the code to re-set build statuses would run on
2610 # that build and raise an exception because the job no longer
2611 # existed.
2612 self.worker.hold_jobs_in_build = True
2613
2614 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2615
2616 # This change will fail and later be removed by the reconfiguration.
2617 self.worker.addFailTest('project-test1', A)
2618
2619 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2620 self.waitUntilSettled()
2621 self.worker.release('.*-merge')
2622 self.waitUntilSettled()
2623 self.worker.release('project-test1')
2624 self.waitUntilSettled()
2625
2626 self.assertEqual(A.data['status'], 'NEW')
2627 self.assertEqual(A.reported, 0)
2628
2629 self.assertEqual(self.getJobFromHistory('project-merge').result,
2630 'SUCCESS')
2631 self.assertEqual(self.getJobFromHistory('project-test1').result,
2632 'FAILURE')
2633 self.assertEqual(len(self.history), 2)
2634
2635 # Remove the test1 job.
James E. Blairf84026c2015-12-08 16:11:46 -08002636 self.updateConfigLayout(
2637 'tests/fixtures/layout-live-reconfiguration-failed-job.yaml')
James E. Blair400e8fd2015-07-30 17:44:45 -07002638 self.sched.reconfigure(self.config)
2639 self.waitUntilSettled()
2640
2641 self.worker.hold_jobs_in_build = False
2642 self.worker.release()
2643 self.waitUntilSettled()
2644
2645 self.assertEqual(self.getJobFromHistory('project-test2').result,
2646 'SUCCESS')
2647 self.assertEqual(self.getJobFromHistory('project-testfile').result,
2648 'SUCCESS')
2649 self.assertEqual(len(self.history), 4)
2650
2651 self.assertEqual(A.data['status'], 'NEW')
2652 self.assertEqual(A.reported, 1)
2653 self.assertIn('Build succeeded', A.messages[0])
2654 # Ensure the removed job was not included in the report.
2655 self.assertNotIn('project-test1', A.messages[0])
2656
James E. Blairec056492016-07-22 09:45:56 -07002657 @skip("Disabled for early v3 development")
James E. Blairfe707d12015-08-05 15:18:15 -07002658 def test_live_reconfiguration_shared_queue(self):
2659 # Test that a change with a failing job which was removed from
2660 # this project but otherwise still exists in the system does
2661 # not disrupt reconfiguration.
2662
2663 self.worker.hold_jobs_in_build = True
2664
2665 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2666
2667 self.worker.addFailTest('project1-project2-integration', A)
2668
2669 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2670 self.waitUntilSettled()
2671 self.worker.release('.*-merge')
2672 self.waitUntilSettled()
2673 self.worker.release('project1-project2-integration')
2674 self.waitUntilSettled()
2675
2676 self.assertEqual(A.data['status'], 'NEW')
2677 self.assertEqual(A.reported, 0)
2678
2679 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2680 'SUCCESS')
2681 self.assertEqual(self.getJobFromHistory(
2682 'project1-project2-integration').result, 'FAILURE')
2683 self.assertEqual(len(self.history), 2)
2684
2685 # Remove the integration job.
James E. Blairf84026c2015-12-08 16:11:46 -08002686 self.updateConfigLayout(
2687 'tests/fixtures/layout-live-reconfiguration-shared-queue.yaml')
James E. Blairfe707d12015-08-05 15:18:15 -07002688 self.sched.reconfigure(self.config)
2689 self.waitUntilSettled()
2690
2691 self.worker.hold_jobs_in_build = False
2692 self.worker.release()
2693 self.waitUntilSettled()
2694
2695 self.assertEqual(self.getJobFromHistory('project1-merge').result,
2696 'SUCCESS')
2697 self.assertEqual(self.getJobFromHistory('project1-test1').result,
2698 'SUCCESS')
2699 self.assertEqual(self.getJobFromHistory('project1-test2').result,
2700 'SUCCESS')
2701 self.assertEqual(self.getJobFromHistory(
2702 'project1-project2-integration').result, 'FAILURE')
2703 self.assertEqual(len(self.history), 4)
2704
2705 self.assertEqual(A.data['status'], 'NEW')
2706 self.assertEqual(A.reported, 1)
2707 self.assertIn('Build succeeded', A.messages[0])
2708 # Ensure the removed job was not included in the report.
2709 self.assertNotIn('project1-project2-integration', A.messages[0])
2710
James E. Blairec056492016-07-22 09:45:56 -07002711 @skip("Disabled for early v3 development")
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11002712 def test_double_live_reconfiguration_shared_queue(self):
2713 # This was a real-world regression. A change is added to
2714 # gate; a reconfigure happens, a second change which depends
2715 # on the first is added, and a second reconfiguration happens.
2716 # Ensure that both changes merge.
2717
2718 # A failure may indicate incorrect caching or cleaning up of
2719 # references during a reconfiguration.
2720 self.worker.hold_jobs_in_build = True
2721
2722 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2723 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2724 B.setDependsOn(A, 1)
2725 A.addApproval('CRVW', 2)
2726 B.addApproval('CRVW', 2)
2727
2728 # Add the parent change.
2729 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2730 self.waitUntilSettled()
2731 self.worker.release('.*-merge')
2732 self.waitUntilSettled()
2733
2734 # Reconfigure (with only one change in the pipeline).
2735 self.sched.reconfigure(self.config)
2736 self.waitUntilSettled()
2737
2738 # Add the child change.
2739 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2740 self.waitUntilSettled()
2741 self.worker.release('.*-merge')
2742 self.waitUntilSettled()
2743
2744 # Reconfigure (with both in the pipeline).
2745 self.sched.reconfigure(self.config)
2746 self.waitUntilSettled()
2747
2748 self.worker.hold_jobs_in_build = False
2749 self.worker.release()
2750 self.waitUntilSettled()
2751
2752 self.assertEqual(len(self.history), 8)
2753
2754 self.assertEqual(A.data['status'], 'MERGED')
2755 self.assertEqual(A.reported, 2)
2756 self.assertEqual(B.data['status'], 'MERGED')
2757 self.assertEqual(B.reported, 2)
2758
James E. Blairec056492016-07-22 09:45:56 -07002759 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002760 def test_live_reconfiguration_del_project(self):
2761 # Test project deletion from layout
2762 # while changes are enqueued
2763
2764 self.worker.hold_jobs_in_build = True
2765 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
2766 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
2767 C = self.fake_gerrit.addFakeChange('org/project1', 'master', 'C')
2768
2769 # A Depends-On: B
2770 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
2771 A.subject, B.data['id'])
2772 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2773
2774 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2775 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
2776 self.waitUntilSettled()
2777 self.worker.release('.*-merge')
2778 self.waitUntilSettled()
2779 self.assertEqual(len(self.builds), 5)
2780
2781 # This layout defines only org/project, not org/project1
James E. Blairf84026c2015-12-08 16:11:46 -08002782 self.updateConfigLayout(
2783 'tests/fixtures/layout-live-reconfiguration-del-project.yaml')
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00002784 self.sched.reconfigure(self.config)
2785 self.waitUntilSettled()
2786
2787 # Builds for C aborted, builds for A succeed,
2788 # and have change B applied ahead
2789 job_c = self.getJobFromHistory('project1-test1')
2790 self.assertEqual(job_c.changes, '3,1')
2791 self.assertEqual(job_c.result, 'ABORTED')
2792
2793 self.worker.hold_jobs_in_build = False
2794 self.worker.release()
2795 self.waitUntilSettled()
2796
2797 self.assertEqual(self.getJobFromHistory('project-test1').changes,
2798 '2,1 1,1')
2799
2800 self.assertEqual(A.data['status'], 'NEW')
2801 self.assertEqual(B.data['status'], 'NEW')
2802 self.assertEqual(C.data['status'], 'NEW')
2803 self.assertEqual(A.reported, 1)
2804 self.assertEqual(B.reported, 0)
2805 self.assertEqual(C.reported, 0)
2806
2807 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
2808 self.assertIn('Build succeeded', A.messages[0])
2809
James E. Blairec056492016-07-22 09:45:56 -07002810 @skip("Disabled for early v3 development")
James E. Blaire712d9f2013-07-31 11:40:11 -07002811 def test_live_reconfiguration_functions(self):
2812 "Test live reconfiguration with a custom function"
2813 self.worker.registerFunction('build:node-project-test1:debian')
2814 self.worker.registerFunction('build:node-project-test1:wheezy')
2815 A = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'A')
2816 A.addApproval('CRVW', 2)
2817 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2818 self.waitUntilSettled()
2819
2820 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2821 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2822 'debian')
2823 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2824
James E. Blairf84026c2015-12-08 16:11:46 -08002825 self.updateConfigLayout(
2826 'tests/fixtures/layout-live-reconfiguration-functions.yaml')
James E. Blaire712d9f2013-07-31 11:40:11 -07002827 self.sched.reconfigure(self.config)
2828 self.worker.build_history = []
2829
2830 B = self.fake_gerrit.addFakeChange('org/node-project', 'master', 'B')
2831 B.addApproval('CRVW', 2)
2832 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2833 self.waitUntilSettled()
2834
2835 self.assertIsNone(self.getJobFromHistory('node-project-merge').node)
2836 self.assertEqual(self.getJobFromHistory('node-project-test1').node,
2837 'wheezy')
2838 self.assertIsNone(self.getJobFromHistory('node-project-test2').node)
2839
James E. Blairec056492016-07-22 09:45:56 -07002840 @skip("Disabled for early v3 development")
James E. Blair287c06d2013-07-24 10:39:30 -07002841 def test_delayed_repo_init(self):
James E. Blairf84026c2015-12-08 16:11:46 -08002842 self.updateConfigLayout(
2843 'tests/fixtures/layout-delayed-repo-init.yaml')
James E. Blair287c06d2013-07-24 10:39:30 -07002844 self.sched.reconfigure(self.config)
2845
2846 self.init_repo("org/new-project")
2847 A = self.fake_gerrit.addFakeChange('org/new-project', 'master', 'A')
2848
2849 A.addApproval('CRVW', 2)
2850 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2851 self.waitUntilSettled()
2852 self.assertEqual(self.getJobFromHistory('project-merge').result,
2853 'SUCCESS')
2854 self.assertEqual(self.getJobFromHistory('project-test1').result,
2855 'SUCCESS')
2856 self.assertEqual(self.getJobFromHistory('project-test2').result,
2857 'SUCCESS')
2858 self.assertEqual(A.data['status'], 'MERGED')
2859 self.assertEqual(A.reported, 2)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002860
James E. Blairec056492016-07-22 09:45:56 -07002861 @skip("Disabled for early v3 development")
Clark Boylan6dbbc482013-10-18 10:57:31 -07002862 def test_repo_deleted(self):
James E. Blairf84026c2015-12-08 16:11:46 -08002863 self.updateConfigLayout(
2864 'tests/fixtures/layout-repo-deleted.yaml')
Clark Boylan6dbbc482013-10-18 10:57:31 -07002865 self.sched.reconfigure(self.config)
2866
2867 self.init_repo("org/delete-project")
2868 A = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'A')
2869
2870 A.addApproval('CRVW', 2)
2871 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
2872 self.waitUntilSettled()
2873 self.assertEqual(self.getJobFromHistory('project-merge').result,
2874 'SUCCESS')
2875 self.assertEqual(self.getJobFromHistory('project-test1').result,
2876 'SUCCESS')
2877 self.assertEqual(self.getJobFromHistory('project-test2').result,
2878 'SUCCESS')
2879 self.assertEqual(A.data['status'], 'MERGED')
2880 self.assertEqual(A.reported, 2)
2881
2882 # Delete org/new-project zuul repo. Should be recloned.
2883 shutil.rmtree(os.path.join(self.git_root, "org/delete-project"))
2884
2885 B = self.fake_gerrit.addFakeChange('org/delete-project', 'master', 'B')
2886
2887 B.addApproval('CRVW', 2)
2888 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
2889 self.waitUntilSettled()
2890 self.assertEqual(self.getJobFromHistory('project-merge').result,
2891 'SUCCESS')
2892 self.assertEqual(self.getJobFromHistory('project-test1').result,
2893 'SUCCESS')
2894 self.assertEqual(self.getJobFromHistory('project-test2').result,
2895 'SUCCESS')
2896 self.assertEqual(B.data['status'], 'MERGED')
2897 self.assertEqual(B.reported, 2)
2898
James E. Blairec056492016-07-22 09:45:56 -07002899 @skip("Disabled for early v3 development")
James E. Blair456f2fb2016-02-09 09:29:33 -08002900 def test_tags(self):
2901 "Test job tags"
2902 self.config.set('zuul', 'layout_config',
2903 'tests/fixtures/layout-tags.yaml')
2904 self.sched.reconfigure(self.config)
2905
2906 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
2907 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
2908 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
2909 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
2910 self.waitUntilSettled()
2911
2912 results = {'project1-merge': 'extratag merge project1',
2913 'project2-merge': 'merge'}
2914
2915 for build in self.history:
2916 self.assertEqual(results.get(build.name, ''),
2917 build.parameters.get('BUILD_TAGS'))
2918
James E. Blairec056492016-07-22 09:45:56 -07002919 @skip("Disabled for early v3 development")
James E. Blair63bb0ef2013-07-29 17:14:51 -07002920 def test_timer(self):
2921 "Test that a periodic job is triggered"
2922 self.worker.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08002923 self.updateConfigLayout(
2924 'tests/fixtures/layout-timer.yaml')
James E. Blair63bb0ef2013-07-29 17:14:51 -07002925 self.sched.reconfigure(self.config)
2926 self.registerJobs()
2927
Clark Boylan3ee090a2014-04-03 20:55:09 -07002928 # The pipeline triggers every second, so we should have seen
2929 # several by now.
2930 time.sleep(5)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002931 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002932
2933 self.assertEqual(len(self.builds), 2)
2934
James E. Blair63bb0ef2013-07-29 17:14:51 -07002935 port = self.webapp.server.socket.getsockname()[1]
2936
Morgan Fainberg293f7f82016-05-30 14:01:22 -07002937 req = urllib.request.Request("http://localhost:%s/status.json" % port)
2938 f = urllib.request.urlopen(req)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002939 data = f.read()
2940
2941 self.worker.hold_jobs_in_build = False
Clark Boylan3ee090a2014-04-03 20:55:09 -07002942 # Stop queuing timer triggered jobs so that the assertions
2943 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08002944 self.updateConfigLayout(
2945 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002946 self.sched.reconfigure(self.config)
2947 self.registerJobs()
James E. Blair63bb0ef2013-07-29 17:14:51 -07002948 self.worker.release()
2949 self.waitUntilSettled()
2950
2951 self.assertEqual(self.getJobFromHistory(
2952 'project-bitrot-stable-old').result, 'SUCCESS')
2953 self.assertEqual(self.getJobFromHistory(
2954 'project-bitrot-stable-older').result, 'SUCCESS')
2955
2956 data = json.loads(data)
2957 status_jobs = set()
2958 for p in data['pipelines']:
2959 for q in p['change_queues']:
2960 for head in q['heads']:
2961 for change in head:
Alex Gaynorddb9ef32013-09-16 21:04:58 -07002962 self.assertEqual(change['id'], None)
James E. Blair63bb0ef2013-07-29 17:14:51 -07002963 for job in change['jobs']:
2964 status_jobs.add(job['name'])
2965 self.assertIn('project-bitrot-stable-old', status_jobs)
2966 self.assertIn('project-bitrot-stable-older', status_jobs)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10002967
James E. Blairec056492016-07-22 09:45:56 -07002968 @skip("Disabled for early v3 development")
James E. Blair4f6033c2014-03-27 15:49:09 -07002969 def test_idle(self):
2970 "Test that frequent periodic jobs work"
2971 self.worker.hold_jobs_in_build = True
James E. Blair4f6033c2014-03-27 15:49:09 -07002972
Clark Boylan3ee090a2014-04-03 20:55:09 -07002973 for x in range(1, 3):
2974 # Test that timer triggers periodic jobs even across
2975 # layout config reloads.
2976 # Start timer trigger
James E. Blairf84026c2015-12-08 16:11:46 -08002977 self.updateConfigLayout(
2978 'tests/fixtures/layout-idle.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002979 self.sched.reconfigure(self.config)
2980 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08002981 self.waitUntilSettled()
James E. Blair4f6033c2014-03-27 15:49:09 -07002982
Clark Boylan3ee090a2014-04-03 20:55:09 -07002983 # The pipeline triggers every second, so we should have seen
2984 # several by now.
2985 time.sleep(5)
Clark Boylan3ee090a2014-04-03 20:55:09 -07002986
2987 # Stop queuing timer triggered jobs so that the assertions
2988 # below don't race against more jobs being queued.
James E. Blairf84026c2015-12-08 16:11:46 -08002989 self.updateConfigLayout(
2990 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07002991 self.sched.reconfigure(self.config)
2992 self.registerJobs()
James E. Blair995fc0f2016-02-04 16:48:31 -08002993 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07002994
2995 self.assertEqual(len(self.builds), 2)
2996 self.worker.release('.*')
2997 self.waitUntilSettled()
2998 self.assertEqual(len(self.builds), 0)
2999 self.assertEqual(len(self.history), x * 2)
James E. Blair4f6033c2014-03-27 15:49:09 -07003000
James E. Blairec056492016-07-22 09:45:56 -07003001 @skip("Disabled for early v3 development")
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003002 def test_check_smtp_pool(self):
James E. Blairf84026c2015-12-08 16:11:46 -08003003 self.updateConfigLayout(
3004 'tests/fixtures/layout-smtp.yaml')
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003005 self.sched.reconfigure(self.config)
3006
3007 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3008 self.waitUntilSettled()
3009
3010 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
3011 self.waitUntilSettled()
3012
James E. Blairff80a2f2013-12-27 13:24:06 -08003013 self.assertEqual(len(self.smtp_messages), 2)
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003014
3015 # A.messages only holds what FakeGerrit places in it. Thus we
3016 # work on the knowledge of what the first message should be as
3017 # it is only configured to go to SMTP.
3018
3019 self.assertEqual('zuul@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003020 self.smtp_messages[0]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003021 self.assertEqual(['you@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003022 self.smtp_messages[0]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003023 self.assertEqual('Starting check jobs.',
James E. Blairff80a2f2013-12-27 13:24:06 -08003024 self.smtp_messages[0]['body'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003025
3026 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003027 self.smtp_messages[1]['from_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003028 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003029 self.smtp_messages[1]['to_email'])
Joshua Hesketh5fea8672013-08-19 17:32:01 +10003030 self.assertEqual(A.messages[0],
James E. Blairff80a2f2013-12-27 13:24:06 -08003031 self.smtp_messages[1]['body'])
James E. Blairad28e912013-11-27 10:43:22 -08003032
James E. Blairec056492016-07-22 09:45:56 -07003033 @skip("Disabled for early v3 development")
James E. Blaire5910202013-12-27 09:50:31 -08003034 def test_timer_smtp(self):
3035 "Test that a periodic job is triggered"
Clark Boylan3ee090a2014-04-03 20:55:09 -07003036 self.worker.hold_jobs_in_build = True
James E. Blairf84026c2015-12-08 16:11:46 -08003037 self.updateConfigLayout(
3038 'tests/fixtures/layout-timer-smtp.yaml')
James E. Blaire5910202013-12-27 09:50:31 -08003039 self.sched.reconfigure(self.config)
3040 self.registerJobs()
3041
Clark Boylan3ee090a2014-04-03 20:55:09 -07003042 # The pipeline triggers every second, so we should have seen
3043 # several by now.
3044 time.sleep(5)
James E. Blaire5910202013-12-27 09:50:31 -08003045 self.waitUntilSettled()
3046
Clark Boylan3ee090a2014-04-03 20:55:09 -07003047 self.assertEqual(len(self.builds), 2)
3048 self.worker.release('.*')
3049 self.waitUntilSettled()
3050 self.assertEqual(len(self.history), 2)
3051
James E. Blaire5910202013-12-27 09:50:31 -08003052 self.assertEqual(self.getJobFromHistory(
3053 'project-bitrot-stable-old').result, 'SUCCESS')
3054 self.assertEqual(self.getJobFromHistory(
3055 'project-bitrot-stable-older').result, 'SUCCESS')
3056
James E. Blairff80a2f2013-12-27 13:24:06 -08003057 self.assertEqual(len(self.smtp_messages), 1)
James E. Blaire5910202013-12-27 09:50:31 -08003058
3059 # A.messages only holds what FakeGerrit places in it. Thus we
3060 # work on the knowledge of what the first message should be as
3061 # it is only configured to go to SMTP.
3062
3063 self.assertEqual('zuul_from@example.com',
James E. Blairff80a2f2013-12-27 13:24:06 -08003064 self.smtp_messages[0]['from_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003065 self.assertEqual(['alternative_me@example.com'],
James E. Blairff80a2f2013-12-27 13:24:06 -08003066 self.smtp_messages[0]['to_email'])
James E. Blaire5910202013-12-27 09:50:31 -08003067 self.assertIn('Subject: Periodic check for org/project succeeded',
James E. Blairff80a2f2013-12-27 13:24:06 -08003068 self.smtp_messages[0]['headers'])
James E. Blaire5910202013-12-27 09:50:31 -08003069
Clark Boylan3ee090a2014-04-03 20:55:09 -07003070 # Stop queuing timer triggered jobs and let any that may have
3071 # queued through so that end of test assertions pass.
James E. Blairf84026c2015-12-08 16:11:46 -08003072 self.updateConfigLayout(
3073 'tests/fixtures/layout-no-timer.yaml')
Clark Boylan3ee090a2014-04-03 20:55:09 -07003074 self.sched.reconfigure(self.config)
3075 self.registerJobs()
James E. Blairf8058972014-08-15 16:09:16 -07003076 self.waitUntilSettled()
Clark Boylan3ee090a2014-04-03 20:55:09 -07003077 self.worker.release('.*')
3078 self.waitUntilSettled()
3079
James E. Blairec056492016-07-22 09:45:56 -07003080 @skip("Disabled for early v3 development")
James E. Blair91e34592015-07-31 16:45:59 -07003081 def test_client_enqueue_change(self):
James E. Blairad28e912013-11-27 10:43:22 -08003082 "Test that the RPC client can enqueue a change"
3083 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3084 A.addApproval('CRVW', 2)
3085 A.addApproval('APRV', 1)
3086
3087 client = zuul.rpcclient.RPCClient('127.0.0.1',
3088 self.gearman_server.port)
3089 r = client.enqueue(pipeline='gate',
3090 project='org/project',
3091 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003092 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003093 self.waitUntilSettled()
3094 self.assertEqual(self.getJobFromHistory('project-merge').result,
3095 'SUCCESS')
3096 self.assertEqual(self.getJobFromHistory('project-test1').result,
3097 'SUCCESS')
3098 self.assertEqual(self.getJobFromHistory('project-test2').result,
3099 'SUCCESS')
3100 self.assertEqual(A.data['status'], 'MERGED')
3101 self.assertEqual(A.reported, 2)
3102 self.assertEqual(r, True)
3103
James E. Blairec056492016-07-22 09:45:56 -07003104 @skip("Disabled for early v3 development")
James E. Blair91e34592015-07-31 16:45:59 -07003105 def test_client_enqueue_ref(self):
3106 "Test that the RPC client can enqueue a ref"
3107
3108 client = zuul.rpcclient.RPCClient('127.0.0.1',
3109 self.gearman_server.port)
3110 r = client.enqueue_ref(
3111 pipeline='post',
3112 project='org/project',
3113 trigger='gerrit',
3114 ref='master',
3115 oldrev='90f173846e3af9154517b88543ffbd1691f31366',
3116 newrev='d479a0bfcb34da57a31adb2a595c0cf687812543')
3117 self.waitUntilSettled()
3118 job_names = [x.name for x in self.history]
3119 self.assertEqual(len(self.history), 1)
3120 self.assertIn('project-post', job_names)
3121 self.assertEqual(r, True)
3122
James E. Blairec056492016-07-22 09:45:56 -07003123 @skip("Disabled for early v3 development")
James E. Blairad28e912013-11-27 10:43:22 -08003124 def test_client_enqueue_negative(self):
3125 "Test that the RPC client returns errors"
3126 client = zuul.rpcclient.RPCClient('127.0.0.1',
3127 self.gearman_server.port)
3128 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3129 "Invalid project"):
3130 r = client.enqueue(pipeline='gate',
3131 project='project-does-not-exist',
3132 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003133 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003134 client.shutdown()
3135 self.assertEqual(r, False)
3136
3137 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3138 "Invalid pipeline"):
3139 r = client.enqueue(pipeline='pipeline-does-not-exist',
3140 project='org/project',
3141 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003142 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003143 client.shutdown()
3144 self.assertEqual(r, False)
3145
3146 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3147 "Invalid trigger"):
3148 r = client.enqueue(pipeline='gate',
3149 project='org/project',
3150 trigger='trigger-does-not-exist',
James E. Blair36658cf2013-12-06 17:53:48 -08003151 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003152 client.shutdown()
3153 self.assertEqual(r, False)
3154
3155 with testtools.ExpectedException(zuul.rpcclient.RPCFailure,
3156 "Invalid change"):
3157 r = client.enqueue(pipeline='gate',
3158 project='org/project',
3159 trigger='gerrit',
James E. Blair36658cf2013-12-06 17:53:48 -08003160 change='1,1')
James E. Blairad28e912013-11-27 10:43:22 -08003161 client.shutdown()
3162 self.assertEqual(r, False)
3163
3164 self.waitUntilSettled()
3165 self.assertEqual(len(self.history), 0)
3166 self.assertEqual(len(self.builds), 0)
James E. Blair36658cf2013-12-06 17:53:48 -08003167
James E. Blairec056492016-07-22 09:45:56 -07003168 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003169 def test_client_promote(self):
3170 "Test that the RPC client can promote a change"
3171 self.worker.hold_jobs_in_build = True
3172 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3173 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3174 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3175 A.addApproval('CRVW', 2)
3176 B.addApproval('CRVW', 2)
3177 C.addApproval('CRVW', 2)
3178
3179 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3180 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3181 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3182
3183 self.waitUntilSettled()
3184
Sean Daguef39b9ca2014-01-10 21:34:35 -05003185 items = self.sched.layout.pipelines['gate'].getAllItems()
3186 enqueue_times = {}
3187 for item in items:
3188 enqueue_times[str(item.change)] = item.enqueue_time
3189
James E. Blair36658cf2013-12-06 17:53:48 -08003190 client = zuul.rpcclient.RPCClient('127.0.0.1',
3191 self.gearman_server.port)
3192 r = client.promote(pipeline='gate',
3193 change_ids=['2,1', '3,1'])
3194
Sean Daguef39b9ca2014-01-10 21:34:35 -05003195 # ensure that enqueue times are durable
3196 items = self.sched.layout.pipelines['gate'].getAllItems()
3197 for item in items:
3198 self.assertEqual(
3199 enqueue_times[str(item.change)], item.enqueue_time)
3200
James E. Blair78acec92014-02-06 07:11:32 -08003201 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08003202 self.worker.release('.*-merge')
3203 self.waitUntilSettled()
3204 self.worker.release('.*-merge')
3205 self.waitUntilSettled()
3206 self.worker.release('.*-merge')
3207 self.waitUntilSettled()
3208
3209 self.assertEqual(len(self.builds), 6)
3210 self.assertEqual(self.builds[0].name, 'project-test1')
3211 self.assertEqual(self.builds[1].name, 'project-test2')
3212 self.assertEqual(self.builds[2].name, 'project-test1')
3213 self.assertEqual(self.builds[3].name, 'project-test2')
3214 self.assertEqual(self.builds[4].name, 'project-test1')
3215 self.assertEqual(self.builds[5].name, 'project-test2')
3216
3217 self.assertTrue(self.job_has_changes(self.builds[0], B))
3218 self.assertFalse(self.job_has_changes(self.builds[0], A))
3219 self.assertFalse(self.job_has_changes(self.builds[0], C))
3220
3221 self.assertTrue(self.job_has_changes(self.builds[2], B))
3222 self.assertTrue(self.job_has_changes(self.builds[2], C))
3223 self.assertFalse(self.job_has_changes(self.builds[2], A))
3224
3225 self.assertTrue(self.job_has_changes(self.builds[4], B))
3226 self.assertTrue(self.job_has_changes(self.builds[4], C))
3227 self.assertTrue(self.job_has_changes(self.builds[4], A))
3228
3229 self.worker.release()
3230 self.waitUntilSettled()
3231
3232 self.assertEqual(A.data['status'], 'MERGED')
3233 self.assertEqual(A.reported, 2)
3234 self.assertEqual(B.data['status'], 'MERGED')
3235 self.assertEqual(B.reported, 2)
3236 self.assertEqual(C.data['status'], 'MERGED')
3237 self.assertEqual(C.reported, 2)
3238
3239 client.shutdown()
3240 self.assertEqual(r, True)
3241
James E. Blairec056492016-07-22 09:45:56 -07003242 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003243 def test_client_promote_dependent(self):
3244 "Test that the RPC client can promote a dependent change"
3245 # C (depends on B) -> B -> A ; then promote C to get:
3246 # A -> C (depends on B) -> B
3247 self.worker.hold_jobs_in_build = True
3248 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3249 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3250 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3251
3252 C.setDependsOn(B, 1)
3253
3254 A.addApproval('CRVW', 2)
3255 B.addApproval('CRVW', 2)
3256 C.addApproval('CRVW', 2)
3257
3258 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3259 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3260 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3261
3262 self.waitUntilSettled()
3263
3264 client = zuul.rpcclient.RPCClient('127.0.0.1',
3265 self.gearman_server.port)
3266 r = client.promote(pipeline='gate',
3267 change_ids=['3,1'])
3268
James E. Blair78acec92014-02-06 07:11:32 -08003269 self.waitUntilSettled()
James E. Blair36658cf2013-12-06 17:53:48 -08003270 self.worker.release('.*-merge')
3271 self.waitUntilSettled()
3272 self.worker.release('.*-merge')
3273 self.waitUntilSettled()
3274 self.worker.release('.*-merge')
3275 self.waitUntilSettled()
3276
3277 self.assertEqual(len(self.builds), 6)
3278 self.assertEqual(self.builds[0].name, 'project-test1')
3279 self.assertEqual(self.builds[1].name, 'project-test2')
3280 self.assertEqual(self.builds[2].name, 'project-test1')
3281 self.assertEqual(self.builds[3].name, 'project-test2')
3282 self.assertEqual(self.builds[4].name, 'project-test1')
3283 self.assertEqual(self.builds[5].name, 'project-test2')
3284
3285 self.assertTrue(self.job_has_changes(self.builds[0], B))
3286 self.assertFalse(self.job_has_changes(self.builds[0], A))
3287 self.assertFalse(self.job_has_changes(self.builds[0], C))
3288
3289 self.assertTrue(self.job_has_changes(self.builds[2], B))
3290 self.assertTrue(self.job_has_changes(self.builds[2], C))
3291 self.assertFalse(self.job_has_changes(self.builds[2], A))
3292
3293 self.assertTrue(self.job_has_changes(self.builds[4], B))
3294 self.assertTrue(self.job_has_changes(self.builds[4], C))
3295 self.assertTrue(self.job_has_changes(self.builds[4], A))
3296
3297 self.worker.release()
3298 self.waitUntilSettled()
3299
3300 self.assertEqual(A.data['status'], 'MERGED')
3301 self.assertEqual(A.reported, 2)
3302 self.assertEqual(B.data['status'], 'MERGED')
3303 self.assertEqual(B.reported, 2)
3304 self.assertEqual(C.data['status'], 'MERGED')
3305 self.assertEqual(C.reported, 2)
3306
3307 client.shutdown()
3308 self.assertEqual(r, True)
3309
James E. Blairec056492016-07-22 09:45:56 -07003310 @skip("Disabled for early v3 development")
James E. Blair36658cf2013-12-06 17:53:48 -08003311 def test_client_promote_negative(self):
3312 "Test that the RPC client returns errors for promotion"
3313 self.worker.hold_jobs_in_build = True
3314 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3315 A.addApproval('CRVW', 2)
3316 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3317 self.waitUntilSettled()
3318
3319 client = zuul.rpcclient.RPCClient('127.0.0.1',
3320 self.gearman_server.port)
3321
3322 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
3323 r = client.promote(pipeline='nonexistent',
3324 change_ids=['2,1', '3,1'])
3325 client.shutdown()
3326 self.assertEqual(r, False)
3327
3328 with testtools.ExpectedException(zuul.rpcclient.RPCFailure):
3329 r = client.promote(pipeline='gate',
3330 change_ids=['4,1'])
3331 client.shutdown()
3332 self.assertEqual(r, False)
3333
3334 self.worker.hold_jobs_in_build = False
3335 self.worker.release()
3336 self.waitUntilSettled()
Clark Boylan7603a372014-01-21 11:43:20 -08003337
James E. Blairec056492016-07-22 09:45:56 -07003338 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003339 def test_queue_rate_limiting(self):
3340 "Test that DependentPipelines are rate limited with dep across window"
James E. Blairf84026c2015-12-08 16:11:46 -08003341 self.updateConfigLayout(
3342 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003343 self.sched.reconfigure(self.config)
3344 self.worker.hold_jobs_in_build = True
3345 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3346 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3347 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3348
3349 C.setDependsOn(B, 1)
3350 self.worker.addFailTest('project-test1', A)
3351
3352 A.addApproval('CRVW', 2)
3353 B.addApproval('CRVW', 2)
3354 C.addApproval('CRVW', 2)
3355
3356 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3357 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3358 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3359 self.waitUntilSettled()
3360
3361 # Only A and B will have their merge jobs queued because
3362 # window is 2.
3363 self.assertEqual(len(self.builds), 2)
3364 self.assertEqual(self.builds[0].name, 'project-merge')
3365 self.assertEqual(self.builds[1].name, 'project-merge')
3366
3367 self.worker.release('.*-merge')
3368 self.waitUntilSettled()
3369 self.worker.release('.*-merge')
3370 self.waitUntilSettled()
3371
3372 # Only A and B will have their test jobs queued because
3373 # window is 2.
3374 self.assertEqual(len(self.builds), 4)
3375 self.assertEqual(self.builds[0].name, 'project-test1')
3376 self.assertEqual(self.builds[1].name, 'project-test2')
3377 self.assertEqual(self.builds[2].name, 'project-test1')
3378 self.assertEqual(self.builds[3].name, 'project-test2')
3379
3380 self.worker.release('project-.*')
3381 self.waitUntilSettled()
3382
3383 queue = self.sched.layout.pipelines['gate'].queues[0]
3384 # A failed so window is reduced by 1 to 1.
3385 self.assertEqual(queue.window, 1)
3386 self.assertEqual(queue.window_floor, 1)
3387 self.assertEqual(A.data['status'], 'NEW')
3388
3389 # Gate is reset and only B's merge job is queued because
3390 # window shrunk to 1.
3391 self.assertEqual(len(self.builds), 1)
3392 self.assertEqual(self.builds[0].name, 'project-merge')
3393
3394 self.worker.release('.*-merge')
3395 self.waitUntilSettled()
3396
3397 # Only B's test jobs are queued because window is still 1.
3398 self.assertEqual(len(self.builds), 2)
3399 self.assertEqual(self.builds[0].name, 'project-test1')
3400 self.assertEqual(self.builds[1].name, 'project-test2')
3401
3402 self.worker.release('project-.*')
3403 self.waitUntilSettled()
3404
3405 # B was successfully merged so window is increased to 2.
3406 self.assertEqual(queue.window, 2)
3407 self.assertEqual(queue.window_floor, 1)
3408 self.assertEqual(B.data['status'], 'MERGED')
3409
3410 # Only C is left and its merge job is queued.
3411 self.assertEqual(len(self.builds), 1)
3412 self.assertEqual(self.builds[0].name, 'project-merge')
3413
3414 self.worker.release('.*-merge')
3415 self.waitUntilSettled()
3416
3417 # After successful merge job the test jobs for C are queued.
3418 self.assertEqual(len(self.builds), 2)
3419 self.assertEqual(self.builds[0].name, 'project-test1')
3420 self.assertEqual(self.builds[1].name, 'project-test2')
3421
3422 self.worker.release('project-.*')
3423 self.waitUntilSettled()
3424
3425 # C successfully merged so window is bumped to 3.
3426 self.assertEqual(queue.window, 3)
3427 self.assertEqual(queue.window_floor, 1)
3428 self.assertEqual(C.data['status'], 'MERGED')
3429
James E. Blairec056492016-07-22 09:45:56 -07003430 @skip("Disabled for early v3 development")
Clark Boylan7603a372014-01-21 11:43:20 -08003431 def test_queue_rate_limiting_dependent(self):
3432 "Test that DependentPipelines are rate limited with dep in window"
James E. Blairf84026c2015-12-08 16:11:46 -08003433 self.updateConfigLayout(
3434 'tests/fixtures/layout-rate-limit.yaml')
Clark Boylan7603a372014-01-21 11:43:20 -08003435 self.sched.reconfigure(self.config)
3436 self.worker.hold_jobs_in_build = True
3437 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3438 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3439 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3440
3441 B.setDependsOn(A, 1)
3442
3443 self.worker.addFailTest('project-test1', A)
3444
3445 A.addApproval('CRVW', 2)
3446 B.addApproval('CRVW', 2)
3447 C.addApproval('CRVW', 2)
3448
3449 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3450 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3451 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3452 self.waitUntilSettled()
3453
3454 # Only A and B will have their merge jobs queued because
3455 # window is 2.
3456 self.assertEqual(len(self.builds), 2)
3457 self.assertEqual(self.builds[0].name, 'project-merge')
3458 self.assertEqual(self.builds[1].name, 'project-merge')
3459
3460 self.worker.release('.*-merge')
3461 self.waitUntilSettled()
3462 self.worker.release('.*-merge')
3463 self.waitUntilSettled()
3464
3465 # Only A and B will have their test jobs queued because
3466 # window is 2.
3467 self.assertEqual(len(self.builds), 4)
3468 self.assertEqual(self.builds[0].name, 'project-test1')
3469 self.assertEqual(self.builds[1].name, 'project-test2')
3470 self.assertEqual(self.builds[2].name, 'project-test1')
3471 self.assertEqual(self.builds[3].name, 'project-test2')
3472
3473 self.worker.release('project-.*')
3474 self.waitUntilSettled()
3475
3476 queue = self.sched.layout.pipelines['gate'].queues[0]
3477 # A failed so window is reduced by 1 to 1.
3478 self.assertEqual(queue.window, 1)
3479 self.assertEqual(queue.window_floor, 1)
3480 self.assertEqual(A.data['status'], 'NEW')
3481 self.assertEqual(B.data['status'], 'NEW')
3482
3483 # Gate is reset and only C's merge job is queued because
3484 # window shrunk to 1 and A and B were dequeued.
3485 self.assertEqual(len(self.builds), 1)
3486 self.assertEqual(self.builds[0].name, 'project-merge')
3487
3488 self.worker.release('.*-merge')
3489 self.waitUntilSettled()
3490
3491 # Only C's test jobs are queued because window is still 1.
3492 self.assertEqual(len(self.builds), 2)
3493 self.assertEqual(self.builds[0].name, 'project-test1')
3494 self.assertEqual(self.builds[1].name, 'project-test2')
3495
3496 self.worker.release('project-.*')
3497 self.waitUntilSettled()
3498
3499 # C was successfully merged so window is increased to 2.
3500 self.assertEqual(queue.window, 2)
3501 self.assertEqual(queue.window_floor, 1)
3502 self.assertEqual(C.data['status'], 'MERGED')
Joshua Heskethba8776a2014-01-12 14:35:40 +08003503
James E. Blairec056492016-07-22 09:45:56 -07003504 @skip("Disabled for early v3 development")
Joshua Heskethba8776a2014-01-12 14:35:40 +08003505 def test_worker_update_metadata(self):
3506 "Test if a worker can send back metadata about itself"
3507 self.worker.hold_jobs_in_build = True
3508
3509 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3510 A.addApproval('CRVW', 2)
3511 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3512 self.waitUntilSettled()
3513
3514 self.assertEqual(len(self.launcher.builds), 1)
3515
3516 self.log.debug('Current builds:')
3517 self.log.debug(self.launcher.builds)
3518
3519 start = time.time()
3520 while True:
3521 if time.time() - start > 10:
3522 raise Exception("Timeout waiting for gearman server to report "
3523 + "back to the client")
3524 build = self.launcher.builds.values()[0]
3525 if build.worker.name == "My Worker":
3526 break
3527 else:
3528 time.sleep(0)
3529
3530 self.log.debug(build)
3531 self.assertEqual("My Worker", build.worker.name)
3532 self.assertEqual("localhost", build.worker.hostname)
3533 self.assertEqual(['127.0.0.1', '192.168.1.1'], build.worker.ips)
3534 self.assertEqual("zuul.example.org", build.worker.fqdn)
3535 self.assertEqual("FakeBuilder", build.worker.program)
3536 self.assertEqual("v1.1", build.worker.version)
3537 self.assertEqual({'something': 'else'}, build.worker.extra)
3538
3539 self.worker.hold_jobs_in_build = False
3540 self.worker.release()
3541 self.waitUntilSettled()
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003542
James E. Blairec056492016-07-22 09:45:56 -07003543 @skip("Disabled for early v3 development")
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003544 def test_footer_message(self):
3545 "Test a pipeline's footer message is correctly added to the report."
James E. Blairf84026c2015-12-08 16:11:46 -08003546 self.updateConfigLayout(
3547 'tests/fixtures/layout-footer-message.yaml')
Joshua Hesketh3979e3e2014-03-04 11:21:10 +11003548 self.sched.reconfigure(self.config)
3549 self.registerJobs()
3550
3551 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3552 A.addApproval('CRVW', 2)
3553 self.worker.addFailTest('test1', A)
3554 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3555 self.waitUntilSettled()
3556
3557 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3558 B.addApproval('CRVW', 2)
3559 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3560 self.waitUntilSettled()
3561
3562 self.assertEqual(2, len(self.smtp_messages))
3563
3564 failure_body = """\
3565Build failed. For information on how to proceed, see \
3566http://wiki.example.org/Test_Failures
3567
3568- test1 http://logs.example.com/1/1/gate/test1/0 : FAILURE in 0s
3569- test2 http://logs.example.com/1/1/gate/test2/1 : SUCCESS in 0s
3570
3571For CI problems and help debugging, contact ci@example.org"""
3572
3573 success_body = """\
3574Build succeeded.
3575
3576- test1 http://logs.example.com/2/1/gate/test1/2 : SUCCESS in 0s
3577- test2 http://logs.example.com/2/1/gate/test2/3 : SUCCESS in 0s
3578
3579For CI problems and help debugging, contact ci@example.org"""
3580
3581 self.assertEqual(failure_body, self.smtp_messages[0]['body'])
3582 self.assertEqual(success_body, self.smtp_messages[1]['body'])
Joshua Heskethb7179772014-01-30 23:30:46 +11003583
James E. Blairec056492016-07-22 09:45:56 -07003584 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003585 def test_merge_failure_reporters(self):
3586 """Check that the config is set up correctly"""
3587
James E. Blairf84026c2015-12-08 16:11:46 -08003588 self.updateConfigLayout(
3589 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003590 self.sched.reconfigure(self.config)
3591 self.registerJobs()
3592
3593 self.assertEqual(
Jeremy Stanley1c2c3c22015-06-15 21:23:19 +00003594 "Merge Failed.\n\nThis change or one of its cross-repo "
3595 "dependencies was unable to be automatically merged with the "
3596 "current state of its repository. Please rebase the change and "
3597 "upload a new patchset.",
Joshua Heskethb7179772014-01-30 23:30:46 +11003598 self.sched.layout.pipelines['check'].merge_failure_message)
3599 self.assertEqual(
3600 "The merge failed! For more information...",
3601 self.sched.layout.pipelines['gate'].merge_failure_message)
3602
3603 self.assertEqual(
3604 len(self.sched.layout.pipelines['check'].merge_failure_actions), 1)
3605 self.assertEqual(
3606 len(self.sched.layout.pipelines['gate'].merge_failure_actions), 2)
3607
3608 self.assertTrue(isinstance(
Joshua Heskethde958652015-11-10 19:19:50 +11003609 self.sched.layout.pipelines['check'].merge_failure_actions[0],
3610 zuul.reporter.gerrit.GerritReporter))
Joshua Heskethb7179772014-01-30 23:30:46 +11003611
3612 self.assertTrue(
3613 (
3614 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003615 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003616 zuul.reporter.smtp.SMTPReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003617 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003618 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003619 zuul.reporter.gerrit.GerritReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003620 ) or (
3621 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003622 merge_failure_actions[0],
Joshua Heskethffe42062014-09-05 21:43:52 +10003623 zuul.reporter.gerrit.GerritReporter) and
Joshua Heskethb7179772014-01-30 23:30:46 +11003624 isinstance(self.sched.layout.pipelines['gate'].
Joshua Heskethde958652015-11-10 19:19:50 +11003625 merge_failure_actions[1],
Joshua Heskethffe42062014-09-05 21:43:52 +10003626 zuul.reporter.smtp.SMTPReporter)
Joshua Heskethb7179772014-01-30 23:30:46 +11003627 )
3628 )
3629
James E. Blairec056492016-07-22 09:45:56 -07003630 @skip("Disabled for early v3 development")
Joshua Heskethb7179772014-01-30 23:30:46 +11003631 def test_merge_failure_reports(self):
3632 """Check that when a change fails to merge the correct message is sent
3633 to the correct reporter"""
James E. Blairf84026c2015-12-08 16:11:46 -08003634 self.updateConfigLayout(
3635 'tests/fixtures/layout-merge-failure.yaml')
Joshua Heskethb7179772014-01-30 23:30:46 +11003636 self.sched.reconfigure(self.config)
3637 self.registerJobs()
3638
3639 # Check a test failure isn't reported to SMTP
3640 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3641 A.addApproval('CRVW', 2)
3642 self.worker.addFailTest('project-test1', A)
3643 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3644 self.waitUntilSettled()
3645
3646 self.assertEqual(3, len(self.history)) # 3 jobs
3647 self.assertEqual(0, len(self.smtp_messages))
3648
3649 # Check a merge failure is reported to SMTP
3650 # B should be merged, but C will conflict with B
3651 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3652 B.addPatchset(['conflict'])
3653 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
3654 C.addPatchset(['conflict'])
3655 B.addApproval('CRVW', 2)
3656 C.addApproval('CRVW', 2)
3657 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3658 self.fake_gerrit.addEvent(C.addApproval('APRV', 1))
3659 self.waitUntilSettled()
3660
3661 self.assertEqual(6, len(self.history)) # A and B jobs
3662 self.assertEqual(1, len(self.smtp_messages))
3663 self.assertEqual('The merge failed! For more information...',
3664 self.smtp_messages[0]['body'])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003665
James E. Blairec056492016-07-22 09:45:56 -07003666 @skip("Disabled for early v3 development")
James E. Blairf760f0e2016-02-09 08:44:52 -08003667 def test_default_merge_failure_reports(self):
3668 """Check that the default merge failure reports are correct."""
3669
3670 # A should report success, B should report merge failure.
3671 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3672 A.addPatchset(['conflict'])
3673 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3674 B.addPatchset(['conflict'])
3675 A.addApproval('CRVW', 2)
3676 B.addApproval('CRVW', 2)
3677 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3678 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3679 self.waitUntilSettled()
3680
3681 self.assertEqual(3, len(self.history)) # A jobs
3682 self.assertEqual(A.reported, 2)
3683 self.assertEqual(B.reported, 2)
3684 self.assertEqual(A.data['status'], 'MERGED')
3685 self.assertEqual(B.data['status'], 'NEW')
3686 self.assertIn('Build succeeded', A.messages[1])
3687 self.assertIn('Merge Failed', B.messages[1])
3688 self.assertIn('automatically merged', B.messages[1])
3689 self.assertNotIn('logs.example.com', B.messages[1])
3690 self.assertNotIn('SKIPPED', B.messages[1])
3691
James E. Blairec056492016-07-22 09:45:56 -07003692 @skip("Disabled for early v3 development")
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003693 def test_swift_instructions(self):
3694 "Test that the correct swift instructions are sent to the workers"
James E. Blairf84026c2015-12-08 16:11:46 -08003695 self.updateConfigLayout(
3696 'tests/fixtures/layout-swift.yaml')
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003697 self.sched.reconfigure(self.config)
3698 self.registerJobs()
3699
3700 self.worker.hold_jobs_in_build = True
3701 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3702
3703 A.addApproval('CRVW', 2)
3704 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3705 self.waitUntilSettled()
3706
3707 self.assertEqual(
3708 "https://storage.example.org/V1/AUTH_account/merge_logs/1/1/1/"
3709 "gate/test-merge/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003710 self.builds[0].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003711 self.assertEqual(5,
3712 len(self.builds[0].parameters['SWIFT_logs_HMAC_BODY'].
3713 split('\n')))
3714 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[0].parameters)
3715
3716 self.assertEqual(
3717 "https://storage.example.org/V1/AUTH_account/logs/1/1/1/"
3718 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003719 self.builds[1].parameters['SWIFT_logs_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003720 self.assertEqual(5,
3721 len(self.builds[1].parameters['SWIFT_logs_HMAC_BODY'].
3722 split('\n')))
3723 self.assertIn('SWIFT_logs_SIGNATURE', self.builds[1].parameters)
3724
3725 self.assertEqual(
3726 "https://storage.example.org/V1/AUTH_account/stash/1/1/1/"
3727 "gate/test-test/",
Joshua Hesketh76dee532014-07-03 15:39:13 +10003728 self.builds[1].parameters['SWIFT_MOSTLY_URL'][:-7])
Joshua Hesketh36c3fa52014-01-22 11:40:52 +11003729 self.assertEqual(5,
3730 len(self.builds[1].
3731 parameters['SWIFT_MOSTLY_HMAC_BODY'].split('\n')))
3732 self.assertIn('SWIFT_MOSTLY_SIGNATURE', self.builds[1].parameters)
3733
3734 self.worker.hold_jobs_in_build = False
3735 self.worker.release()
3736 self.waitUntilSettled()
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003737
James E. Blairec056492016-07-22 09:45:56 -07003738 @skip("Disabled for early v3 development")
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003739 def test_client_get_running_jobs(self):
3740 "Test that the RPC client can get a list of running jobs"
3741 self.worker.hold_jobs_in_build = True
3742 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
3743 A.addApproval('CRVW', 2)
3744 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3745 self.waitUntilSettled()
3746
3747 client = zuul.rpcclient.RPCClient('127.0.0.1',
3748 self.gearman_server.port)
3749
3750 # Wait for gearman server to send the initial workData back to zuul
3751 start = time.time()
3752 while True:
3753 if time.time() - start > 10:
3754 raise Exception("Timeout waiting for gearman server to report "
3755 + "back to the client")
3756 build = self.launcher.builds.values()[0]
3757 if build.worker.name == "My Worker":
3758 break
3759 else:
3760 time.sleep(0)
3761
3762 running_items = client.get_running_jobs()
3763
3764 self.assertEqual(1, len(running_items))
3765 running_item = running_items[0]
3766 self.assertEqual([], running_item['failing_reasons'])
3767 self.assertEqual([], running_item['items_behind'])
3768 self.assertEqual('https://hostname/1', running_item['url'])
3769 self.assertEqual(None, running_item['item_ahead'])
3770 self.assertEqual('org/project', running_item['project'])
3771 self.assertEqual(None, running_item['remaining_time'])
3772 self.assertEqual(True, running_item['active'])
3773 self.assertEqual('1,1', running_item['id'])
3774
3775 self.assertEqual(3, len(running_item['jobs']))
3776 for job in running_item['jobs']:
3777 if job['name'] == 'project-merge':
3778 self.assertEqual('project-merge', job['name'])
3779 self.assertEqual('gate', job['pipeline'])
3780 self.assertEqual(False, job['retry'])
Joshua Hesketh85af4e92014-02-21 08:28:58 -08003781 self.assertEqual('https://server/job/project-merge/0/',
3782 job['url'])
3783 self.assertEqual(7, len(job['worker']))
3784 self.assertEqual(False, job['canceled'])
3785 self.assertEqual(True, job['voting'])
3786 self.assertEqual(None, job['result'])
3787 self.assertEqual('gate', job['pipeline'])
3788 break
3789
3790 self.worker.hold_jobs_in_build = False
3791 self.worker.release()
3792 self.waitUntilSettled()
3793
3794 running_items = client.get_running_jobs()
3795 self.assertEqual(0, len(running_items))
James E. Blairbadc1ad2014-04-28 13:55:14 -07003796
James E. Blairec056492016-07-22 09:45:56 -07003797 @skip("Disabled for early v3 development")
James E. Blairbadc1ad2014-04-28 13:55:14 -07003798 def test_nonvoting_pipeline(self):
3799 "Test that a nonvoting pipeline (experimental) can still report"
3800
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003801 A = self.fake_gerrit.addFakeChange('org/experimental-project',
3802 'master', 'A')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003803 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
3804 self.waitUntilSettled()
Joshua Heskethcc017ea2014-04-30 19:55:25 +10003805 self.assertEqual(
3806 self.getJobFromHistory('experimental-project-test').result,
3807 'SUCCESS')
James E. Blairbadc1ad2014-04-28 13:55:14 -07003808 self.assertEqual(A.reported, 1)
James E. Blair5ee24252014-12-30 10:12:29 -08003809
James E. Blairec056492016-07-22 09:45:56 -07003810 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08003811 def test_crd_gate(self):
3812 "Test cross-repo dependencies"
3813 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3814 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3815 A.addApproval('CRVW', 2)
3816 B.addApproval('CRVW', 2)
3817
3818 AM2 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM2')
3819 AM1 = self.fake_gerrit.addFakeChange('org/project1', 'master', 'AM1')
3820 AM2.setMerged()
3821 AM1.setMerged()
3822
3823 BM2 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM2')
3824 BM1 = self.fake_gerrit.addFakeChange('org/project2', 'master', 'BM1')
3825 BM2.setMerged()
3826 BM1.setMerged()
3827
3828 # A -> AM1 -> AM2
3829 # B -> BM1 -> BM2
3830 # A Depends-On: B
3831 # M2 is here to make sure it is never queried. If it is, it
3832 # means zuul is walking down the entire history of merged
3833 # changes.
3834
3835 B.setDependsOn(BM1, 1)
3836 BM1.setDependsOn(BM2, 1)
3837
3838 A.setDependsOn(AM1, 1)
3839 AM1.setDependsOn(AM2, 1)
3840
3841 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3842 A.subject, B.data['id'])
3843
3844 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3845 self.waitUntilSettled()
3846
3847 self.assertEqual(A.data['status'], 'NEW')
3848 self.assertEqual(B.data['status'], 'NEW')
3849
Joshua Hesketh4bd7da32016-02-17 20:58:47 +11003850 for connection in self.connections.values():
3851 connection.maintainCache([])
James E. Blair5ee24252014-12-30 10:12:29 -08003852
3853 self.worker.hold_jobs_in_build = True
3854 B.addApproval('APRV', 1)
3855 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3856 self.waitUntilSettled()
3857
3858 self.worker.release('.*-merge')
3859 self.waitUntilSettled()
3860 self.worker.release('.*-merge')
3861 self.waitUntilSettled()
3862 self.worker.hold_jobs_in_build = False
3863 self.worker.release()
3864 self.waitUntilSettled()
3865
3866 self.assertEqual(AM2.queried, 0)
3867 self.assertEqual(BM2.queried, 0)
3868 self.assertEqual(A.data['status'], 'MERGED')
3869 self.assertEqual(B.data['status'], 'MERGED')
3870 self.assertEqual(A.reported, 2)
3871 self.assertEqual(B.reported, 2)
3872
James E. Blair8f78d882015-02-05 08:51:37 -08003873 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3874 '2,1 1,1')
3875
James E. Blairec056492016-07-22 09:45:56 -07003876 @skip("Disabled for early v3 development")
James E. Blair8f78d882015-02-05 08:51:37 -08003877 def test_crd_branch(self):
3878 "Test cross-repo dependencies in multiple branches"
3879 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3880 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3881 C = self.fake_gerrit.addFakeChange('org/project2', 'mp', 'C')
3882 C.data['id'] = B.data['id']
3883 A.addApproval('CRVW', 2)
3884 B.addApproval('CRVW', 2)
3885 C.addApproval('CRVW', 2)
3886
3887 # A Depends-On: B+C
3888 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3889 A.subject, B.data['id'])
3890
3891 self.worker.hold_jobs_in_build = True
3892 B.addApproval('APRV', 1)
3893 C.addApproval('APRV', 1)
3894 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3895 self.waitUntilSettled()
3896
3897 self.worker.release('.*-merge')
3898 self.waitUntilSettled()
3899 self.worker.release('.*-merge')
3900 self.waitUntilSettled()
3901 self.worker.release('.*-merge')
3902 self.waitUntilSettled()
3903 self.worker.hold_jobs_in_build = False
3904 self.worker.release()
3905 self.waitUntilSettled()
3906
3907 self.assertEqual(A.data['status'], 'MERGED')
3908 self.assertEqual(B.data['status'], 'MERGED')
3909 self.assertEqual(C.data['status'], 'MERGED')
3910 self.assertEqual(A.reported, 2)
3911 self.assertEqual(B.reported, 2)
3912 self.assertEqual(C.reported, 2)
3913
3914 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3915 '2,1 3,1 1,1')
3916
James E. Blairec056492016-07-22 09:45:56 -07003917 @skip("Disabled for early v3 development")
James E. Blair8f78d882015-02-05 08:51:37 -08003918 def test_crd_multiline(self):
3919 "Test multiple depends-on lines in commit"
3920 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3921 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
3922 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
3923 A.addApproval('CRVW', 2)
3924 B.addApproval('CRVW', 2)
3925 C.addApproval('CRVW', 2)
3926
3927 # A Depends-On: B+C
3928 A.data['commitMessage'] = '%s\n\nDepends-On: %s\nDepends-On: %s\n' % (
3929 A.subject, B.data['id'], C.data['id'])
3930
3931 self.worker.hold_jobs_in_build = True
3932 B.addApproval('APRV', 1)
3933 C.addApproval('APRV', 1)
3934 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3935 self.waitUntilSettled()
3936
3937 self.worker.release('.*-merge')
3938 self.waitUntilSettled()
3939 self.worker.release('.*-merge')
3940 self.waitUntilSettled()
3941 self.worker.release('.*-merge')
3942 self.waitUntilSettled()
3943 self.worker.hold_jobs_in_build = False
3944 self.worker.release()
3945 self.waitUntilSettled()
3946
3947 self.assertEqual(A.data['status'], 'MERGED')
3948 self.assertEqual(B.data['status'], 'MERGED')
3949 self.assertEqual(C.data['status'], 'MERGED')
3950 self.assertEqual(A.reported, 2)
3951 self.assertEqual(B.reported, 2)
3952 self.assertEqual(C.reported, 2)
3953
3954 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
3955 '2,1 3,1 1,1')
James E. Blair5ee24252014-12-30 10:12:29 -08003956
James E. Blairec056492016-07-22 09:45:56 -07003957 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08003958 def test_crd_unshared_gate(self):
3959 "Test cross-repo dependencies in unshared gate queues"
3960 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
3961 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
3962 A.addApproval('CRVW', 2)
3963 B.addApproval('CRVW', 2)
3964
3965 # A Depends-On: B
3966 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
3967 A.subject, B.data['id'])
3968
3969 # A and B do not share a queue, make sure that A is unable to
3970 # enqueue B (and therefore, A is unable to be enqueued).
3971 B.addApproval('APRV', 1)
3972 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3973 self.waitUntilSettled()
3974
3975 self.assertEqual(A.data['status'], 'NEW')
3976 self.assertEqual(B.data['status'], 'NEW')
3977 self.assertEqual(A.reported, 0)
3978 self.assertEqual(B.reported, 0)
3979 self.assertEqual(len(self.history), 0)
3980
3981 # Enqueue and merge B alone.
3982 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
3983 self.waitUntilSettled()
3984
3985 self.assertEqual(B.data['status'], 'MERGED')
3986 self.assertEqual(B.reported, 2)
3987
3988 # Now that B is merged, A should be able to be enqueued and
3989 # merged.
3990 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
3991 self.waitUntilSettled()
3992
3993 self.assertEqual(A.data['status'], 'MERGED')
3994 self.assertEqual(A.reported, 2)
3995
James E. Blairec056492016-07-22 09:45:56 -07003996 @skip("Disabled for early v3 development")
James E. Blair96698e22015-04-02 07:48:21 -07003997 def test_crd_gate_reverse(self):
3998 "Test reverse cross-repo dependencies"
3999 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4000 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4001 A.addApproval('CRVW', 2)
4002 B.addApproval('CRVW', 2)
4003
4004 # A Depends-On: B
4005
4006 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4007 A.subject, B.data['id'])
4008
4009 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4010 self.waitUntilSettled()
4011
4012 self.assertEqual(A.data['status'], 'NEW')
4013 self.assertEqual(B.data['status'], 'NEW')
4014
4015 self.worker.hold_jobs_in_build = True
4016 A.addApproval('APRV', 1)
4017 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
4018 self.waitUntilSettled()
4019
4020 self.worker.release('.*-merge')
4021 self.waitUntilSettled()
4022 self.worker.release('.*-merge')
4023 self.waitUntilSettled()
4024 self.worker.hold_jobs_in_build = False
4025 self.worker.release()
4026 self.waitUntilSettled()
4027
4028 self.assertEqual(A.data['status'], 'MERGED')
4029 self.assertEqual(B.data['status'], 'MERGED')
4030 self.assertEqual(A.reported, 2)
4031 self.assertEqual(B.reported, 2)
4032
4033 self.assertEqual(self.getJobFromHistory('project1-merge').changes,
4034 '2,1 1,1')
4035
James E. Blairec056492016-07-22 09:45:56 -07004036 @skip("Disabled for early v3 development")
James E. Blair5ee24252014-12-30 10:12:29 -08004037 def test_crd_cycle(self):
4038 "Test cross-repo dependency cycles"
4039 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4040 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4041 A.addApproval('CRVW', 2)
4042 B.addApproval('CRVW', 2)
4043
4044 # A -> B -> A (via commit-depends)
4045
4046 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4047 A.subject, B.data['id'])
4048 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4049 B.subject, A.data['id'])
4050
4051 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4052 self.waitUntilSettled()
4053
4054 self.assertEqual(A.reported, 0)
4055 self.assertEqual(B.reported, 0)
4056 self.assertEqual(A.data['status'], 'NEW')
4057 self.assertEqual(B.data['status'], 'NEW')
James E. Blairbfb8e042014-12-30 17:01:44 -08004058
James E. Blairec056492016-07-22 09:45:56 -07004059 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004060 def test_crd_gate_unknown(self):
4061 "Test unknown projects in dependent pipeline"
4062 self.init_repo("org/unknown")
4063 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4064 B = self.fake_gerrit.addFakeChange('org/unknown', 'master', 'B')
4065 A.addApproval('CRVW', 2)
4066 B.addApproval('CRVW', 2)
4067
4068 # A Depends-On: B
4069 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4070 A.subject, B.data['id'])
4071
4072 B.addApproval('APRV', 1)
4073 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4074 self.waitUntilSettled()
4075
4076 # Unknown projects cannot share a queue with any other
4077 # since they don't have common jobs with any other (they have no jobs).
4078 # Changes which depend on unknown project changes
4079 # should not be processed in dependent pipeline
4080 self.assertEqual(A.data['status'], 'NEW')
4081 self.assertEqual(B.data['status'], 'NEW')
4082 self.assertEqual(A.reported, 0)
4083 self.assertEqual(B.reported, 0)
4084 self.assertEqual(len(self.history), 0)
4085
4086 # Simulate change B being gated outside this layout
4087 self.fake_gerrit.addEvent(B.addApproval('APRV', 1))
4088 B.setMerged()
4089 self.waitUntilSettled()
4090 self.assertEqual(len(self.history), 0)
4091
4092 # Now that B is merged, A should be able to be enqueued and
4093 # merged.
4094 self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
4095 self.waitUntilSettled()
4096
4097 self.assertEqual(A.data['status'], 'MERGED')
4098 self.assertEqual(A.reported, 2)
4099 self.assertEqual(B.data['status'], 'MERGED')
4100 self.assertEqual(B.reported, 0)
4101
James E. Blairec056492016-07-22 09:45:56 -07004102 @skip("Disabled for early v3 development")
James E. Blairbfb8e042014-12-30 17:01:44 -08004103 def test_crd_check(self):
4104 "Test cross-repo dependencies in independent pipelines"
4105
4106 self.gearman_server.hold_jobs_in_queue = True
4107 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4108 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4109
4110 # A Depends-On: B
4111 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4112 A.subject, B.data['id'])
4113
4114 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4115 self.waitUntilSettled()
4116
4117 queue = self.gearman_server.getQueue()
4118 ref = self.getParameter(queue[-1], 'ZUUL_REF')
4119 self.gearman_server.hold_jobs_in_queue = False
4120 self.gearman_server.release()
4121 self.waitUntilSettled()
4122
4123 path = os.path.join(self.git_root, "org/project1")
4124 repo = git.Repo(path)
4125 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4126 repo_messages.reverse()
4127 correct_messages = ['initial commit', 'A-1']
4128 self.assertEqual(repo_messages, correct_messages)
4129
4130 path = os.path.join(self.git_root, "org/project2")
4131 repo = git.Repo(path)
4132 repo_messages = [c.message.strip() for c in repo.iter_commits(ref)]
4133 repo_messages.reverse()
4134 correct_messages = ['initial commit', 'B-1']
4135 self.assertEqual(repo_messages, correct_messages)
4136
4137 self.assertEqual(A.data['status'], 'NEW')
4138 self.assertEqual(B.data['status'], 'NEW')
4139 self.assertEqual(A.reported, 1)
4140 self.assertEqual(B.reported, 0)
4141
4142 self.assertEqual(self.history[0].changes, '2,1 1,1')
4143 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
James E. Blair8f78d882015-02-05 08:51:37 -08004144
James E. Blairec056492016-07-22 09:45:56 -07004145 @skip("Disabled for early v3 development")
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004146 def test_crd_check_git_depends(self):
4147 "Test single-repo dependencies in independent pipelines"
James E. Blairb8c16472015-05-05 14:55:26 -07004148 self.gearman_server.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004149 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4150 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4151
4152 # Add two git-dependent changes and make sure they both report
4153 # success.
4154 B.setDependsOn(A, 1)
4155 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4156 self.waitUntilSettled()
4157 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4158 self.waitUntilSettled()
4159
James E. Blairb8c16472015-05-05 14:55:26 -07004160 self.orderedRelease()
4161 self.gearman_server.hold_jobs_in_build = False
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004162 self.waitUntilSettled()
4163
4164 self.assertEqual(A.data['status'], 'NEW')
4165 self.assertEqual(B.data['status'], 'NEW')
4166 self.assertEqual(A.reported, 1)
4167 self.assertEqual(B.reported, 1)
4168
4169 self.assertEqual(self.history[0].changes, '1,1')
4170 self.assertEqual(self.history[-1].changes, '1,1 2,1')
4171 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
4172
4173 self.assertIn('Build succeeded', A.messages[0])
4174 self.assertIn('Build succeeded', B.messages[0])
4175
James E. Blairec056492016-07-22 09:45:56 -07004176 @skip("Disabled for early v3 development")
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004177 def test_crd_check_duplicate(self):
4178 "Test duplicate check in independent pipelines"
James E. Blair1e263032015-05-07 14:35:34 -07004179 self.worker.hold_jobs_in_build = True
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004180 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4181 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4182 check_pipeline = self.sched.layout.pipelines['check']
4183
4184 # Add two git-dependent changes...
4185 B.setDependsOn(A, 1)
4186 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4187 self.waitUntilSettled()
4188 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4189
4190 # ...make sure the live one is not duplicated...
4191 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4192 self.waitUntilSettled()
4193 self.assertEqual(len(check_pipeline.getAllItems()), 2)
4194
4195 # ...but the non-live one is able to be.
4196 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4197 self.waitUntilSettled()
4198 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4199
Clark Boylandd849822015-03-02 12:38:14 -08004200 # Release jobs in order to avoid races with change A jobs
4201 # finishing before change B jobs.
James E. Blaird7650852015-05-07 15:47:37 -07004202 self.orderedRelease()
James E. Blair1e263032015-05-07 14:35:34 -07004203 self.worker.hold_jobs_in_build = False
4204 self.worker.release()
James E. Blairdbfe1cd2015-02-07 11:41:19 -08004205 self.waitUntilSettled()
4206
4207 self.assertEqual(A.data['status'], 'NEW')
4208 self.assertEqual(B.data['status'], 'NEW')
4209 self.assertEqual(A.reported, 1)
4210 self.assertEqual(B.reported, 1)
4211
4212 self.assertEqual(self.history[0].changes, '1,1 2,1')
4213 self.assertEqual(self.history[1].changes, '1,1')
4214 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
4215
4216 self.assertIn('Build succeeded', A.messages[0])
4217 self.assertIn('Build succeeded', B.messages[0])
4218
James E. Blairec056492016-07-22 09:45:56 -07004219 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004220 def _test_crd_check_reconfiguration(self, project1, project2):
James E. Blair8f78d882015-02-05 08:51:37 -08004221 "Test cross-repo dependencies re-enqueued in independent pipelines"
4222
4223 self.gearman_server.hold_jobs_in_queue = True
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004224 A = self.fake_gerrit.addFakeChange(project1, 'master', 'A')
4225 B = self.fake_gerrit.addFakeChange(project2, 'master', 'B')
James E. Blair8f78d882015-02-05 08:51:37 -08004226
4227 # A Depends-On: B
4228 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4229 A.subject, B.data['id'])
4230
4231 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4232 self.waitUntilSettled()
4233
4234 self.sched.reconfigure(self.config)
4235
4236 # Make sure the items still share a change queue, and the
4237 # first one is not live.
4238 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 1)
4239 queue = self.sched.layout.pipelines['check'].queues[0]
4240 first_item = queue.queue[0]
4241 for item in queue.queue:
4242 self.assertEqual(item.queue, first_item.queue)
4243 self.assertFalse(first_item.live)
4244 self.assertTrue(queue.queue[1].live)
4245
4246 self.gearman_server.hold_jobs_in_queue = False
4247 self.gearman_server.release()
4248 self.waitUntilSettled()
4249
4250 self.assertEqual(A.data['status'], 'NEW')
4251 self.assertEqual(B.data['status'], 'NEW')
4252 self.assertEqual(A.reported, 1)
4253 self.assertEqual(B.reported, 0)
4254
4255 self.assertEqual(self.history[0].changes, '2,1 1,1')
4256 self.assertEqual(len(self.sched.layout.pipelines['check'].queues), 0)
James E. Blair17dd6772015-02-09 14:45:18 -08004257
James E. Blairec056492016-07-22 09:45:56 -07004258 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004259 def test_crd_check_reconfiguration(self):
4260 self._test_crd_check_reconfiguration('org/project1', 'org/project2')
4261
James E. Blairec056492016-07-22 09:45:56 -07004262 @skip("Disabled for early v3 development")
Evgeny Antyshev0deaaad2015-08-03 20:22:56 +00004263 def test_crd_undefined_project(self):
4264 """Test that undefined projects in dependencies are handled for
4265 independent pipelines"""
4266 # It's a hack for fake gerrit,
4267 # as it implies repo creation upon the creation of any change
4268 self.init_repo("org/unknown")
4269 self._test_crd_check_reconfiguration('org/project1', 'org/unknown')
4270
James E. Blairec056492016-07-22 09:45:56 -07004271 @skip("Disabled for early v3 development")
James E. Blair17dd6772015-02-09 14:45:18 -08004272 def test_crd_check_ignore_dependencies(self):
4273 "Test cross-repo dependencies can be ignored"
James E. Blairf84026c2015-12-08 16:11:46 -08004274 self.updateConfigLayout(
4275 'tests/fixtures/layout-ignore-dependencies.yaml')
James E. Blair17dd6772015-02-09 14:45:18 -08004276 self.sched.reconfigure(self.config)
4277 self.registerJobs()
4278
4279 self.gearman_server.hold_jobs_in_queue = True
4280 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4281 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4282 C = self.fake_gerrit.addFakeChange('org/project2', 'master', 'C')
4283
4284 # A Depends-On: B
4285 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4286 A.subject, B.data['id'])
4287 # C git-depends on B
4288 C.setDependsOn(B, 1)
4289 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4290 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4291 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4292 self.waitUntilSettled()
4293
4294 # Make sure none of the items share a change queue, and all
4295 # are live.
4296 check_pipeline = self.sched.layout.pipelines['check']
4297 self.assertEqual(len(check_pipeline.queues), 3)
4298 self.assertEqual(len(check_pipeline.getAllItems()), 3)
4299 for item in check_pipeline.getAllItems():
4300 self.assertTrue(item.live)
4301
4302 self.gearman_server.hold_jobs_in_queue = False
4303 self.gearman_server.release()
4304 self.waitUntilSettled()
4305
4306 self.assertEqual(A.data['status'], 'NEW')
4307 self.assertEqual(B.data['status'], 'NEW')
4308 self.assertEqual(C.data['status'], 'NEW')
4309 self.assertEqual(A.reported, 1)
4310 self.assertEqual(B.reported, 1)
4311 self.assertEqual(C.reported, 1)
4312
4313 # Each job should have tested exactly one change
4314 for job in self.history:
4315 self.assertEqual(len(job.changes.split()), 1)
James E. Blair96698e22015-04-02 07:48:21 -07004316
James E. Blairec056492016-07-22 09:45:56 -07004317 @skip("Disabled for early v3 development")
James E. Blair96698e22015-04-02 07:48:21 -07004318 def test_crd_check_transitive(self):
4319 "Test transitive cross-repo dependencies"
4320 # Specifically, if A -> B -> C, and C gets a new patchset and
4321 # A gets a new patchset, ensure the test of A,2 includes B,1
4322 # and C,2 (not C,1 which would indicate stale data in the
4323 # cache for B).
4324 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
4325 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
4326 C = self.fake_gerrit.addFakeChange('org/project3', 'master', 'C')
4327
4328 # A Depends-On: B
4329 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4330 A.subject, B.data['id'])
4331
4332 # B Depends-On: C
4333 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4334 B.subject, C.data['id'])
4335
4336 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4337 self.waitUntilSettled()
4338 self.assertEqual(self.history[-1].changes, '3,1 2,1 1,1')
4339
4340 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4341 self.waitUntilSettled()
4342 self.assertEqual(self.history[-1].changes, '3,1 2,1')
4343
4344 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4345 self.waitUntilSettled()
4346 self.assertEqual(self.history[-1].changes, '3,1')
4347
4348 C.addPatchset()
4349 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(2))
4350 self.waitUntilSettled()
4351 self.assertEqual(self.history[-1].changes, '3,2')
4352
4353 A.addPatchset()
4354 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
4355 self.waitUntilSettled()
4356 self.assertEqual(self.history[-1].changes, '3,2 2,1 1,2')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004357
James E. Blairec056492016-07-22 09:45:56 -07004358 @skip("Disabled for early v3 development")
James E. Blair92464a22016-04-05 10:21:26 -07004359 def test_crd_cycle_join(self):
4360 "Test an updated change creates a cycle"
4361 A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A')
4362
4363 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4364 self.waitUntilSettled()
4365
4366 # Create B->A
4367 B = self.fake_gerrit.addFakeChange('org/project1', 'master', 'B')
4368 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4369 B.subject, A.data['id'])
4370 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4371 self.waitUntilSettled()
4372
4373 # Update A to add A->B (a cycle).
4374 A.addPatchset()
4375 A.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
4376 A.subject, B.data['id'])
4377 # Normally we would submit the patchset-created event for
4378 # processing here, however, we have no way of noting whether
4379 # the dependency cycle detection correctly raised an
4380 # exception, so instead, we reach into the source driver and
4381 # call the method that would ultimately be called by the event
4382 # processing.
4383
4384 source = self.sched.layout.pipelines['gate'].source
4385 with testtools.ExpectedException(
4386 Exception, "Dependency cycle detected"):
4387 source._getChange(u'1', u'2', True)
4388 self.log.debug("Got expected dependency cycle exception")
4389
4390 # Now if we update B to remove the depends-on, everything
4391 # should be okay. B; A->B
4392
4393 B.addPatchset()
4394 B.data['commitMessage'] = '%s\n' % (B.subject,)
4395 source._getChange(u'1', u'2', True)
4396 source._getChange(u'2', u'2', True)
4397
James E. Blairec056492016-07-22 09:45:56 -07004398 @skip("Disabled for early v3 development")
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004399 def test_disable_at(self):
4400 "Test a pipeline will only report to the disabled trigger when failing"
4401
James E. Blairf84026c2015-12-08 16:11:46 -08004402 self.updateConfigLayout(
4403 'tests/fixtures/layout-disable-at.yaml')
Joshua Hesketh89e829d2015-02-10 16:29:45 +11004404 self.sched.reconfigure(self.config)
4405
4406 self.assertEqual(3, self.sched.layout.pipelines['check'].disable_at)
4407 self.assertEqual(
4408 0, self.sched.layout.pipelines['check']._consecutive_failures)
4409 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4410
4411 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
4412 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
4413 C = self.fake_gerrit.addFakeChange('org/project', 'master', 'C')
4414 D = self.fake_gerrit.addFakeChange('org/project', 'master', 'D')
4415 E = self.fake_gerrit.addFakeChange('org/project', 'master', 'E')
4416 F = self.fake_gerrit.addFakeChange('org/project', 'master', 'F')
4417 G = self.fake_gerrit.addFakeChange('org/project', 'master', 'G')
4418 H = self.fake_gerrit.addFakeChange('org/project', 'master', 'H')
4419 I = self.fake_gerrit.addFakeChange('org/project', 'master', 'I')
4420 J = self.fake_gerrit.addFakeChange('org/project', 'master', 'J')
4421 K = self.fake_gerrit.addFakeChange('org/project', 'master', 'K')
4422
4423 self.worker.addFailTest('project-test1', A)
4424 self.worker.addFailTest('project-test1', B)
4425 # Let C pass, resetting the counter
4426 self.worker.addFailTest('project-test1', D)
4427 self.worker.addFailTest('project-test1', E)
4428 self.worker.addFailTest('project-test1', F)
4429 self.worker.addFailTest('project-test1', G)
4430 self.worker.addFailTest('project-test1', H)
4431 # I also passes but should only report to the disabled reporters
4432 self.worker.addFailTest('project-test1', J)
4433 self.worker.addFailTest('project-test1', K)
4434
4435 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4436 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
4437 self.waitUntilSettled()
4438
4439 self.assertEqual(
4440 2, self.sched.layout.pipelines['check']._consecutive_failures)
4441 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4442
4443 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
4444 self.waitUntilSettled()
4445
4446 self.assertEqual(
4447 0, self.sched.layout.pipelines['check']._consecutive_failures)
4448 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4449
4450 self.fake_gerrit.addEvent(D.getPatchsetCreatedEvent(1))
4451 self.fake_gerrit.addEvent(E.getPatchsetCreatedEvent(1))
4452 self.fake_gerrit.addEvent(F.getPatchsetCreatedEvent(1))
4453 self.waitUntilSettled()
4454
4455 # We should be disabled now
4456 self.assertEqual(
4457 3, self.sched.layout.pipelines['check']._consecutive_failures)
4458 self.assertTrue(self.sched.layout.pipelines['check']._disabled)
4459
4460 # We need to wait between each of these patches to make sure the
4461 # smtp messages come back in an expected order
4462 self.fake_gerrit.addEvent(G.getPatchsetCreatedEvent(1))
4463 self.waitUntilSettled()
4464 self.fake_gerrit.addEvent(H.getPatchsetCreatedEvent(1))
4465 self.waitUntilSettled()
4466 self.fake_gerrit.addEvent(I.getPatchsetCreatedEvent(1))
4467 self.waitUntilSettled()
4468
4469 # The first 6 (ABCDEF) jobs should have reported back to gerrt thus
4470 # leaving a message on each change
4471 self.assertEqual(1, len(A.messages))
4472 self.assertIn('Build failed.', A.messages[0])
4473 self.assertEqual(1, len(B.messages))
4474 self.assertIn('Build failed.', B.messages[0])
4475 self.assertEqual(1, len(C.messages))
4476 self.assertIn('Build succeeded.', C.messages[0])
4477 self.assertEqual(1, len(D.messages))
4478 self.assertIn('Build failed.', D.messages[0])
4479 self.assertEqual(1, len(E.messages))
4480 self.assertIn('Build failed.', E.messages[0])
4481 self.assertEqual(1, len(F.messages))
4482 self.assertIn('Build failed.', F.messages[0])
4483
4484 # The last 3 (GHI) would have only reported via smtp.
4485 self.assertEqual(3, len(self.smtp_messages))
4486 self.assertEqual(0, len(G.messages))
4487 self.assertIn('Build failed.', self.smtp_messages[0]['body'])
4488 self.assertIn('/7/1/check', self.smtp_messages[0]['body'])
4489 self.assertEqual(0, len(H.messages))
4490 self.assertIn('Build failed.', self.smtp_messages[1]['body'])
4491 self.assertIn('/8/1/check', self.smtp_messages[1]['body'])
4492 self.assertEqual(0, len(I.messages))
4493 self.assertIn('Build succeeded.', self.smtp_messages[2]['body'])
4494 self.assertIn('/9/1/check', self.smtp_messages[2]['body'])
4495
4496 # Now reload the configuration (simulate a HUP) to check the pipeline
4497 # comes out of disabled
4498 self.sched.reconfigure(self.config)
4499
4500 self.assertEqual(3, self.sched.layout.pipelines['check'].disable_at)
4501 self.assertEqual(
4502 0, self.sched.layout.pipelines['check']._consecutive_failures)
4503 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4504
4505 self.fake_gerrit.addEvent(J.getPatchsetCreatedEvent(1))
4506 self.fake_gerrit.addEvent(K.getPatchsetCreatedEvent(1))
4507 self.waitUntilSettled()
4508
4509 self.assertEqual(
4510 2, self.sched.layout.pipelines['check']._consecutive_failures)
4511 self.assertFalse(self.sched.layout.pipelines['check']._disabled)
4512
4513 # J and K went back to gerrit
4514 self.assertEqual(1, len(J.messages))
4515 self.assertIn('Build failed.', J.messages[0])
4516 self.assertEqual(1, len(K.messages))
4517 self.assertIn('Build failed.', K.messages[0])
4518 # No more messages reported via smtp
4519 self.assertEqual(3, len(self.smtp_messages))
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004520
James E. Blairec056492016-07-22 09:45:56 -07004521 @skip("Disabled for early v3 development")
Joshua Heskethd6dbd682015-12-22 10:06:54 +11004522 def test_success_pattern(self):
4523 "Ensure bad build params are ignored"
4524
4525 # Use SMTP reporter to grab the result message easier
4526 self.init_repo("org/docs")
4527 self.config.set('zuul', 'layout_config',
4528 'tests/fixtures/layout-success-pattern.yaml')
4529 self.sched.reconfigure(self.config)
4530 self.worker.hold_jobs_in_build = True
4531 self.registerJobs()
4532
4533 A = self.fake_gerrit.addFakeChange('org/docs', 'master', 'A')
4534 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
4535 self.waitUntilSettled()
4536
4537 # Grab build id
4538 self.assertEqual(len(self.builds), 1)
4539 uuid = self.builds[0].unique[:7]
4540
4541 self.worker.hold_jobs_in_build = False
4542 self.worker.release()
4543 self.waitUntilSettled()
4544
4545 self.assertEqual(len(self.smtp_messages), 1)
4546 body = self.smtp_messages[0]['body'].splitlines()
4547 self.assertEqual('Build succeeded.', body[0])
4548
4549 self.assertIn(
4550 '- docs-draft-test http://docs-draft.example.org/1/1/1/check/'
4551 'docs-draft-test/%s/publish-docs/' % uuid,
4552 body[2])
4553 self.assertIn(
4554 '- docs-draft-test2 https://server/job/docs-draft-test2/1/',
4555 body[3])