blob: 5c0679de8a654902b908bb513944f7e6afe5978a [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. Blaira92cbc82017-01-23 14:56:49 -080017import os
James E. Blair14abdf42015-12-09 16:11:53 -080018import textwrap
James E. Blair59fdbac2015-12-07 17:08:06 -080019
James E. Blairb9c0d772017-03-03 14:34:49 -080020import testtools
21
22import zuul.configloader
James E. Blairff555742017-02-19 11:34:27 -080023from tests.base import AnsibleZuulTestCase, ZuulTestCase
James E. Blair59fdbac2015-12-07 17:08:06 -080024
James E. Blair59fdbac2015-12-07 17:08:06 -080025
James E. Blair3f876d52016-07-22 13:07:14 -070026class TestMultipleTenants(AnsibleZuulTestCase):
James E. Blair59fdbac2015-12-07 17:08:06 -080027 # A temporary class to hold new tests while others are disabled
28
James E. Blair2a629ec2015-12-22 15:32:02 -080029 tenant_config_file = 'config/multi-tenant/main.yaml'
James E. Blair59fdbac2015-12-07 17:08:06 -080030
James E. Blair83005782015-12-11 14:46:03 -080031 def test_multiple_tenants(self):
James E. Blair96f26942015-12-09 10:15:59 -080032 A = self.fake_gerrit.addFakeChange('org/project1', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -070033 A.addApproval('code-review', 2)
34 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair59fdbac2015-12-07 17:08:06 -080035 self.waitUntilSettled()
James E. Blair96f26942015-12-09 10:15:59 -080036 self.assertEqual(self.getJobFromHistory('project1-test1').result,
James E. Blair59fdbac2015-12-07 17:08:06 -080037 'SUCCESS')
James E. Blair96c6bf82016-01-15 16:20:40 -080038 self.assertEqual(self.getJobFromHistory('python27').result,
39 'SUCCESS')
James E. Blair59fdbac2015-12-07 17:08:06 -080040 self.assertEqual(A.data['status'], 'MERGED')
James E. Blair96f26942015-12-09 10:15:59 -080041 self.assertEqual(A.reported, 2,
42 "A should report start and success")
43 self.assertIn('tenant-one-gate', A.messages[1],
44 "A should transit tenant-one gate")
45 self.assertNotIn('tenant-two-gate', A.messages[1],
46 "A should *not* transit tenant-two gate")
James E. Blair59fdbac2015-12-07 17:08:06 -080047
James E. Blair96f26942015-12-09 10:15:59 -080048 B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B')
James E. Blair8b5408c2016-08-08 15:37:46 -070049 B.addApproval('code-review', 2)
50 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
James E. Blair96f26942015-12-09 10:15:59 -080051 self.waitUntilSettled()
James E. Blair96c6bf82016-01-15 16:20:40 -080052 self.assertEqual(self.getJobFromHistory('python27',
53 'org/project2').result,
54 'SUCCESS')
James E. Blair96f26942015-12-09 10:15:59 -080055 self.assertEqual(self.getJobFromHistory('project2-test1').result,
56 'SUCCESS')
57 self.assertEqual(B.data['status'], 'MERGED')
58 self.assertEqual(B.reported, 2,
59 "B should report start and success")
60 self.assertIn('tenant-two-gate', B.messages[1],
61 "B should transit tenant-two gate")
62 self.assertNotIn('tenant-one-gate', B.messages[1],
63 "B should *not* transit tenant-one gate")
James E. Blair59fdbac2015-12-07 17:08:06 -080064
James E. Blair96f26942015-12-09 10:15:59 -080065 self.assertEqual(A.reported, 2, "Activity in tenant two should"
66 "not affect tenant one")
James E. Blair14abdf42015-12-09 16:11:53 -080067
James E. Blair83005782015-12-11 14:46:03 -080068
James E. Blairff555742017-02-19 11:34:27 -080069class TestInRepoConfig(ZuulTestCase):
James E. Blair83005782015-12-11 14:46:03 -080070 # A temporary class to hold new tests while others are disabled
71
James E. Blair2a629ec2015-12-22 15:32:02 -080072 tenant_config_file = 'config/in-repo/main.yaml'
James E. Blair83005782015-12-11 14:46:03 -080073
James E. Blair83005782015-12-11 14:46:03 -080074 def test_in_repo_config(self):
James E. Blair14abdf42015-12-09 16:11:53 -080075 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair8b5408c2016-08-08 15:37:46 -070076 A.addApproval('code-review', 2)
77 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair14abdf42015-12-09 16:11:53 -080078 self.waitUntilSettled()
79 self.assertEqual(self.getJobFromHistory('project-test1').result,
80 'SUCCESS')
81 self.assertEqual(A.data['status'], 'MERGED')
82 self.assertEqual(A.reported, 2,
83 "A should report start and success")
84 self.assertIn('tenant-one-gate', A.messages[1],
85 "A should transit tenant-one gate")
James E. Blairb97ed802015-12-21 15:55:35 -080086
James E. Blair8b1dc3f2016-07-05 16:49:00 -070087 def test_dynamic_config(self):
88 in_repo_conf = textwrap.dedent(
89 """
90 - job:
91 name: project-test2
92
93 - project:
94 name: org/project
95 tenant-one-gate:
96 jobs:
97 - project-test2
98 """)
99
James E. Blairc73c73a2017-01-20 15:15:15 -0800100 in_repo_playbook = textwrap.dedent(
101 """
102 - hosts: all
103 tasks: []
104 """)
105
106 file_dict = {'.zuul.yaml': in_repo_conf,
107 'playbooks/project-test2.yaml': in_repo_playbook}
James E. Blair8b1dc3f2016-07-05 16:49:00 -0700108 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
James E. Blairc73c73a2017-01-20 15:15:15 -0800109 files=file_dict)
James E. Blair8b5408c2016-08-08 15:37:46 -0700110 A.addApproval('code-review', 2)
111 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
James E. Blair8b1dc3f2016-07-05 16:49:00 -0700112 self.waitUntilSettled()
James E. Blair8b1dc3f2016-07-05 16:49:00 -0700113 self.assertEqual(A.data['status'], 'MERGED')
114 self.assertEqual(A.reported, 2,
115 "A should report start and success")
116 self.assertIn('tenant-one-gate', A.messages[1],
117 "A should transit tenant-one gate")
James E. Blair646322f2017-01-27 15:50:34 -0800118 self.assertHistory([
119 dict(name='project-test2', result='SUCCESS', changes='1,1')])
120
James E. Blairc2a5ed72017-02-20 14:12:01 -0500121 self.fake_gerrit.addEvent(A.getChangeMergedEvent())
James E. Blair7bbd7a32017-03-06 11:36:13 -0800122 self.waitUntilSettled()
James E. Blairc2a5ed72017-02-20 14:12:01 -0500123
James E. Blair646322f2017-01-27 15:50:34 -0800124 # Now that the config change is landed, it should be live for
125 # subsequent changes.
126 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
127 B.addApproval('code-review', 2)
128 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
129 self.waitUntilSettled()
130 self.assertEqual(self.getJobFromHistory('project-test2').result,
131 'SUCCESS')
132 self.assertHistory([
133 dict(name='project-test2', result='SUCCESS', changes='1,1'),
134 dict(name='project-test2', result='SUCCESS', changes='2,1')])
James E. Blairc73c73a2017-01-20 15:15:15 -0800135
James E. Blairff555742017-02-19 11:34:27 -0800136 def test_in_repo_branch(self):
137 in_repo_conf = textwrap.dedent(
138 """
139 - job:
140 name: project-test2
141
142 - project:
143 name: org/project
144 tenant-one-gate:
145 jobs:
146 - project-test2
147 """)
148
149 in_repo_playbook = textwrap.dedent(
150 """
151 - hosts: all
152 tasks: []
153 """)
154
155 file_dict = {'.zuul.yaml': in_repo_conf,
156 'playbooks/project-test2.yaml': in_repo_playbook}
157 self.create_branch('org/project', 'stable')
158 A = self.fake_gerrit.addFakeChange('org/project', 'stable', 'A',
159 files=file_dict)
160 A.addApproval('code-review', 2)
161 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
162 self.waitUntilSettled()
163 self.assertEqual(A.data['status'], 'MERGED')
164 self.assertEqual(A.reported, 2,
165 "A should report start and success")
166 self.assertIn('tenant-one-gate', A.messages[1],
167 "A should transit tenant-one gate")
168 self.assertHistory([
169 dict(name='project-test2', result='SUCCESS', changes='1,1')])
170 self.fake_gerrit.addEvent(A.getChangeMergedEvent())
James E. Blair7bbd7a32017-03-06 11:36:13 -0800171 self.waitUntilSettled()
James E. Blairff555742017-02-19 11:34:27 -0800172
173 # The config change should not affect master.
174 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
175 B.addApproval('code-review', 2)
176 self.fake_gerrit.addEvent(B.addApproval('approved', 1))
177 self.waitUntilSettled()
178 self.assertHistory([
179 dict(name='project-test2', result='SUCCESS', changes='1,1'),
180 dict(name='project-test1', result='SUCCESS', changes='2,1')])
181
182 # The config change should be live for further changes on
183 # stable.
184 C = self.fake_gerrit.addFakeChange('org/project', 'stable', 'C')
185 C.addApproval('code-review', 2)
186 self.fake_gerrit.addEvent(C.addApproval('approved', 1))
187 self.waitUntilSettled()
188 self.assertHistory([
189 dict(name='project-test2', result='SUCCESS', changes='1,1'),
190 dict(name='project-test1', result='SUCCESS', changes='2,1'),
191 dict(name='project-test2', result='SUCCESS', changes='3,1')])
192
James E. Blair149b69c2017-03-02 10:48:16 -0800193 def test_untrusted_syntax_error(self):
James E. Blaire53250c2017-03-01 14:34:36 -0800194 in_repo_conf = textwrap.dedent(
195 """
196 - job:
197 name: project-test2
198 foo: error
199 """)
200
201 file_dict = {'.zuul.yaml': in_repo_conf}
202 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
203 files=file_dict)
204 A.addApproval('code-review', 2)
205 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
206 self.waitUntilSettled()
207
208 self.assertEqual(A.data['status'], 'NEW')
209 self.assertEqual(A.reported, 2,
210 "A should report start and failure")
211 self.assertIn('syntax error', A.messages[1],
212 "A should have a syntax error reported")
213
James E. Blair149b69c2017-03-02 10:48:16 -0800214 def test_trusted_syntax_error(self):
215 in_repo_conf = textwrap.dedent(
216 """
217 - job:
218 name: project-test2
219 foo: error
220 """)
221
222 file_dict = {'zuul.yaml': in_repo_conf}
223 A = self.fake_gerrit.addFakeChange('common-config', 'master', 'A',
224 files=file_dict)
225 A.addApproval('code-review', 2)
226 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
227 self.waitUntilSettled()
228
229 self.assertEqual(A.data['status'], 'NEW')
230 self.assertEqual(A.reported, 2,
231 "A should report start and failure")
232 self.assertIn('syntax error', A.messages[1],
233 "A should have a syntax error reported")
234
James E. Blair6f140c72017-03-03 10:32:07 -0800235 def test_untrusted_yaml_error(self):
236 in_repo_conf = textwrap.dedent(
237 """
238 - job:
239 foo: error
240 """)
241
242 file_dict = {'.zuul.yaml': in_repo_conf}
243 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A',
244 files=file_dict)
245 A.addApproval('code-review', 2)
246 self.fake_gerrit.addEvent(A.addApproval('approved', 1))
247 self.waitUntilSettled()
248
249 self.assertEqual(A.data['status'], 'NEW')
250 self.assertEqual(A.reported, 2,
251 "A should report start and failure")
252 self.assertIn('syntax error', A.messages[1],
253 "A should have a syntax error reported")
254
James E. Blairc73c73a2017-01-20 15:15:15 -0800255
256class TestAnsible(AnsibleZuulTestCase):
257 # A temporary class to hold new tests while others are disabled
258
259 tenant_config_file = 'config/ansible/main.yaml'
260
261 def test_playbook(self):
262 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
263 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
264 self.waitUntilSettled()
Paul Belanger96618ed2017-03-01 09:42:33 -0500265 build = self.getJobFromHistory('timeout')
266 self.assertEqual(build.result, 'ABORTED')
Monty Taylorc231d932017-02-03 09:57:15 -0600267 build = self.getJobFromHistory('faillocal')
268 self.assertEqual(build.result, 'FAILURE')
Paul Belanger30ba93a2017-03-16 16:28:10 -0400269 build = self.getJobFromHistory('nodepool')
270 self.assertEqual(build.result, 'SUCCESS')
James E. Blaira92cbc82017-01-23 14:56:49 -0800271 build = self.getJobFromHistory('python27')
272 self.assertEqual(build.result, 'SUCCESS')
273 flag_path = os.path.join(self.test_root, build.uuid + '.flag')
274 self.assertTrue(os.path.exists(flag_path))
Monty Taylorc231d932017-02-03 09:57:15 -0600275 copied_path = os.path.join(self.test_root, build.uuid +
276 '.copied')
277 self.assertTrue(os.path.exists(copied_path))
278 failed_path = os.path.join(self.test_root, build.uuid +
279 '.failed')
280 self.assertFalse(os.path.exists(failed_path))
James E. Blair66b274e2017-01-31 14:47:52 -0800281 pre_flag_path = os.path.join(self.test_root, build.uuid +
282 '.pre.flag')
283 self.assertTrue(os.path.exists(pre_flag_path))
284 post_flag_path = os.path.join(self.test_root, build.uuid +
285 '.post.flag')
286 self.assertTrue(os.path.exists(post_flag_path))
James E. Blair5ac93842017-01-20 06:47:34 -0800287 bare_role_flag_path = os.path.join(self.test_root,
288 build.uuid + '.bare-role.flag')
289 self.assertTrue(os.path.exists(bare_role_flag_path))
James E. Blairb9c0d772017-03-03 14:34:49 -0800290
291
292class TestBrokenConfig(ZuulTestCase):
293 # Test that we get an appropriate syntax error if we start with a
294 # broken config.
295
296 tenant_config_file = 'config/broken/main.yaml'
297
298 def setUp(self):
299 with testtools.ExpectedException(
300 zuul.configloader.ConfigurationSyntaxError,
301 "\nZuul encountered a syntax error"):
302 super(TestBrokenConfig, self).setUp()
303
304 def test_broken_config_on_startup(self):
305 pass