blob: 68ea74f8107dcbed479da8aa17ec8da87f7ca25d [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. Blair6069f2b2017-09-26 16:34:11 -0700402 self.waitUntilSettled()
James E. Blairff555742017-02-19 11:34:27 -0800403 A = self.fake_gerrit.addFakeChange('org/project', 'stable', 'A',
404 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200405 A.addApproval('Code-Review', 2)
406 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blairff555742017-02-19 11:34:27 -0800407 self.waitUntilSettled()
408 self.assertEqual(A.data['status'], 'MERGED')
409 self.assertEqual(A.reported, 2,
410 "A should report start and success")
411 self.assertIn('tenant-one-gate', A.messages[1],
412 "A should transit tenant-one gate")
413 self.assertHistory([
414 dict(name='project-test2', result='SUCCESS', changes='1,1')])
415 self.fake_gerrit.addEvent(A.getChangeMergedEvent())
James E. Blair7bbd7a32017-03-06 11:36:13 -0800416 self.waitUntilSettled()
James E. Blairff555742017-02-19 11:34:27 -0800417
418 # The config change should not affect master.
419 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200420 B.addApproval('Code-Review', 2)
421 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
James E. Blairff555742017-02-19 11:34:27 -0800422 self.waitUntilSettled()
423 self.assertHistory([
424 dict(name='project-test2', result='SUCCESS', changes='1,1'),
425 dict(name='project-test1', result='SUCCESS', changes='2,1')])
426
427 # The config change should be live for further changes on
428 # stable.
429 C = self.fake_gerrit.addFakeChange('org/project', 'stable', 'C')
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200430 C.addApproval('Code-Review', 2)
431 self.fake_gerrit.addEvent(C.addApproval('Approved', 1))
James E. Blairff555742017-02-19 11:34:27 -0800432 self.waitUntilSettled()
433 self.assertHistory([
434 dict(name='project-test2', result='SUCCESS', changes='1,1'),
435 dict(name='project-test1', result='SUCCESS', changes='2,1'),
436 dict(name='project-test2', result='SUCCESS', changes='3,1')])
437
James E. Blaira5a12492017-05-03 11:40:48 -0700438 def test_crd_dynamic_config_branch(self):
439 # Test that we can create a job in one repo and be able to use
440 # it from a different branch on a different repo.
441
442 self.create_branch('org/project1', 'stable')
James E. Blair72facdc2017-08-17 10:29:12 -0700443 self.fake_gerrit.addEvent(
444 self.fake_gerrit.getFakeBranchCreatedEvent(
445 'org/project1', 'stable'))
James E. Blaira5a12492017-05-03 11:40:48 -0700446
447 in_repo_conf = textwrap.dedent(
448 """
449 - job:
Tobias Henkelf02cf512017-07-21 22:55:34 +0200450 name: project-test1
451
452 - job:
James E. Blaira5a12492017-05-03 11:40:48 -0700453 name: project-test2
454
455 - project:
456 name: org/project
457 check:
458 jobs:
459 - project-test2
460 """)
461
462 in_repo_playbook = textwrap.dedent(
463 """
464 - hosts: all
465 tasks: []
466 """)
467
468 file_dict = {'.zuul.yaml': in_repo_conf,
469 'playbooks/project-test2.yaml': in_repo_playbook}
470 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
471 files=file_dict)
472
473 second_repo_conf = textwrap.dedent(
474 """
475 - project:
476 name: org/project1
477 check:
478 jobs:
479 - project-test2
480 """)
481
482 second_file_dict = {'.zuul.yaml': second_repo_conf}
483 B = self.fake_gerrit.addFakeChange('org/project1', 'stable', 'B',
484 files=second_file_dict)
485 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
486 B.subject, A.data['id'])
487
488 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
489 self.waitUntilSettled()
490 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
491 self.waitUntilSettled()
492
493 self.assertEqual(A.reported, 1, "A should report")
494 self.assertHistory([
495 dict(name='project-test2', result='SUCCESS', changes='1,1'),
496 dict(name='project-test2', result='SUCCESS', changes='1,1 2,1'),
497 ])
498
James E. Blair97043882017-09-06 15:51:17 -0700499 def test_yaml_list_error(self):
500 in_repo_conf = textwrap.dedent(
501 """
502 job: foo
503 """)
504
505 file_dict = {'.zuul.yaml': in_repo_conf}
506 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
507 files=file_dict)
508 A.addApproval('Code-Review', 2)
509 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
510 self.waitUntilSettled()
511
512 self.assertEqual(A.data['status'], 'NEW')
513 self.assertEqual(A.reported, 1,
514 "A should report failure")
515 self.assertIn('not a list', A.messages[0],
516 "A should have a syntax error reported")
517
518 def test_yaml_dict_error(self):
519 in_repo_conf = textwrap.dedent(
520 """
521 - job
522 """)
523
524 file_dict = {'.zuul.yaml': in_repo_conf}
525 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
526 files=file_dict)
527 A.addApproval('Code-Review', 2)
528 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
529 self.waitUntilSettled()
530
531 self.assertEqual(A.data['status'], 'NEW')
532 self.assertEqual(A.reported, 1,
533 "A should report failure")
534 self.assertIn('not a dictionary', A.messages[0],
535 "A should have a syntax error reported")
536
537 def test_yaml_key_error(self):
538 in_repo_conf = textwrap.dedent(
539 """
540 - job:
541 name: project-test2
542 """)
543
544 file_dict = {'.zuul.yaml': in_repo_conf}
545 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
546 files=file_dict)
547 A.addApproval('Code-Review', 2)
548 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
549 self.waitUntilSettled()
550
551 self.assertEqual(A.data['status'], 'NEW')
552 self.assertEqual(A.reported, 1,
553 "A should report failure")
554 self.assertIn('has more than one key', A.messages[0],
555 "A should have a syntax error reported")
556
557 def test_yaml_unknown_error(self):
558 in_repo_conf = textwrap.dedent(
559 """
560 - foobar:
561 foo: bar
562 """)
563
564 file_dict = {'.zuul.yaml': in_repo_conf}
565 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
566 files=file_dict)
567 A.addApproval('Code-Review', 2)
568 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
569 self.waitUntilSettled()
570
571 self.assertEqual(A.data['status'], 'NEW')
572 self.assertEqual(A.reported, 1,
573 "A should report failure")
574 self.assertIn('not recognized', A.messages[0],
575 "A should have a syntax error reported")
576
James E. Blair149b69c2017-03-02 10:48:16 -0800577 def test_untrusted_syntax_error(self):
James E. Blaire53250c2017-03-01 14:34:36 -0800578 in_repo_conf = textwrap.dedent(
579 """
580 - job:
581 name: project-test2
582 foo: error
583 """)
584
585 file_dict = {'.zuul.yaml': in_repo_conf}
586 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
587 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200588 A.addApproval('Code-Review', 2)
589 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blaire53250c2017-03-01 14:34:36 -0800590 self.waitUntilSettled()
591
592 self.assertEqual(A.data['status'], 'NEW')
Tobias Henkel9842bd72017-05-16 13:40:03 +0200593 self.assertEqual(A.reported, 1,
594 "A should report failure")
595 self.assertIn('syntax error', A.messages[0],
James E. Blaire53250c2017-03-01 14:34:36 -0800596 "A should have a syntax error reported")
597
James E. Blair149b69c2017-03-02 10:48:16 -0800598 def test_trusted_syntax_error(self):
599 in_repo_conf = textwrap.dedent(
600 """
601 - job:
602 name: project-test2
603 foo: error
604 """)
605
606 file_dict = {'zuul.yaml': in_repo_conf}
607 A = self.fake_gerrit.addFakeChange('common-config', 'master', 'A',
608 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200609 A.addApproval('Code-Review', 2)
610 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blair149b69c2017-03-02 10:48:16 -0800611 self.waitUntilSettled()
612
613 self.assertEqual(A.data['status'], 'NEW')
Tobias Henkel9842bd72017-05-16 13:40:03 +0200614 self.assertEqual(A.reported, 1,
615 "A should report failure")
616 self.assertIn('syntax error', A.messages[0],
James E. Blair149b69c2017-03-02 10:48:16 -0800617 "A should have a syntax error reported")
618
James E. Blair6f140c72017-03-03 10:32:07 -0800619 def test_untrusted_yaml_error(self):
620 in_repo_conf = textwrap.dedent(
621 """
622 - job:
623 foo: error
624 """)
625
626 file_dict = {'.zuul.yaml': in_repo_conf}
627 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
628 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200629 A.addApproval('Code-Review', 2)
630 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blair6f140c72017-03-03 10:32:07 -0800631 self.waitUntilSettled()
632
633 self.assertEqual(A.data['status'], 'NEW')
Tobias Henkel9842bd72017-05-16 13:40:03 +0200634 self.assertEqual(A.reported, 1,
635 "A should report failure")
636 self.assertIn('syntax error', A.messages[0],
James E. Blair6f140c72017-03-03 10:32:07 -0800637 "A should have a syntax error reported")
638
James E. Blairdb04e6a2017-05-03 14:49:36 -0700639 def test_untrusted_shadow_error(self):
640 in_repo_conf = textwrap.dedent(
641 """
642 - job:
643 name: common-config-test
644 """)
645
646 file_dict = {'.zuul.yaml': in_repo_conf}
647 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
648 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200649 A.addApproval('Code-Review', 2)
650 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blairdb04e6a2017-05-03 14:49:36 -0700651 self.waitUntilSettled()
652
653 self.assertEqual(A.data['status'], 'NEW')
Tobias Henkel9842bd72017-05-16 13:40:03 +0200654 self.assertEqual(A.reported, 1,
655 "A should report failure")
656 self.assertIn('not permitted to shadow', A.messages[0],
James E. Blairdb04e6a2017-05-03 14:49:36 -0700657 "A should have a syntax error reported")
658
James E. Blaird5656ad2017-06-02 14:29:41 -0700659 def test_untrusted_pipeline_error(self):
660 in_repo_conf = textwrap.dedent(
661 """
662 - pipeline:
663 name: test
664 """)
665
666 file_dict = {'.zuul.yaml': in_repo_conf}
667 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
668 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200669 A.addApproval('Code-Review', 2)
670 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blaird5656ad2017-06-02 14:29:41 -0700671 self.waitUntilSettled()
672
673 self.assertEqual(A.data['status'], 'NEW')
674 self.assertEqual(A.reported, 1,
675 "A should report failure")
676 self.assertIn('Pipelines may not be defined', A.messages[0],
677 "A should have a syntax error reported")
678
679 def test_untrusted_project_error(self):
680 in_repo_conf = textwrap.dedent(
681 """
682 - project:
683 name: org/project1
684 """)
685
686 file_dict = {'.zuul.yaml': in_repo_conf}
687 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
688 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200689 A.addApproval('Code-Review', 2)
690 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blaird5656ad2017-06-02 14:29:41 -0700691 self.waitUntilSettled()
692
693 self.assertEqual(A.data['status'], 'NEW')
694 self.assertEqual(A.reported, 1,
695 "A should report failure")
696 self.assertIn('the only project definition permitted', A.messages[0],
697 "A should have a syntax error reported")
698
James E. Blaire64b0e42017-06-08 11:23:34 -0700699 def test_duplicate_node_error(self):
700 in_repo_conf = textwrap.dedent(
701 """
702 - nodeset:
703 name: duplicate
704 nodes:
705 - name: compute
James E. Blair16d96a02017-06-08 11:32:56 -0700706 label: foo
James E. Blaire64b0e42017-06-08 11:23:34 -0700707 - name: compute
James E. Blair16d96a02017-06-08 11:32:56 -0700708 label: foo
James E. Blaire64b0e42017-06-08 11:23:34 -0700709 """)
710
711 file_dict = {'.zuul.yaml': in_repo_conf}
712 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
713 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200714 A.addApproval('Code-Review', 2)
715 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blaire64b0e42017-06-08 11:23:34 -0700716 self.waitUntilSettled()
717
718 self.assertEqual(A.data['status'], 'NEW')
719 self.assertEqual(A.reported, 1,
720 "A should report failure")
721 self.assertIn('appears multiple times', A.messages[0],
722 "A should have a syntax error reported")
723
724 def test_duplicate_group_error(self):
725 in_repo_conf = textwrap.dedent(
726 """
727 - nodeset:
728 name: duplicate
729 nodes:
730 - name: compute
James E. Blair16d96a02017-06-08 11:32:56 -0700731 label: foo
James E. Blaire64b0e42017-06-08 11:23:34 -0700732 groups:
733 - name: group
734 nodes: compute
735 - name: group
736 nodes: compute
737 """)
738
739 file_dict = {'.zuul.yaml': in_repo_conf}
740 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
741 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200742 A.addApproval('Code-Review', 2)
743 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blaire64b0e42017-06-08 11:23:34 -0700744 self.waitUntilSettled()
745
746 self.assertEqual(A.data['status'], 'NEW')
747 self.assertEqual(A.reported, 1,
748 "A should report failure")
749 self.assertIn('appears multiple times', A.messages[0],
750 "A should have a syntax error reported")
751
James E. Blair4ae399f2017-09-20 17:15:09 -0700752 def test_secret_not_found_error(self):
753 in_repo_conf = textwrap.dedent(
754 """
755 - job:
756 name: test
757 secrets: does-not-exist
758 """)
759
760 file_dict = {'.zuul.yaml': in_repo_conf}
761 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
762 files=file_dict)
763 A.addApproval('Code-Review', 2)
764 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
765 self.waitUntilSettled()
766
767 self.assertEqual(A.data['status'], 'NEW')
768 self.assertEqual(A.reported, 1,
769 "A should report failure")
770 self.assertIn('secret "does-not-exist" was not found', A.messages[0],
771 "A should have a syntax error reported")
772
773 def test_nodeset_not_found_error(self):
774 in_repo_conf = textwrap.dedent(
775 """
776 - job:
777 name: test
778 nodeset: does-not-exist
779 """)
780
781 file_dict = {'.zuul.yaml': in_repo_conf}
782 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
783 files=file_dict)
784 A.addApproval('Code-Review', 2)
785 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
786 self.waitUntilSettled()
787
788 self.assertEqual(A.data['status'], 'NEW')
789 self.assertEqual(A.reported, 1,
790 "A should report failure")
791 self.assertIn('nodeset "does-not-exist" was not found', A.messages[0],
792 "A should have a syntax error reported")
793
James E. Blair89e25eb2017-09-26 09:11:31 -0700794 def test_template_not_found_error(self):
795 in_repo_conf = textwrap.dedent(
796 """
797 - job:
798 name: project-test1
799 - project:
800 name: org/project
801 templates:
802 - does-not-exist
803 """)
804
805 file_dict = {'.zuul.yaml': in_repo_conf}
806 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
807 files=file_dict)
808 A.addApproval('Code-Review', 2)
809 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
810 self.waitUntilSettled()
811
812 self.assertEqual(A.data['status'], 'NEW')
813 self.assertEqual(A.reported, 1,
814 "A should report failure")
815 self.assertIn('project template "does-not-exist" was not found',
816 A.messages[0],
817 "A should have a syntax error reported")
818
Monty Taylor8be3c0c2017-10-06 10:37:37 -0500819 def test_job_list_in_project_template_not_dict_error(self):
820 in_repo_conf = textwrap.dedent(
821 """
822 - job:
823 name: project-test1
824 - project-template:
825 name: some-jobs
826 check:
827 jobs:
828 - project-test1:
829 - required-projects:
830 org/project2
831 """)
832
833 file_dict = {'.zuul.yaml': in_repo_conf}
834 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
835 files=file_dict)
836 A.addApproval('Code-Review', 2)
837 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
838 self.waitUntilSettled()
839
840 self.assertEqual(A.data['status'], 'NEW')
841 self.assertEqual(A.reported, 1,
842 "A should report failure")
843 self.assertIn('expected str for dictionary value',
844 A.messages[0], "A should have a syntax error reported")
845
846 def test_job_list_in_project_not_dict_error(self):
847 in_repo_conf = textwrap.dedent(
848 """
849 - job:
850 name: project-test1
851 - project:
852 name: org/project1
853 check:
854 jobs:
855 - project-test1:
856 - required-projects:
857 org/project2
858 """)
859
860 file_dict = {'.zuul.yaml': in_repo_conf}
861 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
862 files=file_dict)
863 A.addApproval('Code-Review', 2)
864 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
865 self.waitUntilSettled()
866
867 self.assertEqual(A.data['status'], 'NEW')
868 self.assertEqual(A.reported, 1,
869 "A should report failure")
870 self.assertIn('expected str for dictionary value',
871 A.messages[0], "A should have a syntax error reported")
872
James E. Blair09f9ffe2017-07-11 15:30:25 -0700873 def test_multi_repo(self):
874 downstream_repo_conf = textwrap.dedent(
875 """
876 - project:
877 name: org/project1
878 tenant-one-gate:
879 jobs:
880 - project-test1
881
882 - job:
883 name: project1-test1
884 parent: project-test1
885 """)
886
887 file_dict = {'.zuul.yaml': downstream_repo_conf}
888 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A',
889 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200890 A.addApproval('Code-Review', 2)
891 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
James E. Blair09f9ffe2017-07-11 15:30:25 -0700892 self.waitUntilSettled()
893
894 self.assertEqual(A.data['status'], 'MERGED')
895 self.fake_gerrit.addEvent(A.getChangeMergedEvent())
896 self.waitUntilSettled()
897
898 upstream_repo_conf = textwrap.dedent(
899 """
900 - job:
901 name: project-test1
902
903 - job:
904 name: project-test2
905
906 - project:
907 name: org/project
908 tenant-one-gate:
909 jobs:
910 - project-test1
911 """)
912
913 file_dict = {'.zuul.yaml': upstream_repo_conf}
914 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B',
915 files=file_dict)
Tobias Henkelbf24fd12017-07-27 06:13:07 +0200916 B.addApproval('Code-Review', 2)
917 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
James E. Blair09f9ffe2017-07-11 15:30:25 -0700918 self.waitUntilSettled()
919
920 self.assertEqual(B.data['status'], 'MERGED')
921 self.fake_gerrit.addEvent(B.getChangeMergedEvent())
922 self.waitUntilSettled()
923
924 tenant = self.sched.abide.tenants.get('tenant-one')
925 # Ensure the latest change is reflected in the config; if it
926 # isn't this will raise an exception.
927 tenant.layout.getJob('project-test2')
928
James E. Blair332636e2017-09-05 10:14:35 -0700929 def test_pipeline_error(self):
930 with open(os.path.join(FIXTURE_DIR,
931 'config/in-repo/git/',
932 'common-config/zuul.yaml')) as f:
933 base_common_config = f.read()
934
935 in_repo_conf_A = textwrap.dedent(
936 """
937 - pipeline:
938 name: periodic
939 foo: error
940 """)
941
942 file_dict = {'zuul.yaml': None,
943 'zuul.d/main.yaml': base_common_config,
944 'zuul.d/test1.yaml': in_repo_conf_A}
945 A = self.fake_gerrit.addFakeChange('common-config', 'master', 'A',
946 files=file_dict)
947 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
948 self.waitUntilSettled()
949 self.assertEqual(A.reported, 1,
950 "A should report failure")
951 self.assertIn('syntax error',
952 A.messages[0],
953 "A should have an error reported")
954
955 def test_change_series_error(self):
956 with open(os.path.join(FIXTURE_DIR,
957 'config/in-repo/git/',
958 'common-config/zuul.yaml')) as f:
959 base_common_config = f.read()
960
961 in_repo_conf_A = textwrap.dedent(
962 """
963 - pipeline:
964 name: periodic
965 foo: error
966 """)
967
968 file_dict = {'zuul.yaml': None,
969 'zuul.d/main.yaml': base_common_config,
970 'zuul.d/test1.yaml': in_repo_conf_A}
971 A = self.fake_gerrit.addFakeChange('common-config', 'master', 'A',
972 files=file_dict)
973
974 in_repo_conf_B = textwrap.dedent(
975 """
976 - job:
977 name: project-test2
978 foo: error
979 """)
980
981 file_dict = {'zuul.yaml': None,
982 'zuul.d/main.yaml': base_common_config,
983 'zuul.d/test1.yaml': in_repo_conf_A,
984 'zuul.d/test2.yaml': in_repo_conf_B}
985 B = self.fake_gerrit.addFakeChange('common-config', 'master', 'B',
986 files=file_dict)
987 B.setDependsOn(A, 1)
988 C = self.fake_gerrit.addFakeChange('common-config', 'master', 'C')
989 C.setDependsOn(B, 1)
990 self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
991 self.waitUntilSettled()
992
993 self.assertEqual(C.reported, 1,
994 "C should report failure")
995 self.assertIn('depends on a change that failed to merge',
996 C.messages[0],
997 "C should have an error reported")
998
James E. Blairc73c73a2017-01-20 15:15:15 -0800999
James E. Blairc9455002017-09-06 09:22:19 -07001000class TestInRepoJoin(ZuulTestCase):
1001 # In this config, org/project is not a member of any pipelines, so
1002 # that we may test the changes that cause it to join them.
1003
1004 tenant_config_file = 'config/in-repo-join/main.yaml'
1005
1006 def test_dynamic_dependent_pipeline(self):
1007 # Test dynamically adding a project to a
1008 # dependent pipeline for the first time
1009 self.executor_server.hold_jobs_in_build = True
1010
1011 tenant = self.sched.abide.tenants.get('tenant-one')
1012 gate_pipeline = tenant.layout.pipelines['gate']
1013
1014 in_repo_conf = textwrap.dedent(
1015 """
1016 - job:
1017 name: project-test1
1018
1019 - job:
1020 name: project-test2
1021
1022 - project:
1023 name: org/project
1024 gate:
1025 jobs:
1026 - project-test2
1027 """)
1028
1029 in_repo_playbook = textwrap.dedent(
1030 """
1031 - hosts: all
1032 tasks: []
1033 """)
1034
1035 file_dict = {'.zuul.yaml': in_repo_conf,
1036 'playbooks/project-test2.yaml': in_repo_playbook}
1037 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1038 files=file_dict)
1039 A.addApproval('Code-Review', 2)
1040 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
1041 self.waitUntilSettled()
1042
1043 items = gate_pipeline.getAllItems()
1044 self.assertEqual(items[0].change.number, '1')
1045 self.assertEqual(items[0].change.patchset, '1')
1046 self.assertTrue(items[0].live)
1047
1048 self.executor_server.hold_jobs_in_build = False
1049 self.executor_server.release()
1050 self.waitUntilSettled()
1051
1052 # Make sure the dynamic queue got cleaned up
1053 self.assertEqual(gate_pipeline.queues, [])
1054
1055 def test_dynamic_dependent_pipeline_failure(self):
1056 # Test that a change behind a failing change adding a project
1057 # to a dependent pipeline is dequeued.
1058 self.executor_server.hold_jobs_in_build = True
1059
1060 in_repo_conf = textwrap.dedent(
1061 """
1062 - job:
1063 name: project-test1
1064
1065 - project:
1066 name: org/project
1067 gate:
1068 jobs:
1069 - project-test1
1070 """)
1071
1072 file_dict = {'.zuul.yaml': in_repo_conf}
1073 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1074 files=file_dict)
1075 self.executor_server.failJob('project-test1', A)
1076 A.addApproval('Code-Review', 2)
1077 self.fake_gerrit.addEvent(A.addApproval('Approved', 1))
1078 self.waitUntilSettled()
1079
1080 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1081 B.addApproval('Code-Review', 2)
1082 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
1083 self.waitUntilSettled()
1084
James E. Blair3490c5d2017-09-07 08:33:23 -07001085 self.orderedRelease()
James E. Blairc9455002017-09-06 09:22:19 -07001086 self.waitUntilSettled()
1087 self.assertEqual(A.reported, 2,
1088 "A should report start and failure")
1089 self.assertEqual(A.data['status'], 'NEW')
1090 self.assertEqual(B.reported, 1,
1091 "B should report start")
1092 self.assertHistory([
1093 dict(name='project-test1', result='FAILURE', changes='1,1'),
James E. Blair3490c5d2017-09-07 08:33:23 -07001094 dict(name='project-test1', result='ABORTED', changes='1,1 2,1'),
James E. Blairc9455002017-09-06 09:22:19 -07001095 ], ordered=False)
1096
James E. Blair0af198f2017-09-06 09:52:35 -07001097 def test_dynamic_dependent_pipeline_absent(self):
1098 # Test that a series of dependent changes don't report merge
1099 # failures to a pipeline they aren't in.
1100 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1101 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
1102 B.setDependsOn(A, 1)
1103
1104 A.addApproval('Code-Review', 2)
1105 A.addApproval('Approved', 1)
1106 B.addApproval('Code-Review', 2)
1107 self.fake_gerrit.addEvent(B.addApproval('Approved', 1))
1108 self.waitUntilSettled()
1109 self.assertEqual(A.reported, 0,
1110 "A should not report")
1111 self.assertEqual(A.data['status'], 'NEW')
1112 self.assertEqual(B.reported, 0,
1113 "B should not report")
1114 self.assertEqual(B.data['status'], 'NEW')
1115 self.assertHistory([])
1116
James E. Blairc9455002017-09-06 09:22:19 -07001117
James E. Blairc73c73a2017-01-20 15:15:15 -08001118class TestAnsible(AnsibleZuulTestCase):
1119 # A temporary class to hold new tests while others are disabled
1120
1121 tenant_config_file = 'config/ansible/main.yaml'
1122
1123 def test_playbook(self):
Jamie Lennox7655b552017-03-17 12:33:38 +11001124 # Keep the jobdir around so we can inspect contents if an
1125 # assert fails.
1126 self.executor_server.keep_jobdir = True
1127 # Output extra ansible info so we might see errors.
1128 self.executor_server.verbose = True
1129 # Add a site variables file, used by check-vars
1130 path = os.path.join(FIXTURE_DIR, 'config', 'ansible',
1131 'variables.yaml')
1132 self.config.set('executor', 'variables', path)
James E. Blairc73c73a2017-01-20 15:15:15 -08001133 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1134 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1135 self.waitUntilSettled()
Tobias Henkel077f2f32017-05-30 20:16:46 +02001136 build_timeout = self.getJobFromHistory('timeout')
Jamie Lennox7655b552017-03-17 12:33:38 +11001137 with self.jobLog(build_timeout):
1138 self.assertEqual(build_timeout.result, 'TIMED_OUT')
Tobias Henkel077f2f32017-05-30 20:16:46 +02001139 build_faillocal = self.getJobFromHistory('faillocal')
Jamie Lennox7655b552017-03-17 12:33:38 +11001140 with self.jobLog(build_faillocal):
1141 self.assertEqual(build_faillocal.result, 'FAILURE')
Tobias Henkel077f2f32017-05-30 20:16:46 +02001142 build_failpost = self.getJobFromHistory('failpost')
Jamie Lennox7655b552017-03-17 12:33:38 +11001143 with self.jobLog(build_failpost):
1144 self.assertEqual(build_failpost.result, 'POST_FAILURE')
Tobias Henkel077f2f32017-05-30 20:16:46 +02001145 build_check_vars = self.getJobFromHistory('check-vars')
Jamie Lennox7655b552017-03-17 12:33:38 +11001146 with self.jobLog(build_check_vars):
1147 self.assertEqual(build_check_vars.result, 'SUCCESS')
Monty Tayloraff8b402017-08-16 18:40:41 -05001148 build_check_secret_names = self.getJobFromHistory('check-secret-names')
1149 with self.jobLog(build_check_secret_names):
1150 self.assertEqual(build_check_secret_names.result, 'SUCCESS')
Tobias Henkel077f2f32017-05-30 20:16:46 +02001151 build_hello = self.getJobFromHistory('hello-world')
Jamie Lennox7655b552017-03-17 12:33:38 +11001152 with self.jobLog(build_hello):
1153 self.assertEqual(build_hello.result, 'SUCCESS')
Tobias Henkel077f2f32017-05-30 20:16:46 +02001154 build_python27 = self.getJobFromHistory('python27')
Jamie Lennox7655b552017-03-17 12:33:38 +11001155 with self.jobLog(build_python27):
1156 self.assertEqual(build_python27.result, 'SUCCESS')
1157 flag_path = os.path.join(self.test_root,
1158 build_python27.uuid + '.flag')
1159 self.assertTrue(os.path.exists(flag_path))
1160 copied_path = os.path.join(self.test_root, build_python27.uuid +
1161 '.copied')
1162 self.assertTrue(os.path.exists(copied_path))
1163 failed_path = os.path.join(self.test_root, build_python27.uuid +
1164 '.failed')
1165 self.assertFalse(os.path.exists(failed_path))
1166 pre_flag_path = os.path.join(self.test_root, build_python27.uuid +
1167 '.pre.flag')
1168 self.assertTrue(os.path.exists(pre_flag_path))
1169 post_flag_path = os.path.join(self.test_root, build_python27.uuid +
1170 '.post.flag')
1171 self.assertTrue(os.path.exists(post_flag_path))
1172 bare_role_flag_path = os.path.join(self.test_root,
1173 build_python27.uuid +
1174 '.bare-role.flag')
1175 self.assertTrue(os.path.exists(bare_role_flag_path))
1176 secrets_path = os.path.join(self.test_root,
1177 build_python27.uuid + '.secrets')
1178 with open(secrets_path) as f:
1179 self.assertEqual(f.read(), "test-username test-password")
James E. Blairb9c0d772017-03-03 14:34:49 -08001180
Jamie Lennox7655b552017-03-17 12:33:38 +11001181 msg = A.messages[0]
1182 success = "{} https://success.example.com/zuul-logs/{}"
1183 fail = "{} https://failure.example.com/zuul-logs/{}"
1184 self.assertIn(success.format("python27", build_python27.uuid), msg)
1185 self.assertIn(fail.format("faillocal", build_faillocal.uuid), msg)
1186 self.assertIn(success.format("check-vars",
1187 build_check_vars.uuid), msg)
1188 self.assertIn(success.format("hello-world", build_hello.uuid), msg)
1189 self.assertIn(fail.format("timeout", build_timeout.uuid), msg)
1190 self.assertIn(fail.format("failpost", build_failpost.uuid), msg)
Tobias Henkel077f2f32017-05-30 20:16:46 +02001191
James E. Blairabbaa6f2017-04-06 16:11:44 -07001192 def _add_job(self, job_name):
1193 conf = textwrap.dedent(
1194 """
1195 - job:
1196 name: %s
1197
1198 - project:
1199 name: org/plugin-project
1200 check:
1201 jobs:
1202 - %s
1203 """ % (job_name, job_name))
1204
1205 file_dict = {'.zuul.yaml': conf}
1206 A = self.fake_gerrit.addFakeChange('org/plugin-project', 'master', 'A',
1207 files=file_dict)
1208 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1209 self.waitUntilSettled()
1210
1211 def test_plugins(self):
1212 # Keep the jobdir around so we can inspect contents if an
1213 # assert fails.
1214 self.executor_server.keep_jobdir = True
1215 # Output extra ansible info so we might see errors.
1216 self.executor_server.verbose = True
1217
1218 count = 0
1219 plugin_tests = [
1220 ('passwd', 'FAILURE'),
1221 ('cartesian', 'SUCCESS'),
1222 ('consul_kv', 'FAILURE'),
1223 ('credstash', 'FAILURE'),
1224 ('csvfile_good', 'SUCCESS'),
1225 ('csvfile_bad', 'FAILURE'),
Monty Taylor93ad2212017-08-02 14:59:50 -05001226 ('uri_bad_path', 'FAILURE'),
1227 ('uri_bad_scheme', 'FAILURE'),
Monty Taylor788a40e2017-08-02 16:14:05 -05001228 ('block_local_override', 'FAILURE'),
Monty Taylor8da768f2017-08-31 14:15:35 -05001229 ('file_local_good', 'SUCCESS'),
1230 ('file_local_bad', 'FAILURE'),
James E. Blairabbaa6f2017-04-06 16:11:44 -07001231 ]
1232 for job_name, result in plugin_tests:
1233 count += 1
1234 self._add_job(job_name)
1235
1236 job = self.getJobFromHistory(job_name)
1237 with self.jobLog(job):
1238 self.assertEqual(count, len(self.history))
1239 build = self.history[-1]
1240 self.assertEqual(build.result, result)
1241
1242 # TODOv3(jeblair): parse the ansible output and verify we're
1243 # getting the exception we expect.
1244
James E. Blairb9c0d772017-03-03 14:34:49 -08001245
James E. Blaira4d4eef2017-06-30 14:49:17 -07001246class TestPrePlaybooks(AnsibleZuulTestCase):
1247 # A temporary class to hold new tests while others are disabled
1248
1249 tenant_config_file = 'config/pre-playbook/main.yaml'
1250
1251 def test_pre_playbook_fail(self):
1252 # Test that we run the post playbooks (but not the actual
1253 # playbook) when a pre-playbook fails.
1254 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1255 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1256 self.waitUntilSettled()
1257 build = self.getJobFromHistory('python27')
1258 self.assertIsNone(build.result)
1259 self.assertIn('RETRY_LIMIT', A.messages[0])
1260 flag_path = os.path.join(self.test_root, build.uuid +
1261 '.main.flag')
1262 self.assertFalse(os.path.exists(flag_path))
1263 pre_flag_path = os.path.join(self.test_root, build.uuid +
1264 '.pre.flag')
1265 self.assertFalse(os.path.exists(pre_flag_path))
1266 post_flag_path = os.path.join(self.test_root, build.uuid +
1267 '.post.flag')
James E. Blair21037782017-07-19 11:56:55 -07001268 self.assertTrue(os.path.exists(post_flag_path),
1269 "The file %s should exist" % post_flag_path)
James E. Blaira4d4eef2017-06-30 14:49:17 -07001270
1271
James E. Blairb9c0d772017-03-03 14:34:49 -08001272class TestBrokenConfig(ZuulTestCase):
1273 # Test that we get an appropriate syntax error if we start with a
1274 # broken config.
1275
1276 tenant_config_file = 'config/broken/main.yaml'
1277
1278 def setUp(self):
1279 with testtools.ExpectedException(
1280 zuul.configloader.ConfigurationSyntaxError,
1281 "\nZuul encountered a syntax error"):
1282 super(TestBrokenConfig, self).setUp()
1283
1284 def test_broken_config_on_startup(self):
1285 pass
Ricardo Carrillo Cruz22994f92016-12-02 11:41:58 +00001286
1287
1288class TestProjectKeys(ZuulTestCase):
1289 # Test that we can generate project keys
1290
1291 # Normally the test infrastructure copies a static key in place
1292 # for each project before starting tests. This saves time because
1293 # Zuul's automatic key-generation on startup can be slow. To make
1294 # sure we exercise that code, in this test we allow Zuul to create
1295 # keys for the project on startup.
1296 create_project_keys = True
Tobias Henkelabf973e2017-07-28 10:07:34 +02001297 config_file = 'zuul-connections-gerrit-and-github.conf'
Ricardo Carrillo Cruz22994f92016-12-02 11:41:58 +00001298 tenant_config_file = 'config/in-repo/main.yaml'
1299
1300 def test_key_generation(self):
1301 key_root = os.path.join(self.state_root, 'keys')
1302 private_key_file = os.path.join(key_root, 'gerrit/org/project.pem')
1303 # Make sure that a proper key was created on startup
1304 with open(private_key_file, "rb") as f:
James E. Blairbf1a4f22017-03-17 10:59:37 -07001305 private_key, public_key = \
1306 encryption.deserialize_rsa_keypair(f.read())
Ricardo Carrillo Cruz22994f92016-12-02 11:41:58 +00001307
1308 with open(os.path.join(FIXTURE_DIR, 'private.pem')) as i:
1309 fixture_private_key = i.read()
1310
1311 # Make sure that we didn't just end up with the static fixture
1312 # key
1313 self.assertNotEqual(fixture_private_key, private_key)
1314
1315 # Make sure it's the right length
1316 self.assertEqual(4096, private_key.key_size)
James E. Blairbce76932017-05-04 10:03:15 -07001317
1318
James E. Blairbb94dfa2017-07-11 07:45:19 -07001319class RoleTestCase(ZuulTestCase):
James E. Blair1b27f6a2017-07-14 14:09:07 -07001320 def _assertRolePath(self, build, playbook, content):
1321 path = os.path.join(self.test_root, build.uuid,
1322 'ansible', playbook, 'ansible.cfg')
1323 roles_paths = []
1324 with open(path) as f:
1325 for line in f:
1326 if line.startswith('roles_path'):
1327 roles_paths.append(line)
1328 print(roles_paths)
1329 if content:
1330 self.assertEqual(len(roles_paths), 1,
1331 "Should have one roles_path line in %s" %
1332 (playbook,))
1333 self.assertIn(content, roles_paths[0])
1334 else:
1335 self.assertEqual(len(roles_paths), 0,
1336 "Should have no roles_path line in %s" %
1337 (playbook,))
1338
James E. Blairbb94dfa2017-07-11 07:45:19 -07001339
1340class TestRoles(RoleTestCase):
1341 tenant_config_file = 'config/roles/main.yaml'
1342
James E. Blairbce76932017-05-04 10:03:15 -07001343 def test_role(self):
1344 # This exercises a proposed change to a role being checked out
1345 # and used.
1346 A = self.fake_gerrit.addFakeChange('bare-role', 'master', 'A')
1347 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1348 B.data['commitMessage'] = '%s\n\nDepends-On: %s\n' % (
1349 B.subject, A.data['id'])
1350 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1351 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1352 self.waitUntilSettled()
1353 self.assertHistory([
1354 dict(name='project-test', result='SUCCESS', changes='1,1 2,1'),
1355 ])
James E. Blair6459db12017-06-29 14:57:20 -07001356
James E. Blair1b27f6a2017-07-14 14:09:07 -07001357 def test_role_inheritance(self):
1358 self.executor_server.hold_jobs_in_build = True
1359 conf = textwrap.dedent(
1360 """
1361 - job:
1362 name: parent
1363 roles:
1364 - zuul: bare-role
1365 pre-run: playbooks/parent-pre
1366 post-run: playbooks/parent-post
1367
1368 - job:
1369 name: project-test
1370 parent: parent
1371 roles:
1372 - zuul: org/project
1373
1374 - project:
1375 name: org/project
1376 check:
1377 jobs:
1378 - project-test
1379 """)
1380
1381 file_dict = {'.zuul.yaml': conf}
1382 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1383 files=file_dict)
1384 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1385 self.waitUntilSettled()
1386
1387 self.assertEqual(len(self.builds), 1)
1388 build = self.getBuildByName('project-test')
1389 self._assertRolePath(build, 'pre_playbook_0', 'role_0')
1390 self._assertRolePath(build, 'playbook_0', 'role_0')
1391 self._assertRolePath(build, 'playbook_0', 'role_1')
1392 self._assertRolePath(build, 'post_playbook_0', 'role_0')
1393
1394 self.executor_server.hold_jobs_in_build = False
1395 self.executor_server.release()
1396 self.waitUntilSettled()
1397
1398 self.assertHistory([
1399 dict(name='project-test', result='SUCCESS', changes='1,1'),
1400 ])
1401
James E. Blair6f699732017-07-18 14:19:11 -07001402 def test_role_error(self):
1403 conf = textwrap.dedent(
1404 """
1405 - job:
1406 name: project-test
1407 roles:
1408 - zuul: common-config
1409
1410 - project:
1411 name: org/project
1412 check:
1413 jobs:
1414 - project-test
1415 """)
1416
1417 file_dict = {'.zuul.yaml': conf}
1418 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1419 files=file_dict)
1420 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1421 self.waitUntilSettled()
1422 self.assertIn(
1423 '- project-test project-test : ERROR Unable to find role',
1424 A.messages[-1])
1425
James E. Blair6459db12017-06-29 14:57:20 -07001426
James E. Blairbb94dfa2017-07-11 07:45:19 -07001427class TestImplicitRoles(RoleTestCase):
1428 tenant_config_file = 'config/implicit-roles/main.yaml'
1429
1430 def test_missing_roles(self):
1431 # Test implicit and explicit roles for a project which does
1432 # not have roles. The implicit role should be silently
1433 # ignored since the project doesn't supply roles, but if a
1434 # user declares an explicit role, it should error.
1435 self.executor_server.hold_jobs_in_build = True
1436 A = self.fake_gerrit.addFakeChange('org/norole-project', 'master', 'A')
1437 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1438 self.waitUntilSettled()
1439
1440 self.assertEqual(len(self.builds), 2)
1441 build = self.getBuildByName('implicit-role-fail')
1442 self._assertRolePath(build, 'playbook_0', None)
1443
1444 self.executor_server.hold_jobs_in_build = False
1445 self.executor_server.release()
1446 self.waitUntilSettled()
1447 # The retry_limit doesn't get recorded
1448 self.assertHistory([
1449 dict(name='implicit-role-fail', result='SUCCESS', changes='1,1'),
1450 ])
1451
1452 def test_roles(self):
1453 # Test implicit and explicit roles for a project which does
1454 # have roles. In both cases, we should end up with the role
1455 # in the path. In the explicit case, ensure we end up with
1456 # the name we specified.
1457 self.executor_server.hold_jobs_in_build = True
1458 A = self.fake_gerrit.addFakeChange('org/role-project', 'master', 'A')
1459 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1460 self.waitUntilSettled()
1461
1462 self.assertEqual(len(self.builds), 2)
1463 build = self.getBuildByName('implicit-role-ok')
1464 self._assertRolePath(build, 'playbook_0', 'role_0')
1465
1466 build = self.getBuildByName('explicit-role-ok')
1467 self._assertRolePath(build, 'playbook_0', 'role_0')
1468
1469 self.executor_server.hold_jobs_in_build = False
1470 self.executor_server.release()
1471 self.waitUntilSettled()
1472 self.assertHistory([
1473 dict(name='implicit-role-ok', result='SUCCESS', changes='1,1'),
1474 dict(name='explicit-role-ok', result='SUCCESS', changes='1,1'),
1475 ], ordered=False)
1476
1477
James E. Blair6459db12017-06-29 14:57:20 -07001478class TestShadow(ZuulTestCase):
1479 tenant_config_file = 'config/shadow/main.yaml'
1480
1481 def test_shadow(self):
1482 # Test that a repo is allowed to shadow another's job definitions.
1483 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1484 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1485 self.waitUntilSettled()
1486 self.assertHistory([
1487 dict(name='test1', result='SUCCESS', changes='1,1'),
1488 dict(name='test2', result='SUCCESS', changes='1,1'),
James E. Blairadafa6c2017-07-12 08:50:56 -07001489 ], ordered=False)
James E. Blair196f61a2017-06-30 15:42:29 -07001490
1491
1492class TestDataReturn(AnsibleZuulTestCase):
1493 tenant_config_file = 'config/data-return/main.yaml'
1494
1495 def test_data_return(self):
1496 # This exercises a proposed change to a role being checked out
1497 # and used.
1498 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1499 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1500 self.waitUntilSettled()
1501 self.assertHistory([
1502 dict(name='data-return', result='SUCCESS', changes='1,1'),
James E. Blair88e79c02017-07-07 13:36:54 -07001503 dict(name='data-return-relative', result='SUCCESS', changes='1,1'),
1504 ], ordered=False)
1505 self.assertIn('- data-return http://example.com/test/log/url/',
1506 A.messages[-1])
1507 self.assertIn('- data-return-relative '
1508 'http://example.com/test/log/url/docs/index.html',
James E. Blair196f61a2017-06-30 15:42:29 -07001509 A.messages[-1])
Clint Byrumdc8a0902017-07-20 16:36:27 -07001510
1511
1512class TestDiskAccounting(AnsibleZuulTestCase):
1513 config_file = 'zuul-disk-accounting.conf'
1514 tenant_config_file = 'config/disk-accountant/main.yaml'
1515
1516 def test_disk_accountant_kills_job(self):
1517 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1518 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1519 self.waitUntilSettled()
1520 self.assertHistory([
1521 dict(name='dd-big-empty-file', result='ABORTED', changes='1,1')])
Tristan Cacqueray82f864b2017-08-01 05:54:42 +00001522
1523
1524class TestMaxNodesPerJob(AnsibleZuulTestCase):
1525 tenant_config_file = 'config/multi-tenant/main.yaml'
1526
Tristan Cacquerayc98bff72017-09-10 15:25:26 +00001527 def test_max_timeout_exceeded(self):
Tristan Cacqueray82f864b2017-08-01 05:54:42 +00001528 in_repo_conf = textwrap.dedent(
1529 """
1530 - job:
1531 name: test-job
James E. Blair7e3e6882017-09-20 15:47:13 -07001532 nodeset:
1533 nodes:
1534 - name: node01
1535 label: fake
1536 - name: node02
1537 label: fake
1538 - name: node03
1539 label: fake
1540 - name: node04
1541 label: fake
1542 - name: node05
1543 label: fake
1544 - name: node06
1545 label: fake
Tristan Cacqueray82f864b2017-08-01 05:54:42 +00001546 """)
1547 file_dict = {'.zuul.yaml': in_repo_conf}
1548 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A',
1549 files=file_dict)
1550 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1551 self.waitUntilSettled()
1552 self.assertIn('The job "test-job" exceeds tenant max-nodes-per-job 5.',
1553 A.messages[0], "A should fail because of nodes limit")
1554
1555 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A',
1556 files=file_dict)
1557 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1558 self.waitUntilSettled()
1559 self.assertNotIn("exceeds tenant max-nodes", B.messages[0],
1560 "B should not fail because of nodes limit")
James E. Blair2bab6e72017-08-07 09:52:45 -07001561
1562
Tristan Cacquerayc98bff72017-09-10 15:25:26 +00001563class TestMaxTimeout(AnsibleZuulTestCase):
1564 tenant_config_file = 'config/multi-tenant/main.yaml'
1565
1566 def test_max_nodes_reached(self):
1567 in_repo_conf = textwrap.dedent(
1568 """
1569 - job:
1570 name: test-job
1571 timeout: 3600
1572 """)
1573 file_dict = {'.zuul.yaml': in_repo_conf}
1574 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A',
1575 files=file_dict)
1576 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1577 self.waitUntilSettled()
1578 self.assertIn('The job "test-job" exceeds tenant max-job-timeout',
1579 A.messages[0], "A should fail because of timeout limit")
1580
1581 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A',
1582 files=file_dict)
1583 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
1584 self.waitUntilSettled()
1585 self.assertNotIn("exceeds tenant max-job-timeout", B.messages[0],
1586 "B should not fail because of timeout limit")
1587
1588
James E. Blair2bab6e72017-08-07 09:52:45 -07001589class TestBaseJobs(ZuulTestCase):
1590 tenant_config_file = 'config/base-jobs/main.yaml'
1591
1592 def test_multiple_base_jobs(self):
1593 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1594 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1595 self.waitUntilSettled()
1596 self.assertHistory([
1597 dict(name='my-job', result='SUCCESS', changes='1,1'),
1598 dict(name='other-job', result='SUCCESS', changes='1,1'),
1599 ], ordered=False)
1600 self.assertEqual(self.getJobFromHistory('my-job').
1601 parameters['zuul']['jobtags'],
1602 ['mybase'])
1603 self.assertEqual(self.getJobFromHistory('other-job').
1604 parameters['zuul']['jobtags'],
1605 ['otherbase'])
1606
1607 def test_untrusted_base_job(self):
1608 """Test that a base job may not be defined in an untrusted repo"""
1609 in_repo_conf = textwrap.dedent(
1610 """
1611 - job:
1612 name: fail-base
1613 parent: null
1614 """)
1615
1616 file_dict = {'.zuul.yaml': in_repo_conf}
1617 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1618 files=file_dict)
1619 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1620 self.waitUntilSettled()
1621 self.assertEqual(A.reported, 1,
1622 "A should report failure")
1623 self.assertEqual(A.patchsets[0]['approvals'][0]['value'], "-1")
1624 self.assertIn('Base jobs must be defined in config projects',
1625 A.messages[0])
1626 self.assertHistory([])
James E. Blairdb089032017-08-15 13:42:12 -07001627
1628
1629class TestSecretLeaks(AnsibleZuulTestCase):
1630 tenant_config_file = 'config/secret-leaks/main.yaml'
1631
1632 def searchForContent(self, path, content):
1633 matches = []
1634 for (dirpath, dirnames, filenames) in os.walk(path):
1635 for filename in filenames:
1636 filepath = os.path.join(dirpath, filename)
1637 with open(filepath, 'rb') as f:
1638 if content in f.read():
1639 matches.append(filepath[len(path):])
1640 return matches
1641
1642 def _test_secret_file(self):
1643 # Or rather -- test that they *don't* leak.
1644 # Keep the jobdir around so we can inspect contents.
1645 self.executor_server.keep_jobdir = True
1646 conf = textwrap.dedent(
1647 """
1648 - project:
1649 name: org/project
1650 check:
1651 jobs:
1652 - secret-file
1653 """)
1654
1655 file_dict = {'.zuul.yaml': conf}
1656 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1657 files=file_dict)
1658 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1659 self.waitUntilSettled()
1660 self.assertHistory([
1661 dict(name='secret-file', result='SUCCESS', changes='1,1'),
1662 ], ordered=False)
1663 matches = self.searchForContent(self.history[0].jobdir.root,
1664 b'test-password')
James E. Blaird6a71ca2017-08-18 14:15:05 -07001665 self.assertEqual(set(['/work/secret-file.txt']),
James E. Blairdb089032017-08-15 13:42:12 -07001666 set(matches))
1667
1668 def test_secret_file(self):
1669 self._test_secret_file()
1670
1671 def test_secret_file_verbose(self):
1672 # Output extra ansible info to exercise alternate logging code
1673 # paths.
1674 self.executor_server.verbose = True
1675 self._test_secret_file()
1676
1677 def _test_secret_file_fail(self):
1678 # Or rather -- test that they *don't* leak.
1679 # Keep the jobdir around so we can inspect contents.
1680 self.executor_server.keep_jobdir = True
1681 conf = textwrap.dedent(
1682 """
1683 - project:
1684 name: org/project
1685 check:
1686 jobs:
1687 - secret-file-fail
1688 """)
1689
1690 file_dict = {'.zuul.yaml': conf}
1691 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
1692 files=file_dict)
1693 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1694 self.waitUntilSettled()
1695 self.assertHistory([
1696 dict(name='secret-file-fail', result='FAILURE', changes='1,1'),
1697 ], ordered=False)
1698 matches = self.searchForContent(self.history[0].jobdir.root,
1699 b'test-password')
James E. Blaird6a71ca2017-08-18 14:15:05 -07001700 self.assertEqual(set(['/work/failure-file.txt']),
James E. Blairdb089032017-08-15 13:42:12 -07001701 set(matches))
1702
1703 def test_secret_file_fail(self):
1704 self._test_secret_file_fail()
1705
1706 def test_secret_file_fail_verbose(self):
1707 # Output extra ansible info to exercise alternate logging code
1708 # paths.
1709 self.executor_server.verbose = True
1710 self._test_secret_file_fail()
James E. Blaira00910c2017-08-23 09:15:04 -07001711
1712
1713class TestJobOutput(AnsibleZuulTestCase):
1714 tenant_config_file = 'config/job-output/main.yaml'
1715
1716 def _get_file(self, build, path):
1717 p = os.path.join(build.jobdir.root, path)
1718 with open(p) as f:
1719 return f.read()
1720
1721 def test_job_output(self):
1722 # Verify that command standard output appears in the job output
1723
1724 # This currently only verifies we receive output from
1725 # localhost. Notably, it does not verify we receive output
1726 # via zuul_console streaming.
1727 self.executor_server.keep_jobdir = True
1728 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
1729 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
1730 self.waitUntilSettled()
1731 self.assertHistory([
1732 dict(name='job-output', result='SUCCESS', changes='1,1'),
1733 ], ordered=False)
1734
1735 token = 'Standard output test %s' % (self.history[0].jobdir.src_root)
1736 j = json.loads(self._get_file(self.history[0],
1737 'work/logs/job-output.json'))
1738 self.assertEqual(token,
1739 j[0]['plays'][0]['tasks'][0]
1740 ['hosts']['localhost']['stdout'])
1741
1742 print(self._get_file(self.history[0],
1743 'work/logs/job-output.txt'))
1744 self.assertIn(token,
1745 self._get_file(self.history[0],
1746 'work/logs/job-output.txt'))