blob: c24a9debfc1ff084bbc2c0b508dac47ecf14b41d [file] [log] [blame]
James E. Blair59fdbac2015-12-07 17:08:06 -08001#!/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. Blaira00910c2017-08-23 09:15:04 -070017import json
James E. Blaira92cbc82017-01-23 14:56:49 -080018import os
James E. Blair14abdf42015-12-09 16:11:53 -080019import textwrap
James E. Blair59fdbac2015-12-07 17:08:06 -080020
James E. Blairb9c0d772017-03-03 14:34:49 -080021import testtools
22
23import zuul.configloader
James E. Blairbf1a4f22017-03-17 10:59:37 -070024from zuul.lib import encryption
Ricardo Carrillo Cruz22994f92016-12-02 11:41:58 +000025from tests.base import AnsibleZuulTestCase, ZuulTestCase, FIXTURE_DIR
James E. Blair59fdbac2015-12-07 17:08:06 -080026
James E. Blair59fdbac2015-12-07 17:08:06 -080027
James E. Blair3f876d52016-07-22 13:07:14 -070028class TestMultipleTenants(AnsibleZuulTestCase):
James E. Blair59fdbac2015-12-07 17:08:06 -080029 # A temporary class to hold new tests while others are disabled
30
James E. Blair2a629ec2015-12-22 15:32:02 -080031 tenant_config_file = 'config/multi-tenant/main.yaml'
James E. Blair59fdbac2015-12-07 17:08:06 -080032
James E. Blair83005782015-12-11 14:46:03 -080033 def test_multiple_tenants(self):
James E. Blair96f26942015-12-09 10:15:59 -080034 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
Tobias Henkelbf24fd12017-07-27 06:13:07 +020035 A.addApproval('Code-Review', 2)
36 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blair59fdbac2015-12-07 17:08:06 -080037 self.waitUntilSettled()
James E. Blair96f26942015-12-09 10:15:59 -080038 self.assertEqual(self.getJobFromHistory('project1-test1').result,
James E. Blair59fdbac2015-12-07 17:08:06 -080039 'SUCCESS')
James E. Blair96c6bf82016-01-15 16:20:40 -080040 self.assertEqual(self.getJobFromHistory('python27').result,
41 'SUCCESS')
James E. Blair59fdbac2015-12-07 17:08:06 -080042 self.assertEqual(A.data['status'], 'MERGED')
James E. Blair96f26942015-12-09 10:15:59 -080043 self.assertEqual(A.reported, 2,
44 "A should report start and success")
45 self.assertIn('tenant-one-gate', A.messages[1],
46 "A should transit tenant-one gate")
47 self.assertNotIn('tenant-two-gate', A.messages[1],
48 "A should *not* transit tenant-two gate")
James E. Blair59fdbac2015-12-07 17:08:06 -080049
James E. Blair96f26942015-12-09 10:15:59 -080050 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
Tobias Henkelbf24fd12017-07-27 06:13:07 +020051 B.addApproval('Code-Review', 2)
52 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
James E. Blair96f26942015-12-09 10:15:59 -080053 self.waitUntilSettled()
James E. Blair96c6bf82016-01-15 16:20:40 -080054 self.assertEqual(self.getJobFromHistory('python27',
55 'org/project2').result,
56 'SUCCESS')
James E. Blair96f26942015-12-09 10:15:59 -080057 self.assertEqual(self.getJobFromHistory('project2-test1').result,
58 'SUCCESS')
59 self.assertEqual(B.data['status'], 'MERGED')
60 self.assertEqual(B.reported, 2,
61 "B should report start and success")
62 self.assertIn('tenant-two-gate', B.messages[1],
63 "B should transit tenant-two gate")
64 self.assertNotIn('tenant-one-gate', B.messages[1],
65 "B should *not* transit tenant-one gate")
James E. Blair59fdbac2015-12-07 17:08:06 -080066
James E. Blair96f26942015-12-09 10:15:59 -080067 self.assertEqual(A.reported, 2, "Activity in tenant two should"
68 "not affect tenant one")
James E. Blair14abdf42015-12-09 16:11:53 -080069
James E. Blair83005782015-12-11 14:46:03 -080070
Tobias Henkel83167622017-06-30 19:45:03 +020071class TestFinal(ZuulTestCase):
72
73 tenant_config_file = 'config/final/main.yaml'
74
75 def test_final_variant_ok(self):
76 # test clean usage of final parent job
77 in_repo_conf = textwrap.dedent(
78 """
79 - project:
80 name: org/project
81 check:
82 jobs:
83 - job-final
84 """)
85
86 file_dict = {'.zuul.yaml': in_repo_conf}
87 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
88 files=file_dict)
89 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
90 self.waitUntilSettled()
91
92 self.assertEqual(A.reported, 1)
93 self.assertEqual(A.patchsets[-1]['approvals'][0]['value'], '1')
94
95 def test_final_variant_error(self):
96 # test misuse of final parent job
97 in_repo_conf = textwrap.dedent(
98 """
99 - project:
100 name: org/project
101 check:
102 jobs:
103 - job-final:
104 vars:
105 dont_override_this: bar
106 """)
107 file_dict = {'.zuul.yaml': in_repo_conf}
108 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
109 files=file_dict)
110 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
111 self.waitUntilSettled()
112
113 # The second patch tried to override some variables.
114 # Thus it should fail.
115 self.assertEqual(A.reported, 1)
116 self.assertEqual(A.patchsets[-1]['approvals'][0]['value'], '-1')
117 self.assertIn('Unable to modify final job', A.messages[0])
118
119 def test_final_inheritance(self):
120 # test misuse of final parent job
121 in_repo_conf = textwrap.dedent(
122 """
123 - job:
124 name: project-test
125 parent: job-final
126
127 - project:
128 name: org/project
129 check:
130 jobs:
131 - project-test
132 """)
133
134 in_repo_playbook = textwrap.dedent(
135 """
136 - hosts: all
137 tasks: []
138 """)
139
140 file_dict = {'.zuul.yaml': in_repo_conf,
141 'playbooks/project-test.yaml': in_repo_playbook}
142 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
143 files=file_dict)
144 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
145 self.waitUntilSettled()
146
147 # The second patch tried to override some variables.
148 # Thus it should fail.
149 self.assertEqual(A.reported, 1)
150 self.assertEqual(A.patchsets[-1]['approvals'][0]['value'], '-1')
151 self.assertIn('Unable to inherit from final job', A.messages[0])
152
153
James E. Blairff555742017-02-19 11:34:27 -0800154class TestInRepoConfig(ZuulTestCase):
James E. Blair83005782015-12-11 14:46:03 -0800155 # A temporary class to hold new tests while others are disabled
156
Tobias Henkelabf973e2017-07-28 10:07:34 +0200157 config_file = 'zuul-connections-gerrit-and-github.conf'
James E. Blair2a629ec2015-12-22 15:32:02 -0800158 tenant_config_file = 'config/in-repo/main.yaml'
James E. Blair83005782015-12-11 14:46:03 -0800159
James E. Blair83005782015-12-11 14:46:03 -0800160 def test_in_repo_config(self):
James E. Blair14abdf42015-12-09 16:11:53 -0800161 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200162 A.addApproval('Code-Review', 2)
163 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blair14abdf42015-12-09 16:11:53 -0800164 self.waitUntilSettled()
165 self.assertEqual(self.getJobFromHistory('project-test1').result,
166 'SUCCESS')
167 self.assertEqual(A.data['status'], 'MERGED')
168 self.assertEqual(A.reported, 2,
169 "A should report start and success")
170 self.assertIn('tenant-one-gate', A.messages[1],
171 "A should transit tenant-one gate")
James E. Blairb97ed802015-12-21 15:55:35 -0800172
James E. Blair8b1dc3f2016-07-05 16:49:00 -0700173 def test_dynamic_config(self):
174 in_repo_conf = textwrap.dedent(
175 """
176 - job:
Tobias Henkelf02cf512017-07-21 22:55:34 +0200177 name: project-test1
178
179 - job:
James E. Blair8b1dc3f2016-07-05 16:49:00 -0700180 name: project-test2
181
182 - project:
183 name: org/project
184 tenant-one-gate:
185 jobs:
186 - project-test2
187 """)
188
James E. Blairc73c73a2017-01-20 15:15:15 -0800189 in_repo_playbook = textwrap.dedent(
190 """
191 - hosts: all
192 tasks: []
193 """)
194
195 file_dict = {'.zuul.yaml': in_repo_conf,
196 'playbooks/project-test2.yaml': in_repo_playbook}
James E. Blair8b1dc3f2016-07-05 16:49:00 -0700197 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
James E. Blairc73c73a2017-01-20 15:15:15 -0800198 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200199 A.addApproval('Code-Review', 2)
200 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blair8b1dc3f2016-07-05 16:49:00 -0700201 self.waitUntilSettled()
James E. Blair8b1dc3f2016-07-05 16:49:00 -0700202 self.assertEqual(A.data['status'], 'MERGED')
203 self.assertEqual(A.reported, 2,
204 "A should report start and success")
205 self.assertIn('tenant-one-gate', A.messages[1],
206 "A should transit tenant-one gate")
James E. Blair646322f2017-01-27 15:50:34 -0800207 self.assertHistory([
208 dict(name='project-test2', result='SUCCESS', changes='1,1')])
209
James E. Blairc2a5ed72017-02-20 14:12:01 -0500210 self.fake_gerrit.addEvent(A.getChangeMergedEvent())
James E. Blair7bbd7a32017-03-06 11:36:13 -0800211 self.waitUntilSettled()
James E. Blairc2a5ed72017-02-20 14:12:01 -0500212
James E. Blair646322f2017-01-27 15:50:34 -0800213 # Now that the config change is landed, it should be live for
214 # subsequent changes.
215 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200216 B.addApproval('Code-Review', 2)
217 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
James E. Blair646322f2017-01-27 15:50:34 -0800218 self.waitUntilSettled()
219 self.assertEqual(self.getJobFromHistory('project-test2').result,
220 'SUCCESS')
221 self.assertHistory([
222 dict(name='project-test2', result='SUCCESS', changes='1,1'),
223 dict(name='project-test2', result='SUCCESS', changes='2,1')])
James E. Blairc73c73a2017-01-20 15:15:15 -0800224
Tobias Henkelf02cf512017-07-21 22:55:34 +0200225 def test_dynamic_config_non_existing_job(self):
226 """Test that requesting a non existent job fails"""
227 in_repo_conf = textwrap.dedent(
228 """
229 - job:
230 name: project-test1
231
232 - project:
233 name: org/project
234 check:
235 jobs:
236 - non-existent-job
237 """)
238
239 in_repo_playbook = textwrap.dedent(
240 """
241 - hosts: all
242 tasks: []
243 """)
244
245 file_dict = {'.zuul.yaml': in_repo_conf,
246 'playbooks/project-test2.yaml': in_repo_playbook}
247 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
248 files=file_dict)
249 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
250 self.waitUntilSettled()
251 self.assertEqual(A.reported, 1,
252 "A should report failure")
253 self.assertEqual(A.patchsets[0]['approvals'][0]['value'], "-1")
254 self.assertIn('Job non-existent-job not defined', A.messages[0],
255 "A should have failed the check pipeline")
256 self.assertHistory([])
257
258 def test_dynamic_config_non_existing_job_in_template(self):
259 """Test that requesting a non existent job fails"""
260 in_repo_conf = textwrap.dedent(
261 """
262 - job:
263 name: project-test1
264
265 - project-template:
266 name: test-template
267 check:
268 jobs:
269 - non-existent-job
270
271 - project:
272 name: org/project
273 templates:
274 - test-template
275 """)
276
277 in_repo_playbook = textwrap.dedent(
278 """
279 - hosts: all
280 tasks: []
281 """)
282
283 file_dict = {'.zuul.yaml': in_repo_conf,
284 'playbooks/project-test2.yaml': in_repo_playbook}
285 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
286 files=file_dict)
287 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
288 self.waitUntilSettled()
289 self.assertEqual(A.reported, 1,
290 "A should report failure")
291 self.assertEqual(A.patchsets[0]['approvals'][0]['value'], "-1")
292 self.assertIn('Job non-existent-job not defined', A.messages[0],
293 "A should have failed the check pipeline")
294 self.assertHistory([])
295
Tobias Henkel0f714002017-06-30 23:30:52 +0200296 def test_dynamic_config_new_patchset(self):
297 self.executor_server.hold_jobs_in_build = True
298
299 tenant = self.sched.abide.tenants.get('tenant-one')
300 check_pipeline = tenant.layout.pipelines['check']
301
302 in_repo_conf = textwrap.dedent(
303 """
304 - job:
Tobias Henkelf02cf512017-07-21 22:55:34 +0200305 name: project-test1
306
307 - job:
Tobias Henkel0f714002017-06-30 23:30:52 +0200308 name: project-test2
309
310 - project:
311 name: org/project
312 check:
313 jobs:
314 - project-test2
315 """)
316
317 in_repo_playbook = textwrap.dedent(
318 """
319 - hosts: all
320 tasks: []
321 """)
322
323 file_dict = {'.zuul.yaml': in_repo_conf,
324 'playbooks/project-test2.yaml': in_repo_playbook}
325 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
326 files=file_dict)
327 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
328 self.waitUntilSettled()
329
330 items = check_pipeline.getAllItems()
331 self.assertEqual(items[0].change.number, '1')
332 self.assertEqual(items[0].change.patchset, '1')
333 self.assertTrue(items[0].live)
334
335 in_repo_conf = textwrap.dedent(
336 """
337 - job:
Tobias Henkel0ce7ec62017-07-21 22:50:17 +0200338 name: project-test1
339
340 - job:
Tobias Henkel0f714002017-06-30 23:30:52 +0200341 name: project-test2
342
343 - project:
344 name: org/project
345 check:
346 jobs:
347 - project-test1
348 - project-test2
349 """)
350 file_dict = {'.zuul.yaml': in_repo_conf,
351 'playbooks/project-test2.yaml': in_repo_playbook}
352
353 A.addPatchset(files=file_dict)
354 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(2))
355
356 self.waitUntilSettled()
357
358 items = check_pipeline.getAllItems()
359 self.assertEqual(items[0].change.number, '1')
360 self.assertEqual(items[0].change.patchset, '2')
361 self.assertTrue(items[0].live)
362
363 self.executor_server.hold_jobs_in_build = False
Tobias Henkel0ce7ec62017-07-21 22:50:17 +0200364 self.executor_server.release('project-test1')
365 self.waitUntilSettled()
Tobias Henkel0f714002017-06-30 23:30:52 +0200366 self.executor_server.release()
367 self.waitUntilSettled()
368
Tobias Henkel0ce7ec62017-07-21 22:50:17 +0200369 self.assertHistory([
370 dict(name='project-test2', result='ABORTED', changes='1,1'),
371 dict(name='project-test1', result='SUCCESS', changes='1,2'),
372 dict(name='project-test2', result='SUCCESS', changes='1,2')])
373
James E. Blairff555742017-02-19 11:34:27 -0800374 def test_in_repo_branch(self):
375 in_repo_conf = textwrap.dedent(
376 """
377 - job:
Tobias Henkelf02cf512017-07-21 22:55:34 +0200378 name: project-test1
379
380 - job:
James E. Blairff555742017-02-19 11:34:27 -0800381 name: project-test2
382
383 - project:
384 name: org/project
385 tenant-one-gate:
386 jobs:
387 - project-test2
388 """)
389
390 in_repo_playbook = textwrap.dedent(
391 """
392 - hosts: all
393 tasks: []
394 """)
395
396 file_dict = {'.zuul.yaml': in_repo_conf,
397 'playbooks/project-test2.yaml': in_repo_playbook}
398 self.create_branch('org/project', 'stable')
James E. Blair72facdc2017-08-17 10:29:12 -0700399 self.fake_gerrit.addEvent(
400 self.fake_gerrit.getFakeBranchCreatedEvent(
401 'org/project', 'stable'))
James E. Blairff555742017-02-19 11:34:27 -0800402 A = self.fake_gerrit.addFakeChange('org/project', 'stable', 'A',
403 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200404 A.addApproval('Code-Review', 2)
405 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blairff555742017-02-19 11:34:27 -0800406 self.waitUntilSettled()
407 self.assertEqual(A.data['status'], 'MERGED')
408 self.assertEqual(A.reported, 2,
409 "A should report start and success")
410 self.assertIn('tenant-one-gate', A.messages[1],
411 "A should transit tenant-one gate")
412 self.assertHistory([
413 dict(name='project-test2', result='SUCCESS', changes='1,1')])
414 self.fake_gerrit.addEvent(A.getChangeMergedEvent())
James E. Blair7bbd7a32017-03-06 11:36:13 -0800415 self.waitUntilSettled()
James E. Blairff555742017-02-19 11:34:27 -0800416
417 # The config change should not affect master.
418 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200419 B.addApproval('Code-Review', 2)
420 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
James E. Blairff555742017-02-19 11:34:27 -0800421 self.waitUntilSettled()
422 self.assertHistory([
423 dict(name='project-test2', result='SUCCESS', changes='1,1'),
424 dict(name='project-test1', result='SUCCESS', changes='2,1')])
425
426 # The config change should be live for further changes on
427 # stable.
428 C = self.fake_gerrit.addFakeChange('org/project', 'stable', 'C')
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200429 C.addApproval('Code-Review', 2)
430 self.fake_gerrit.addEvent(C.addApproval('Approved', 1))
James E. Blairff555742017-02-19 11:34:27 -0800431 self.waitUntilSettled()
432 self.assertHistory([
433 dict(name='project-test2', result='SUCCESS', changes='1,1'),
434 dict(name='project-test1', result='SUCCESS', changes='2,1'),
435 dict(name='project-test2', result='SUCCESS', changes='3,1')])
436
James E. Blaira5a12492017-05-03 11:40:48 -0700437 def test_crd_dynamic_config_branch(self):
438 # Test that we can create a job in one repo and be able to use
439 # it from a different branch on a different repo.
440
441 self.create_branch('org/project1', 'stable')
James E. Blair72facdc2017-08-17 10:29:12 -0700442 self.fake_gerrit.addEvent(
443 self.fake_gerrit.getFakeBranchCreatedEvent(
444 'org/project1', 'stable'))
James E. Blaira5a12492017-05-03 11:40:48 -0700445
446 in_repo_conf = textwrap.dedent(
447 """
448 - job:
Tobias Henkelf02cf512017-07-21 22:55:34 +0200449 name: project-test1
450
451 - job:
James E. Blaira5a12492017-05-03 11:40:48 -0700452 name: project-test2
453
454 - project:
455 name: org/project
456 check:
457 jobs:
458 - project-test2
459 """)
460
461 in_repo_playbook = textwrap.dedent(
462 """
463 - hosts: all
464 tasks: []
465 """)
466
467 file_dict = {'.zuul.yaml': in_repo_conf,
468 'playbooks/project-test2.yaml': in_repo_playbook}
469 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
470 files=file_dict)
471
472 second_repo_conf = textwrap.dedent(
473 """
474 - project:
475 name: org/project1
476 check:
477 jobs:
478 - project-test2
479 """)
480
481 second_file_dict = {'.zuul.yaml': second_repo_conf}
482 B = self.fake_gerrit.addFakeChange('org/project1', 'stable', 'B',
483 files=second_file_dict)
484 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
485 B.subject, A.data['id'])
486
487 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
488 self.waitUntilSettled()
489 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
490 self.waitUntilSettled()
491
492 self.assertEqual(A.reported, 1, "A should report")
493 self.assertHistory([
494 dict(name='project-test2', result='SUCCESS', changes='1,1'),
495 dict(name='project-test2', result='SUCCESS', changes='1,1 2,1'),
496 ])
497
James E. Blair97043882017-09-06 15:51:17 -0700498 def test_yaml_list_error(self):
499 in_repo_conf = textwrap.dedent(
500 """
501 job: foo
502 """)
503
504 file_dict = {'.zuul.yaml': in_repo_conf}
505 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
506 files=file_dict)
507 A.addApproval('Code-Review', 2)
508 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
509 self.waitUntilSettled()
510
511 self.assertEqual(A.data['status'], 'NEW')
512 self.assertEqual(A.reported, 1,
513 "A should report failure")
514 self.assertIn('not a list', A.messages[0],
515 "A should have a syntax error reported")
516
517 def test_yaml_dict_error(self):
518 in_repo_conf = textwrap.dedent(
519 """
520 - job
521 """)
522
523 file_dict = {'.zuul.yaml': in_repo_conf}
524 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
525 files=file_dict)
526 A.addApproval('Code-Review', 2)
527 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
528 self.waitUntilSettled()
529
530 self.assertEqual(A.data['status'], 'NEW')
531 self.assertEqual(A.reported, 1,
532 "A should report failure")
533 self.assertIn('not a dictionary', A.messages[0],
534 "A should have a syntax error reported")
535
536 def test_yaml_key_error(self):
537 in_repo_conf = textwrap.dedent(
538 """
539 - job:
540 name: project-test2
541 """)
542
543 file_dict = {'.zuul.yaml': in_repo_conf}
544 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
545 files=file_dict)
546 A.addApproval('Code-Review', 2)
547 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
548 self.waitUntilSettled()
549
550 self.assertEqual(A.data['status'], 'NEW')
551 self.assertEqual(A.reported, 1,
552 "A should report failure")
553 self.assertIn('has more than one key', A.messages[0],
554 "A should have a syntax error reported")
555
556 def test_yaml_unknown_error(self):
557 in_repo_conf = textwrap.dedent(
558 """
559 - foobar:
560 foo: bar
561 """)
562
563 file_dict = {'.zuul.yaml': in_repo_conf}
564 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
565 files=file_dict)
566 A.addApproval('Code-Review', 2)
567 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
568 self.waitUntilSettled()
569
570 self.assertEqual(A.data['status'], 'NEW')
571 self.assertEqual(A.reported, 1,
572 "A should report failure")
573 self.assertIn('not recognized', A.messages[0],
574 "A should have a syntax error reported")
575
James E. Blair149b69c2017-03-02 10:48:16 -0800576 def test_untrusted_syntax_error(self):
James E. Blaire53250c2017-03-01 14:34:36 -0800577 in_repo_conf = textwrap.dedent(
578 """
579 - job:
580 name: project-test2
581 foo: error
582 """)
583
584 file_dict = {'.zuul.yaml': in_repo_conf}
585 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
586 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200587 A.addApproval('Code-Review', 2)
588 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blaire53250c2017-03-01 14:34:36 -0800589 self.waitUntilSettled()
590
591 self.assertEqual(A.data['status'], 'NEW')
Tobias Henkel9842bd72017-05-16 13:40:03 +0200592 self.assertEqual(A.reported, 1,
593 "A should report failure")
594 self.assertIn('syntax error', A.messages[0],
James E. Blaire53250c2017-03-01 14:34:36 -0800595 "A should have a syntax error reported")
596
James E. Blair149b69c2017-03-02 10:48:16 -0800597 def test_trusted_syntax_error(self):
598 in_repo_conf = textwrap.dedent(
599 """
600 - job:
601 name: project-test2
602 foo: error
603 """)
604
605 file_dict = {'zuul.yaml': in_repo_conf}
606 A = self.fake_gerrit.addFakeChange('common-config', 'master', 'A',
607 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200608 A.addApproval('Code-Review', 2)
609 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blair149b69c2017-03-02 10:48:16 -0800610 self.waitUntilSettled()
611
612 self.assertEqual(A.data['status'], 'NEW')
Tobias Henkel9842bd72017-05-16 13:40:03 +0200613 self.assertEqual(A.reported, 1,
614 "A should report failure")
615 self.assertIn('syntax error', A.messages[0],
James E. Blair149b69c2017-03-02 10:48:16 -0800616 "A should have a syntax error reported")
617
James E. Blair6f140c72017-03-03 10:32:07 -0800618 def test_untrusted_yaml_error(self):
619 in_repo_conf = textwrap.dedent(
620 """
621 - job:
622 foo: error
623 """)
624
625 file_dict = {'.zuul.yaml': in_repo_conf}
626 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
627 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200628 A.addApproval('Code-Review', 2)
629 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blair6f140c72017-03-03 10:32:07 -0800630 self.waitUntilSettled()
631
632 self.assertEqual(A.data['status'], 'NEW')
Tobias Henkel9842bd72017-05-16 13:40:03 +0200633 self.assertEqual(A.reported, 1,
634 "A should report failure")
635 self.assertIn('syntax error', A.messages[0],
James E. Blair6f140c72017-03-03 10:32:07 -0800636 "A should have a syntax error reported")
637
James E. Blairdb04e6a2017-05-03 14:49:36 -0700638 def test_untrusted_shadow_error(self):
639 in_repo_conf = textwrap.dedent(
640 """
641 - job:
642 name: common-config-test
643 """)
644
645 file_dict = {'.zuul.yaml': in_repo_conf}
646 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
647 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200648 A.addApproval('Code-Review', 2)
649 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blairdb04e6a2017-05-03 14:49:36 -0700650 self.waitUntilSettled()
651
652 self.assertEqual(A.data['status'], 'NEW')
Tobias Henkel9842bd72017-05-16 13:40:03 +0200653 self.assertEqual(A.reported, 1,
654 "A should report failure")
655 self.assertIn('not permitted to shadow', A.messages[0],
James E. Blairdb04e6a2017-05-03 14:49:36 -0700656 "A should have a syntax error reported")
657
James E. Blaird5656ad2017-06-02 14:29:41 -0700658 def test_untrusted_pipeline_error(self):
659 in_repo_conf = textwrap.dedent(
660 """
661 - pipeline:
662 name: test
663 """)
664
665 file_dict = {'.zuul.yaml': in_repo_conf}
666 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
667 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200668 A.addApproval('Code-Review', 2)
669 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blaird5656ad2017-06-02 14:29:41 -0700670 self.waitUntilSettled()
671
672 self.assertEqual(A.data['status'], 'NEW')
673 self.assertEqual(A.reported, 1,
674 "A should report failure")
675 self.assertIn('Pipelines may not be defined', A.messages[0],
676 "A should have a syntax error reported")
677
678 def test_untrusted_project_error(self):
679 in_repo_conf = textwrap.dedent(
680 """
681 - project:
682 name: org/project1
683 """)
684
685 file_dict = {'.zuul.yaml': in_repo_conf}
686 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
687 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200688 A.addApproval('Code-Review', 2)
689 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blaird5656ad2017-06-02 14:29:41 -0700690 self.waitUntilSettled()
691
692 self.assertEqual(A.data['status'], 'NEW')
693 self.assertEqual(A.reported, 1,
694 "A should report failure")
695 self.assertIn('the only project definition permitted', A.messages[0],
696 "A should have a syntax error reported")
697
James E. Blaire64b0e42017-06-08 11:23:34 -0700698 def test_duplicate_node_error(self):
699 in_repo_conf = textwrap.dedent(
700 """
701 - nodeset:
702 name: duplicate
703 nodes:
704 - name: compute
James E. Blair16d96a02017-06-08 11:32:56 -0700705 label: foo
James E. Blaire64b0e42017-06-08 11:23:34 -0700706 - name: compute
James E. Blair16d96a02017-06-08 11:32:56 -0700707 label: foo
James E. Blaire64b0e42017-06-08 11:23:34 -0700708 """)
709
710 file_dict = {'.zuul.yaml': in_repo_conf}
711 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
712 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200713 A.addApproval('Code-Review', 2)
714 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blaire64b0e42017-06-08 11:23:34 -0700715 self.waitUntilSettled()
716
717 self.assertEqual(A.data['status'], 'NEW')
718 self.assertEqual(A.reported, 1,
719 "A should report failure")
720 self.assertIn('appears multiple times', A.messages[0],
721 "A should have a syntax error reported")
722
723 def test_duplicate_group_error(self):
724 in_repo_conf = textwrap.dedent(
725 """
726 - nodeset:
727 name: duplicate
728 nodes:
729 - name: compute
James E. Blair16d96a02017-06-08 11:32:56 -0700730 label: foo
James E. Blaire64b0e42017-06-08 11:23:34 -0700731 groups:
732 - name: group
733 nodes: compute
734 - name: group
735 nodes: compute
736 """)
737
738 file_dict = {'.zuul.yaml': in_repo_conf}
739 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
740 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200741 A.addApproval('Code-Review', 2)
742 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blaire64b0e42017-06-08 11:23:34 -0700743 self.waitUntilSettled()
744
745 self.assertEqual(A.data['status'], 'NEW')
746 self.assertEqual(A.reported, 1,
747 "A should report failure")
748 self.assertIn('appears multiple times', A.messages[0],
749 "A should have a syntax error reported")
750
James E. Blair4ae399f2017-09-20 17:15:09 -0700751 def test_secret_not_found_error(self):
752 in_repo_conf = textwrap.dedent(
753 """
754 - job:
755 name: test
756 secrets: does-not-exist
757 """)
758
759 file_dict = {'.zuul.yaml': in_repo_conf}
760 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
761 files=file_dict)
762 A.addApproval('Code-Review', 2)
763 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
764 self.waitUntilSettled()
765
766 self.assertEqual(A.data['status'], 'NEW')
767 self.assertEqual(A.reported, 1,
768 "A should report failure")
769 self.assertIn('secret "does-not-exist" was not found', A.messages[0],
770 "A should have a syntax error reported")
771
772 def test_nodeset_not_found_error(self):
773 in_repo_conf = textwrap.dedent(
774 """
775 - job:
776 name: test
777 nodeset: does-not-exist
778 """)
779
780 file_dict = {'.zuul.yaml': in_repo_conf}
781 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
782 files=file_dict)
783 A.addApproval('Code-Review', 2)
784 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
785 self.waitUntilSettled()
786
787 self.assertEqual(A.data['status'], 'NEW')
788 self.assertEqual(A.reported, 1,
789 "A should report failure")
790 self.assertIn('nodeset "does-not-exist" was not found', A.messages[0],
791 "A should have a syntax error reported")
792
James E. Blair89e25eb2017-09-26 09:11:31 -0700793 def test_template_not_found_error(self):
794 in_repo_conf = textwrap.dedent(
795 """
796 - job:
797 name: project-test1
798 - project:
799 name: org/project
800 templates:
801 - does-not-exist
802 """)
803
804 file_dict = {'.zuul.yaml': in_repo_conf}
805 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
806 files=file_dict)
807 A.addApproval('Code-Review', 2)
808 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
809 self.waitUntilSettled()
810
811 self.assertEqual(A.data['status'], 'NEW')
812 self.assertEqual(A.reported, 1,
813 "A should report failure")
814 self.assertIn('project template "does-not-exist" was not found',
815 A.messages[0],
816 "A should have a syntax error reported")
817
James E. Blair09f9ffe2017-07-11 15:30:25 -0700818 def test_multi_repo(self):
819 downstream_repo_conf = textwrap.dedent(
820 """
821 - project:
822 name: org/project1
823 tenant-one-gate:
824 jobs:
825 - project-test1
826
827 - job:
828 name: project1-test1
829 parent: project-test1
830 """)
831
832 file_dict = {'.zuul.yaml': downstream_repo_conf}
833 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A',
834 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200835 A.addApproval('Code-Review', 2)
836 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blair09f9ffe2017-07-11 15:30:25 -0700837 self.waitUntilSettled()
838
839 self.assertEqual(A.data['status'], 'MERGED')
840 self.fake_gerrit.addEvent(A.getChangeMergedEvent())
841 self.waitUntilSettled()
842
843 upstream_repo_conf = textwrap.dedent(
844 """
845 - job:
846 name: project-test1
847
848 - job:
849 name: project-test2
850
851 - project:
852 name: org/project
853 tenant-one-gate:
854 jobs:
855 - project-test1
856 """)
857
858 file_dict = {'.zuul.yaml': upstream_repo_conf}
859 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B',
860 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200861 B.addApproval('Code-Review', 2)
862 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
James E. Blair09f9ffe2017-07-11 15:30:25 -0700863 self.waitUntilSettled()
864
865 self.assertEqual(B.data['status'], 'MERGED')
866 self.fake_gerrit.addEvent(B.getChangeMergedEvent())
867 self.waitUntilSettled()
868
869 tenant = self.sched.abide.tenants.get('tenant-one')
870 # Ensure the latest change is reflected in the config; if it
871 # isn't this will raise an exception.
872 tenant.layout.getJob('project-test2')
873
James E. Blair332636e2017-09-05 10:14:35 -0700874 def test_pipeline_error(self):
875 with open(os.path.join(FIXTURE_DIR,
876 'config/in-repo/git/',
877 'common-config/zuul.yaml')) as f:
878 base_common_config = f.read()
879
880 in_repo_conf_A = textwrap.dedent(
881 """
882 - pipeline:
883 name: periodic
884 foo: error
885 """)
886
887 file_dict = {'zuul.yaml': None,
888 'zuul.d/main.yaml': base_common_config,
889 'zuul.d/test1.yaml': in_repo_conf_A}
890 A = self.fake_gerrit.addFakeChange('common-config', 'master', 'A',
891 files=file_dict)
892 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
893 self.waitUntilSettled()
894 self.assertEqual(A.reported, 1,
895 "A should report failure")
896 self.assertIn('syntax error',
897 A.messages[0],
898 "A should have an error reported")
899
900 def test_change_series_error(self):
901 with open(os.path.join(FIXTURE_DIR,
902 'config/in-repo/git/',
903 'common-config/zuul.yaml')) as f:
904 base_common_config = f.read()
905
906 in_repo_conf_A = textwrap.dedent(
907 """
908 - pipeline:
909 name: periodic
910 foo: error
911 """)
912
913 file_dict = {'zuul.yaml': None,
914 'zuul.d/main.yaml': base_common_config,
915 'zuul.d/test1.yaml': in_repo_conf_A}
916 A = self.fake_gerrit.addFakeChange('common-config', 'master', 'A',
917 files=file_dict)
918
919 in_repo_conf_B = textwrap.dedent(
920 """
921 - job:
922 name: project-test2
923 foo: error
924 """)
925
926 file_dict = {'zuul.yaml': None,
927 'zuul.d/main.yaml': base_common_config,
928 'zuul.d/test1.yaml': in_repo_conf_A,
929 'zuul.d/test2.yaml': in_repo_conf_B}
930 B = self.fake_gerrit.addFakeChange('common-config', 'master', 'B',
931 files=file_dict)
932 B.setDependsOn(A, 1)
933 C = self.fake_gerrit.addFakeChange('common-config', 'master', 'C')
934 C.setDependsOn(B, 1)
935 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
936 self.waitUntilSettled()
937
938 self.assertEqual(C.reported, 1,
939 "C should report failure")
940 self.assertIn('depends on a change that failed to merge',
941 C.messages[0],
942 "C should have an error reported")
943
James E. Blairc73c73a2017-01-20 15:15:15 -0800944
James E. Blairc9455002017-09-06 09:22:19 -0700945class TestInRepoJoin(ZuulTestCase):
946 # In this config, org/project is not a member of any pipelines, so
947 # that we may test the changes that cause it to join them.
948
949 tenant_config_file = 'config/in-repo-join/main.yaml'
950
951 def test_dynamic_dependent_pipeline(self):
952 # Test dynamically adding a project to a
953 # dependent pipeline for the first time
954 self.executor_server.hold_jobs_in_build = True
955
956 tenant = self.sched.abide.tenants.get('tenant-one')
957 gate_pipeline = tenant.layout.pipelines['gate']
958
959 in_repo_conf = textwrap.dedent(
960 """
961 - job:
962 name: project-test1
963
964 - job:
965 name: project-test2
966
967 - project:
968 name: org/project
969 gate:
970 jobs:
971 - project-test2
972 """)
973
974 in_repo_playbook = textwrap.dedent(
975 """
976 - hosts: all
977 tasks: []
978 """)
979
980 file_dict = {'.zuul.yaml': in_repo_conf,
981 'playbooks/project-test2.yaml': in_repo_playbook}
982 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
983 files=file_dict)
984 A.addApproval('Code-Review', 2)
985 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
986 self.waitUntilSettled()
987
988 items = gate_pipeline.getAllItems()
989 self.assertEqual(items[0].change.number, '1')
990 self.assertEqual(items[0].change.patchset, '1')
991 self.assertTrue(items[0].live)
992
993 self.executor_server.hold_jobs_in_build = False
994 self.executor_server.release()
995 self.waitUntilSettled()
996
997 # Make sure the dynamic queue got cleaned up
998 self.assertEqual(gate_pipeline.queues, [])
999
1000 def test_dynamic_dependent_pipeline_failure(self):
1001 # Test that a change behind a failing change adding a project
1002 # to a dependent pipeline is dequeued.
1003 self.executor_server.hold_jobs_in_build = True
1004
1005 in_repo_conf = textwrap.dedent(
1006 """
1007 - job:
1008 name: project-test1
1009
1010 - project:
1011 name: org/project
1012 gate:
1013 jobs:
1014 - project-test1
1015 """)
1016
1017 file_dict = {'.zuul.yaml': in_repo_conf}
1018 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1019 files=file_dict)
1020 self.executor_server.failJob('project-test1', A)
1021 A.addApproval('Code-Review', 2)
1022 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
1023 self.waitUntilSettled()
1024
1025 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1026 B.addApproval('Code-Review', 2)
1027 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
1028 self.waitUntilSettled()
1029
James E. Blair3490c5d2017-09-07 08:33:23 -07001030 self.orderedRelease()
James E. Blairc9455002017-09-06 09:22:19 -07001031 self.waitUntilSettled()
1032 self.assertEqual(A.reported, 2,
1033 "A should report start and failure")
1034 self.assertEqual(A.data['status'], 'NEW')
1035 self.assertEqual(B.reported, 1,
1036 "B should report start")
1037 self.assertHistory([
1038 dict(name='project-test1', result='FAILURE', changes='1,1'),
James E. Blair3490c5d2017-09-07 08:33:23 -07001039 dict(name='project-test1', result='ABORTED', changes='1,1 2,1'),
James E. Blairc9455002017-09-06 09:22:19 -07001040 ], ordered=False)
1041
James E. Blair0af198f2017-09-06 09:52:35 -07001042 def test_dynamic_dependent_pipeline_absent(self):
1043 # Test that a series of dependent changes don't report merge
1044 # failures to a pipeline they aren't in.
1045 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1046 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1047 B.setDependsOn(A, 1)
1048
1049 A.addApproval('Code-Review', 2)
1050 A.addApproval('Approved', 1)
1051 B.addApproval('Code-Review', 2)
1052 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
1053 self.waitUntilSettled()
1054 self.assertEqual(A.reported, 0,
1055 "A should not report")
1056 self.assertEqual(A.data['status'], 'NEW')
1057 self.assertEqual(B.reported, 0,
1058 "B should not report")
1059 self.assertEqual(B.data['status'], 'NEW')
1060 self.assertHistory([])
1061
James E. Blairc9455002017-09-06 09:22:19 -07001062
James E. Blairc73c73a2017-01-20 15:15:15 -08001063class TestAnsible(AnsibleZuulTestCase):
1064 # A temporary class to hold new tests while others are disabled
1065
1066 tenant_config_file = 'config/ansible/main.yaml'
1067
1068 def test_playbook(self):
Jamie Lennox7655b552017-03-17 12:33:38 +11001069 # Keep the jobdir around so we can inspect contents if an
1070 # assert fails.
1071 self.executor_server.keep_jobdir = True
1072 # Output extra ansible info so we might see errors.
1073 self.executor_server.verbose = True
1074 # Add a site variables file, used by check-vars
1075 path = os.path.join(FIXTURE_DIR, 'config', 'ansible',
1076 'variables.yaml')
1077 self.config.set('executor', 'variables', path)
James E. Blairc73c73a2017-01-20 15:15:15 -08001078 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1079 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1080 self.waitUntilSettled()
Tobias Henkel077f2f32017-05-30 20:16:46 +02001081 build_timeout = self.getJobFromHistory('timeout')
Jamie Lennox7655b552017-03-17 12:33:38 +11001082 with self.jobLog(build_timeout):
1083 self.assertEqual(build_timeout.result, 'TIMED_OUT')
Tobias Henkel077f2f32017-05-30 20:16:46 +02001084 build_faillocal = self.getJobFromHistory('faillocal')
Jamie Lennox7655b552017-03-17 12:33:38 +11001085 with self.jobLog(build_faillocal):
1086 self.assertEqual(build_faillocal.result, 'FAILURE')
Tobias Henkel077f2f32017-05-30 20:16:46 +02001087 build_failpost = self.getJobFromHistory('failpost')
Jamie Lennox7655b552017-03-17 12:33:38 +11001088 with self.jobLog(build_failpost):
1089 self.assertEqual(build_failpost.result, 'POST_FAILURE')
Tobias Henkel077f2f32017-05-30 20:16:46 +02001090 build_check_vars = self.getJobFromHistory('check-vars')
Jamie Lennox7655b552017-03-17 12:33:38 +11001091 with self.jobLog(build_check_vars):
1092 self.assertEqual(build_check_vars.result, 'SUCCESS')
Monty Tayloraff8b402017-08-16 18:40:41 -05001093 build_check_secret_names = self.getJobFromHistory('check-secret-names')
1094 with self.jobLog(build_check_secret_names):
1095 self.assertEqual(build_check_secret_names.result, 'SUCCESS')
Tobias Henkel077f2f32017-05-30 20:16:46 +02001096 build_hello = self.getJobFromHistory('hello-world')
Jamie Lennox7655b552017-03-17 12:33:38 +11001097 with self.jobLog(build_hello):
1098 self.assertEqual(build_hello.result, 'SUCCESS')
Tobias Henkel077f2f32017-05-30 20:16:46 +02001099 build_python27 = self.getJobFromHistory('python27')
Jamie Lennox7655b552017-03-17 12:33:38 +11001100 with self.jobLog(build_python27):
1101 self.assertEqual(build_python27.result, 'SUCCESS')
1102 flag_path = os.path.join(self.test_root,
1103 build_python27.uuid + '.flag')
1104 self.assertTrue(os.path.exists(flag_path))
1105 copied_path = os.path.join(self.test_root, build_python27.uuid +
1106 '.copied')
1107 self.assertTrue(os.path.exists(copied_path))
1108 failed_path = os.path.join(self.test_root, build_python27.uuid +
1109 '.failed')
1110 self.assertFalse(os.path.exists(failed_path))
1111 pre_flag_path = os.path.join(self.test_root, build_python27.uuid +
1112 '.pre.flag')
1113 self.assertTrue(os.path.exists(pre_flag_path))
1114 post_flag_path = os.path.join(self.test_root, build_python27.uuid +
1115 '.post.flag')
1116 self.assertTrue(os.path.exists(post_flag_path))
1117 bare_role_flag_path = os.path.join(self.test_root,
1118 build_python27.uuid +
1119 '.bare-role.flag')
1120 self.assertTrue(os.path.exists(bare_role_flag_path))
1121 secrets_path = os.path.join(self.test_root,
1122 build_python27.uuid + '.secrets')
1123 with open(secrets_path) as f:
1124 self.assertEqual(f.read(), "test-username test-password")
James E. Blairb9c0d772017-03-03 14:34:49 -08001125
Jamie Lennox7655b552017-03-17 12:33:38 +11001126 msg = A.messages[0]
1127 success = "{} https://success.example.com/zuul-logs/{}"
1128 fail = "{} https://failure.example.com/zuul-logs/{}"
1129 self.assertIn(success.format("python27", build_python27.uuid), msg)
1130 self.assertIn(fail.format("faillocal", build_faillocal.uuid), msg)
1131 self.assertIn(success.format("check-vars",
1132 build_check_vars.uuid), msg)
1133 self.assertIn(success.format("hello-world", build_hello.uuid), msg)
1134 self.assertIn(fail.format("timeout", build_timeout.uuid), msg)
1135 self.assertIn(fail.format("failpost", build_failpost.uuid), msg)
Tobias Henkel077f2f32017-05-30 20:16:46 +02001136
James E. Blairabbaa6f2017-04-06 16:11:44 -07001137 def _add_job(self, job_name):
1138 conf = textwrap.dedent(
1139 """
1140 - job:
1141 name: %s
1142
1143 - project:
1144 name: org/plugin-project
1145 check:
1146 jobs:
1147 - %s
1148 """ % (job_name, job_name))
1149
1150 file_dict = {'.zuul.yaml': conf}
1151 A = self.fake_gerrit.addFakeChange('org/plugin-project', 'master', 'A',
1152 files=file_dict)
1153 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1154 self.waitUntilSettled()
1155
1156 def test_plugins(self):
1157 # Keep the jobdir around so we can inspect contents if an
1158 # assert fails.
1159 self.executor_server.keep_jobdir = True
1160 # Output extra ansible info so we might see errors.
1161 self.executor_server.verbose = True
1162
1163 count = 0
1164 plugin_tests = [
1165 ('passwd', 'FAILURE'),
1166 ('cartesian', 'SUCCESS'),
1167 ('consul_kv', 'FAILURE'),
1168 ('credstash', 'FAILURE'),
1169 ('csvfile_good', 'SUCCESS'),
1170 ('csvfile_bad', 'FAILURE'),
Monty Taylor93ad2212017-08-02 14:59:50 -05001171 ('uri_bad_path', 'FAILURE'),
1172 ('uri_bad_scheme', 'FAILURE'),
Monty Taylor788a40e2017-08-02 16:14:05 -05001173 ('block_local_override', 'FAILURE'),
Monty Taylor8da768f2017-08-31 14:15:35 -05001174 ('file_local_good', 'SUCCESS'),
1175 ('file_local_bad', 'FAILURE'),
James E. Blairabbaa6f2017-04-06 16:11:44 -07001176 ]
1177 for job_name, result in plugin_tests:
1178 count += 1
1179 self._add_job(job_name)
1180
1181 job = self.getJobFromHistory(job_name)
1182 with self.jobLog(job):
1183 self.assertEqual(count, len(self.history))
1184 build = self.history[-1]
1185 self.assertEqual(build.result, result)
1186
1187 # TODOv3(jeblair): parse the ansible output and verify we're
1188 # getting the exception we expect.
1189
James E. Blairb9c0d772017-03-03 14:34:49 -08001190
James E. Blaira4d4eef2017-06-30 14:49:17 -07001191class TestPrePlaybooks(AnsibleZuulTestCase):
1192 # A temporary class to hold new tests while others are disabled
1193
1194 tenant_config_file = 'config/pre-playbook/main.yaml'
1195
1196 def test_pre_playbook_fail(self):
1197 # Test that we run the post playbooks (but not the actual
1198 # playbook) when a pre-playbook fails.
1199 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1200 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1201 self.waitUntilSettled()
1202 build = self.getJobFromHistory('python27')
1203 self.assertIsNone(build.result)
1204 self.assertIn('RETRY_LIMIT', A.messages[0])
1205 flag_path = os.path.join(self.test_root, build.uuid +
1206 '.main.flag')
1207 self.assertFalse(os.path.exists(flag_path))
1208 pre_flag_path = os.path.join(self.test_root, build.uuid +
1209 '.pre.flag')
1210 self.assertFalse(os.path.exists(pre_flag_path))
1211 post_flag_path = os.path.join(self.test_root, build.uuid +
1212 '.post.flag')
James E. Blair21037782017-07-19 11:56:55 -07001213 self.assertTrue(os.path.exists(post_flag_path),
1214 "The file %s should exist" % post_flag_path)
James E. Blaira4d4eef2017-06-30 14:49:17 -07001215
1216
James E. Blairb9c0d772017-03-03 14:34:49 -08001217class TestBrokenConfig(ZuulTestCase):
1218 # Test that we get an appropriate syntax error if we start with a
1219 # broken config.
1220
1221 tenant_config_file = 'config/broken/main.yaml'
1222
1223 def setUp(self):
1224 with testtools.ExpectedException(
1225 zuul.configloader.ConfigurationSyntaxError,
1226 "\nZuul encountered a syntax error"):
1227 super(TestBrokenConfig, self).setUp()
1228
1229 def test_broken_config_on_startup(self):
1230 pass
Ricardo Carrillo Cruz22994f92016-12-02 11:41:58 +00001231
1232
1233class TestProjectKeys(ZuulTestCase):
1234 # Test that we can generate project keys
1235
1236 # Normally the test infrastructure copies a static key in place
1237 # for each project before starting tests. This saves time because
1238 # Zuul's automatic key-generation on startup can be slow. To make
1239 # sure we exercise that code, in this test we allow Zuul to create
1240 # keys for the project on startup.
1241 create_project_keys = True
Tobias Henkelabf973e2017-07-28 10:07:34 +02001242 config_file = 'zuul-connections-gerrit-and-github.conf'
Ricardo Carrillo Cruz22994f92016-12-02 11:41:58 +00001243 tenant_config_file = 'config/in-repo/main.yaml'
1244
1245 def test_key_generation(self):
1246 key_root = os.path.join(self.state_root, 'keys')
1247 private_key_file = os.path.join(key_root, 'gerrit/org/project.pem')
1248 # Make sure that a proper key was created on startup
1249 with open(private_key_file, "rb") as f:
James E. Blairbf1a4f22017-03-17 10:59:37 -07001250 private_key, public_key = \
1251 encryption.deserialize_rsa_keypair(f.read())
Ricardo Carrillo Cruz22994f92016-12-02 11:41:58 +00001252
1253 with open(os.path.join(FIXTURE_DIR, 'private.pem')) as i:
1254 fixture_private_key = i.read()
1255
1256 # Make sure that we didn't just end up with the static fixture
1257 # key
1258 self.assertNotEqual(fixture_private_key, private_key)
1259
1260 # Make sure it's the right length
1261 self.assertEqual(4096, private_key.key_size)
James E. Blairbce76932017-05-04 10:03:15 -07001262
1263
James E. Blairbb94dfa2017-07-11 07:45:19 -07001264class RoleTestCase(ZuulTestCase):
James E. Blair1b27f6a2017-07-14 14:09:07 -07001265 def _assertRolePath(self, build, playbook, content):
1266 path = os.path.join(self.test_root, build.uuid,
1267 'ansible', playbook, 'ansible.cfg')
1268 roles_paths = []
1269 with open(path) as f:
1270 for line in f:
1271 if line.startswith('roles_path'):
1272 roles_paths.append(line)
1273 print(roles_paths)
1274 if content:
1275 self.assertEqual(len(roles_paths), 1,
1276 "Should have one roles_path line in %s" %
1277 (playbook,))
1278 self.assertIn(content, roles_paths[0])
1279 else:
1280 self.assertEqual(len(roles_paths), 0,
1281 "Should have no roles_path line in %s" %
1282 (playbook,))
1283
James E. Blairbb94dfa2017-07-11 07:45:19 -07001284
1285class TestRoles(RoleTestCase):
1286 tenant_config_file = 'config/roles/main.yaml'
1287
James E. Blairbce76932017-05-04 10:03:15 -07001288 def test_role(self):
1289 # This exercises a proposed change to a role being checked out
1290 # and used.
1291 A = self.fake_gerrit.addFakeChange('bare-role', 'master', 'A')
1292 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1293 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
1294 B.subject, A.data['id'])
1295 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1296 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1297 self.waitUntilSettled()
1298 self.assertHistory([
1299 dict(name='project-test', result='SUCCESS', changes='1,1 2,1'),
1300 ])
James E. Blair6459db12017-06-29 14:57:20 -07001301
James E. Blair1b27f6a2017-07-14 14:09:07 -07001302 def test_role_inheritance(self):
1303 self.executor_server.hold_jobs_in_build = True
1304 conf = textwrap.dedent(
1305 """
1306 - job:
1307 name: parent
1308 roles:
1309 - zuul: bare-role
1310 pre-run: playbooks/parent-pre
1311 post-run: playbooks/parent-post
1312
1313 - job:
1314 name: project-test
1315 parent: parent
1316 roles:
1317 - zuul: org/project
1318
1319 - project:
1320 name: org/project
1321 check:
1322 jobs:
1323 - project-test
1324 """)
1325
1326 file_dict = {'.zuul.yaml': conf}
1327 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1328 files=file_dict)
1329 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1330 self.waitUntilSettled()
1331
1332 self.assertEqual(len(self.builds), 1)
1333 build = self.getBuildByName('project-test')
1334 self._assertRolePath(build, 'pre_playbook_0', 'role_0')
1335 self._assertRolePath(build, 'playbook_0', 'role_0')
1336 self._assertRolePath(build, 'playbook_0', 'role_1')
1337 self._assertRolePath(build, 'post_playbook_0', 'role_0')
1338
1339 self.executor_server.hold_jobs_in_build = False
1340 self.executor_server.release()
1341 self.waitUntilSettled()
1342
1343 self.assertHistory([
1344 dict(name='project-test', result='SUCCESS', changes='1,1'),
1345 ])
1346
James E. Blair6f699732017-07-18 14:19:11 -07001347 def test_role_error(self):
1348 conf = textwrap.dedent(
1349 """
1350 - job:
1351 name: project-test
1352 roles:
1353 - zuul: common-config
1354
1355 - project:
1356 name: org/project
1357 check:
1358 jobs:
1359 - project-test
1360 """)
1361
1362 file_dict = {'.zuul.yaml': conf}
1363 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1364 files=file_dict)
1365 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1366 self.waitUntilSettled()
1367 self.assertIn(
1368 '- project-test project-test : ERROR Unable to find role',
1369 A.messages[-1])
1370
James E. Blair6459db12017-06-29 14:57:20 -07001371
James E. Blairbb94dfa2017-07-11 07:45:19 -07001372class TestImplicitRoles(RoleTestCase):
1373 tenant_config_file = 'config/implicit-roles/main.yaml'
1374
1375 def test_missing_roles(self):
1376 # Test implicit and explicit roles for a project which does
1377 # not have roles. The implicit role should be silently
1378 # ignored since the project doesn't supply roles, but if a
1379 # user declares an explicit role, it should error.
1380 self.executor_server.hold_jobs_in_build = True
1381 A = self.fake_gerrit.addFakeChange('org/norole-project', 'master', 'A')
1382 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1383 self.waitUntilSettled()
1384
1385 self.assertEqual(len(self.builds), 2)
1386 build = self.getBuildByName('implicit-role-fail')
1387 self._assertRolePath(build, 'playbook_0', None)
1388
1389 self.executor_server.hold_jobs_in_build = False
1390 self.executor_server.release()
1391 self.waitUntilSettled()
1392 # The retry_limit doesn't get recorded
1393 self.assertHistory([
1394 dict(name='implicit-role-fail', result='SUCCESS', changes='1,1'),
1395 ])
1396
1397 def test_roles(self):
1398 # Test implicit and explicit roles for a project which does
1399 # have roles. In both cases, we should end up with the role
1400 # in the path. In the explicit case, ensure we end up with
1401 # the name we specified.
1402 self.executor_server.hold_jobs_in_build = True
1403 A = self.fake_gerrit.addFakeChange('org/role-project', 'master', 'A')
1404 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1405 self.waitUntilSettled()
1406
1407 self.assertEqual(len(self.builds), 2)
1408 build = self.getBuildByName('implicit-role-ok')
1409 self._assertRolePath(build, 'playbook_0', 'role_0')
1410
1411 build = self.getBuildByName('explicit-role-ok')
1412 self._assertRolePath(build, 'playbook_0', 'role_0')
1413
1414 self.executor_server.hold_jobs_in_build = False
1415 self.executor_server.release()
1416 self.waitUntilSettled()
1417 self.assertHistory([
1418 dict(name='implicit-role-ok', result='SUCCESS', changes='1,1'),
1419 dict(name='explicit-role-ok', result='SUCCESS', changes='1,1'),
1420 ], ordered=False)
1421
1422
James E. Blair6459db12017-06-29 14:57:20 -07001423class TestShadow(ZuulTestCase):
1424 tenant_config_file = 'config/shadow/main.yaml'
1425
1426 def test_shadow(self):
1427 # Test that a repo is allowed to shadow another's job definitions.
1428 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1429 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1430 self.waitUntilSettled()
1431 self.assertHistory([
1432 dict(name='test1', result='SUCCESS', changes='1,1'),
1433 dict(name='test2', result='SUCCESS', changes='1,1'),
James E. Blairadafa6c2017-07-12 08:50:56 -07001434 ], ordered=False)
James E. Blair196f61a2017-06-30 15:42:29 -07001435
1436
1437class TestDataReturn(AnsibleZuulTestCase):
1438 tenant_config_file = 'config/data-return/main.yaml'
1439
1440 def test_data_return(self):
1441 # This exercises a proposed change to a role being checked out
1442 # and used.
1443 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1444 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1445 self.waitUntilSettled()
1446 self.assertHistory([
1447 dict(name='data-return', result='SUCCESS', changes='1,1'),
James E. Blair88e79c02017-07-07 13:36:54 -07001448 dict(name='data-return-relative', result='SUCCESS', changes='1,1'),
1449 ], ordered=False)
1450 self.assertIn('- data-return http://example.com/test/log/url/',
1451 A.messages[-1])
1452 self.assertIn('- data-return-relative '
1453 'http://example.com/test/log/url/docs/index.html',
James E. Blair196f61a2017-06-30 15:42:29 -07001454 A.messages[-1])
Clint Byrumdc8a0902017-07-20 16:36:27 -07001455
1456
1457class TestDiskAccounting(AnsibleZuulTestCase):
1458 config_file = 'zuul-disk-accounting.conf'
1459 tenant_config_file = 'config/disk-accountant/main.yaml'
1460
1461 def test_disk_accountant_kills_job(self):
1462 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1463 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1464 self.waitUntilSettled()
1465 self.assertHistory([
1466 dict(name='dd-big-empty-file', result='ABORTED', changes='1,1')])
Tristan Cacqueray82f864b2017-08-01 05:54:42 +00001467
1468
1469class TestMaxNodesPerJob(AnsibleZuulTestCase):
1470 tenant_config_file = 'config/multi-tenant/main.yaml'
1471
Tristan Cacquerayc98bff72017-09-10 15:25:26 +00001472 def test_max_timeout_exceeded(self):
Tristan Cacqueray82f864b2017-08-01 05:54:42 +00001473 in_repo_conf = textwrap.dedent(
1474 """
1475 - job:
1476 name: test-job
James E. Blair7e3e6882017-09-20 15:47:13 -07001477 nodeset:
1478 nodes:
1479 - name: node01
1480 label: fake
1481 - name: node02
1482 label: fake
1483 - name: node03
1484 label: fake
1485 - name: node04
1486 label: fake
1487 - name: node05
1488 label: fake
1489 - name: node06
1490 label: fake
Tristan Cacqueray82f864b2017-08-01 05:54:42 +00001491 """)
1492 file_dict = {'.zuul.yaml': in_repo_conf}
1493 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A',
1494 files=file_dict)
1495 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1496 self.waitUntilSettled()
1497 self.assertIn('The job "test-job" exceeds tenant max-nodes-per-job 5.',
1498 A.messages[0], "A should fail because of nodes limit")
1499
1500 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A',
1501 files=file_dict)
1502 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1503 self.waitUntilSettled()
1504 self.assertNotIn("exceeds tenant max-nodes", B.messages[0],
1505 "B should not fail because of nodes limit")
James E. Blair2bab6e72017-08-07 09:52:45 -07001506
1507
Tristan Cacquerayc98bff72017-09-10 15:25:26 +00001508class TestMaxTimeout(AnsibleZuulTestCase):
1509 tenant_config_file = 'config/multi-tenant/main.yaml'
1510
1511 def test_max_nodes_reached(self):
1512 in_repo_conf = textwrap.dedent(
1513 """
1514 - job:
1515 name: test-job
1516 timeout: 3600
1517 """)
1518 file_dict = {'.zuul.yaml': in_repo_conf}
1519 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A',
1520 files=file_dict)
1521 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1522 self.waitUntilSettled()
1523 self.assertIn('The job "test-job" exceeds tenant max-job-timeout',
1524 A.messages[0], "A should fail because of timeout limit")
1525
1526 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A',
1527 files=file_dict)
1528 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1529 self.waitUntilSettled()
1530 self.assertNotIn("exceeds tenant max-job-timeout", B.messages[0],
1531 "B should not fail because of timeout limit")
1532
1533
James E. Blair2bab6e72017-08-07 09:52:45 -07001534class TestBaseJobs(ZuulTestCase):
1535 tenant_config_file = 'config/base-jobs/main.yaml'
1536
1537 def test_multiple_base_jobs(self):
1538 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1539 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1540 self.waitUntilSettled()
1541 self.assertHistory([
1542 dict(name='my-job', result='SUCCESS', changes='1,1'),
1543 dict(name='other-job', result='SUCCESS', changes='1,1'),
1544 ], ordered=False)
1545 self.assertEqual(self.getJobFromHistory('my-job').
1546 parameters['zuul']['jobtags'],
1547 ['mybase'])
1548 self.assertEqual(self.getJobFromHistory('other-job').
1549 parameters['zuul']['jobtags'],
1550 ['otherbase'])
1551
1552 def test_untrusted_base_job(self):
1553 """Test that a base job may not be defined in an untrusted repo"""
1554 in_repo_conf = textwrap.dedent(
1555 """
1556 - job:
1557 name: fail-base
1558 parent: null
1559 """)
1560
1561 file_dict = {'.zuul.yaml': in_repo_conf}
1562 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1563 files=file_dict)
1564 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1565 self.waitUntilSettled()
1566 self.assertEqual(A.reported, 1,
1567 "A should report failure")
1568 self.assertEqual(A.patchsets[0]['approvals'][0]['value'], "-1")
1569 self.assertIn('Base jobs must be defined in config projects',
1570 A.messages[0])
1571 self.assertHistory([])
James E. Blairdb089032017-08-15 13:42:12 -07001572
1573
1574class TestSecretLeaks(AnsibleZuulTestCase):
1575 tenant_config_file = 'config/secret-leaks/main.yaml'
1576
1577 def searchForContent(self, path, content):
1578 matches = []
1579 for (dirpath, dirnames, filenames) in os.walk(path):
1580 for filename in filenames:
1581 filepath = os.path.join(dirpath, filename)
1582 with open(filepath, 'rb') as f:
1583 if content in f.read():
1584 matches.append(filepath[len(path):])
1585 return matches
1586
1587 def _test_secret_file(self):
1588 # Or rather -- test that they *don't* leak.
1589 # Keep the jobdir around so we can inspect contents.
1590 self.executor_server.keep_jobdir = True
1591 conf = textwrap.dedent(
1592 """
1593 - project:
1594 name: org/project
1595 check:
1596 jobs:
1597 - secret-file
1598 """)
1599
1600 file_dict = {'.zuul.yaml': conf}
1601 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1602 files=file_dict)
1603 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1604 self.waitUntilSettled()
1605 self.assertHistory([
1606 dict(name='secret-file', result='SUCCESS', changes='1,1'),
1607 ], ordered=False)
1608 matches = self.searchForContent(self.history[0].jobdir.root,
1609 b'test-password')
James E. Blaird6a71ca2017-08-18 14:15:05 -07001610 self.assertEqual(set(['/work/secret-file.txt']),
James E. Blairdb089032017-08-15 13:42:12 -07001611 set(matches))
1612
1613 def test_secret_file(self):
1614 self._test_secret_file()
1615
1616 def test_secret_file_verbose(self):
1617 # Output extra ansible info to exercise alternate logging code
1618 # paths.
1619 self.executor_server.verbose = True
1620 self._test_secret_file()
1621
1622 def _test_secret_file_fail(self):
1623 # Or rather -- test that they *don't* leak.
1624 # Keep the jobdir around so we can inspect contents.
1625 self.executor_server.keep_jobdir = True
1626 conf = textwrap.dedent(
1627 """
1628 - project:
1629 name: org/project
1630 check:
1631 jobs:
1632 - secret-file-fail
1633 """)
1634
1635 file_dict = {'.zuul.yaml': conf}
1636 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1637 files=file_dict)
1638 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1639 self.waitUntilSettled()
1640 self.assertHistory([
1641 dict(name='secret-file-fail', result='FAILURE', changes='1,1'),
1642 ], ordered=False)
1643 matches = self.searchForContent(self.history[0].jobdir.root,
1644 b'test-password')
James E. Blaird6a71ca2017-08-18 14:15:05 -07001645 self.assertEqual(set(['/work/failure-file.txt']),
James E. Blairdb089032017-08-15 13:42:12 -07001646 set(matches))
1647
1648 def test_secret_file_fail(self):
1649 self._test_secret_file_fail()
1650
1651 def test_secret_file_fail_verbose(self):
1652 # Output extra ansible info to exercise alternate logging code
1653 # paths.
1654 self.executor_server.verbose = True
1655 self._test_secret_file_fail()
James E. Blaira00910c2017-08-23 09:15:04 -07001656
1657
1658class TestJobOutput(AnsibleZuulTestCase):
1659 tenant_config_file = 'config/job-output/main.yaml'
1660
1661 def _get_file(self, build, path):
1662 p = os.path.join(build.jobdir.root, path)
1663 with open(p) as f:
1664 return f.read()
1665
1666 def test_job_output(self):
1667 # Verify that command standard output appears in the job output
1668
1669 # This currently only verifies we receive output from
1670 # localhost. Notably, it does not verify we receive output
1671 # via zuul_console streaming.
1672 self.executor_server.keep_jobdir = True
1673 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1674 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1675 self.waitUntilSettled()
1676 self.assertHistory([
1677 dict(name='job-output', result='SUCCESS', changes='1,1'),
1678 ], ordered=False)
1679
1680 token = 'Standard output test %s' % (self.history[0].jobdir.src_root)
1681 j = json.loads(self._get_file(self.history[0],
1682 'work/logs/job-output.json'))
1683 self.assertEqual(token,
1684 j[0]['plays'][0]['tasks'][0]
1685 ['hosts']['localhost']['stdout'])
1686
1687 print(self._get_file(self.history[0],
1688 'work/logs/job-output.txt'))
1689 self.assertIn(token,
1690 self._get_file(self.history[0],
1691 'work/logs/job-output.txt'))