blob: bacdf8fdb58d63abd0926be64fcedd8a3f3f2346 [file] [log] [blame]
Joshua Hesketh352264b2015-08-11 23:42:08 +10001# Copyright 2014 Rackspace Australia
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
Joshua Heskethd78b4482015-09-14 16:56:34 -060015import sqlalchemy as sa
Joshua Heskethd78b4482015-09-14 16:56:34 -060016
17from tests.base import ZuulTestCase, ZuulDBTestCase
18
19
20def _get_reporter_from_connection_name(reporters, connection_name):
21 # Reporters are placed into lists for each action they may exist in.
22 # Search through the given list for the correct reporter by its conncetion
23 # name
24 for r in reporters:
25 if r.connection.connection_name == connection_name:
26 return r
Joshua Heskethacccffc2015-03-31 23:38:17 +110027
Joshua Hesketh352264b2015-08-11 23:42:08 +100028
Joshua Heskethacccffc2015-03-31 23:38:17 +110029class TestConnections(ZuulTestCase):
Morgan Fainberg4245a422016-08-05 16:20:12 -070030 config_file = 'zuul-connections-same-gerrit.conf'
31 tenant_config_file = 'config/zuul-connections-same-gerrit/main.yaml'
Joshua Heskethacccffc2015-03-31 23:38:17 +110032
Joshua Heskethd78b4482015-09-14 16:56:34 -060033 def test_multiple_gerrit_connections(self):
Joshua Heskethacccffc2015-03-31 23:38:17 +110034 "Test multiple connections to the one gerrit"
35
36 A = self.fake_review_gerrit.addFakeChange('org/project', 'master', 'A')
James E. Blair7fc8daa2016-08-08 15:37:15 -070037 self.addEvent('review_gerrit', A.getPatchsetCreatedEvent(1))
Joshua Heskethacccffc2015-03-31 23:38:17 +110038
39 self.waitUntilSettled()
40
41 self.assertEqual(len(A.patchsets[-1]['approvals']), 1)
Tobias Henkelea98a192017-05-29 21:15:17 +020042 self.assertEqual(A.patchsets[-1]['approvals'][0]['type'], 'Verified')
Joshua Heskethacccffc2015-03-31 23:38:17 +110043 self.assertEqual(A.patchsets[-1]['approvals'][0]['value'], '1')
44 self.assertEqual(A.patchsets[-1]['approvals'][0]['by']['username'],
45 'jenkins')
46
47 B = self.fake_review_gerrit.addFakeChange('org/project', 'master', 'B')
Paul Belanger174a8272017-03-14 13:20:10 -040048 self.executor_server.failJob('project-test2', B)
James E. Blair7fc8daa2016-08-08 15:37:15 -070049 self.addEvent('review_gerrit', B.getPatchsetCreatedEvent(1))
Joshua Heskethacccffc2015-03-31 23:38:17 +110050
51 self.waitUntilSettled()
52
53 self.assertEqual(len(B.patchsets[-1]['approvals']), 1)
Tobias Henkelea98a192017-05-29 21:15:17 +020054 self.assertEqual(B.patchsets[-1]['approvals'][0]['type'], 'Verified')
Joshua Heskethacccffc2015-03-31 23:38:17 +110055 self.assertEqual(B.patchsets[-1]['approvals'][0]['value'], '-1')
56 self.assertEqual(B.patchsets[-1]['approvals'][0]['by']['username'],
57 'civoter')
58
James E. Blair82844892017-03-06 10:55:26 -080059
60class TestSQLConnection(ZuulDBTestCase):
61 config_file = 'zuul-sql-driver.conf'
62 tenant_config_file = 'config/sql-driver/main.yaml'
Tobias Henkel94a1d082017-12-09 12:24:52 +010063 expected_table_prefix = ''
James E. Blair82844892017-03-06 10:55:26 -080064
Tobias Henkel94a1d082017-12-09 12:24:52 +010065 def test_sql_tables_created(self):
Joshua Heskethd78b4482015-09-14 16:56:34 -060066 "Test the tables for storing results are created properly"
Joshua Heskethd78b4482015-09-14 16:56:34 -060067
Tobias Henkel94a1d082017-12-09 12:24:52 +010068 connection = self.connections.connections['resultsdb']
69 insp = sa.engine.reflection.Inspector(connection.engine)
70
71 table_prefix = connection.table_prefix
72 self.assertEqual(self.expected_table_prefix, table_prefix)
73
74 buildset_table = table_prefix + 'zuul_buildset'
75 build_table = table_prefix + 'zuul_build'
Joshua Heskethd78b4482015-09-14 16:56:34 -060076
Tristan Cacqueraycb8f7e22018-02-21 01:54:14 +000077 self.assertEqual(14, len(insp.get_columns(buildset_table)))
Joshua Heskethd78b4482015-09-14 16:56:34 -060078 self.assertEqual(10, len(insp.get_columns(build_table)))
79
James E. Blair82844892017-03-06 10:55:26 -080080 def test_sql_results(self):
Joshua Heskethd78b4482015-09-14 16:56:34 -060081 "Test results are entered into an sql table"
James E. Blair66e04132017-09-28 17:10:25 -070082 self.executor_server.hold_jobs_in_build = True
Joshua Heskethd78b4482015-09-14 16:56:34 -060083 # Grab the sa tables
James E. Blair82844892017-03-06 10:55:26 -080084 tenant = self.sched.abide.tenants.get('tenant-one')
Joshua Heskethd78b4482015-09-14 16:56:34 -060085 reporter = _get_reporter_from_connection_name(
James E. Blair82844892017-03-06 10:55:26 -080086 tenant.layout.pipelines['check'].success_actions,
Joshua Heskethd78b4482015-09-14 16:56:34 -060087 'resultsdb'
88 )
89
90 # Add a success result
James E. Blair82844892017-03-06 10:55:26 -080091 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
92 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
Joshua Heskethd78b4482015-09-14 16:56:34 -060093 self.waitUntilSettled()
James E. Blair66e04132017-09-28 17:10:25 -070094 self.orderedRelease()
95 self.waitUntilSettled()
Joshua Heskethd78b4482015-09-14 16:56:34 -060096
Monty Taylor40f7f4d2017-07-27 17:27:43 -050097 # Add a failed result
James E. Blair82844892017-03-06 10:55:26 -080098 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
99
100 self.executor_server.failJob('project-test1', B)
101 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
Joshua Heskethd78b4482015-09-14 16:56:34 -0600102 self.waitUntilSettled()
James E. Blair66e04132017-09-28 17:10:25 -0700103 self.orderedRelease()
104 self.waitUntilSettled()
Joshua Heskethd78b4482015-09-14 16:56:34 -0600105
James E. Blair82844892017-03-06 10:55:26 -0800106 conn = self.connections.connections['resultsdb'].engine.connect()
Joshua Heskethd78b4482015-09-14 16:56:34 -0600107 result = conn.execute(
108 sa.sql.select([reporter.connection.zuul_buildset_table]))
109
110 buildsets = result.fetchall()
111 self.assertEqual(2, len(buildsets))
112 buildset0 = buildsets[0]
113 buildset1 = buildsets[1]
114
115 self.assertEqual('check', buildset0['pipeline'])
116 self.assertEqual('org/project', buildset0['project'])
117 self.assertEqual(1, buildset0['change'])
Tobias Henkel52af4bb2018-01-10 09:45:40 +0100118 self.assertEqual('1', buildset0['patchset'])
Monty Taylor40f7f4d2017-07-27 17:27:43 -0500119 self.assertEqual('SUCCESS', buildset0['result'])
Joshua Heskethd78b4482015-09-14 16:56:34 -0600120 self.assertEqual('Build succeeded.', buildset0['message'])
Tristan Cacqueray64675202017-07-17 06:14:07 +0000121 self.assertEqual('tenant-one', buildset0['tenant'])
James E. Blair0e4c7912018-01-02 14:20:17 -0800122 self.assertEqual('https://review.example.com/%d' % buildset0['change'],
Tristan Cacqueray305a2152017-09-12 23:09:34 +0000123 buildset0['ref_url'])
Joshua Heskethd78b4482015-09-14 16:56:34 -0600124
125 buildset0_builds = conn.execute(
126 sa.sql.select([reporter.connection.zuul_build_table]).
127 where(
128 reporter.connection.zuul_build_table.c.buildset_id ==
129 buildset0['id']
130 )
131 ).fetchall()
132
133 # Check the first result, which should be the project-merge job
134 self.assertEqual('project-merge', buildset0_builds[0]['job_name'])
135 self.assertEqual("SUCCESS", buildset0_builds[0]['result'])
Monty Taylorde8242c2017-02-23 20:29:53 -0600136 self.assertEqual(
Monty Taylor51139a02016-05-24 11:28:10 -0500137 'finger://{hostname}/{uuid}'.format(
138 hostname=self.executor_server.hostname,
Monty Taylorde8242c2017-02-23 20:29:53 -0600139 uuid=buildset0_builds[0]['uuid']),
140 buildset0_builds[0]['log_url'])
Joshua Heskethd78b4482015-09-14 16:56:34 -0600141 self.assertEqual('check', buildset1['pipeline'])
Tristan Cacqueraycb8f7e22018-02-21 01:54:14 +0000142 self.assertEqual('master', buildset1['branch'])
Joshua Heskethd78b4482015-09-14 16:56:34 -0600143 self.assertEqual('org/project', buildset1['project'])
144 self.assertEqual(2, buildset1['change'])
Tobias Henkel52af4bb2018-01-10 09:45:40 +0100145 self.assertEqual('1', buildset1['patchset'])
Monty Taylor40f7f4d2017-07-27 17:27:43 -0500146 self.assertEqual('FAILURE', buildset1['result'])
Joshua Heskethd78b4482015-09-14 16:56:34 -0600147 self.assertEqual('Build failed.', buildset1['message'])
148
149 buildset1_builds = conn.execute(
150 sa.sql.select([reporter.connection.zuul_build_table]).
151 where(
152 reporter.connection.zuul_build_table.c.buildset_id ==
153 buildset1['id']
154 )
155 ).fetchall()
156
James E. Blair66e04132017-09-28 17:10:25 -0700157 # Check the second result, which should be the project-test1 job
Joshua Heskethd78b4482015-09-14 16:56:34 -0600158 # which failed
James E. Blair66e04132017-09-28 17:10:25 -0700159 self.assertEqual('project-test1', buildset1_builds[1]['job_name'])
160 self.assertEqual("FAILURE", buildset1_builds[1]['result'])
Monty Taylorde8242c2017-02-23 20:29:53 -0600161 self.assertEqual(
Monty Taylor51139a02016-05-24 11:28:10 -0500162 'finger://{hostname}/{uuid}'.format(
163 hostname=self.executor_server.hostname,
James E. Blair66e04132017-09-28 17:10:25 -0700164 uuid=buildset1_builds[1]['uuid']),
165 buildset1_builds[1]['log_url'])
Joshua Heskethd78b4482015-09-14 16:56:34 -0600166
Joshua Heskethd78b4482015-09-14 16:56:34 -0600167 def test_multiple_sql_connections(self):
168 "Test putting results in different databases"
Joshua Heskethd78b4482015-09-14 16:56:34 -0600169 # Add a successful result
James E. Blair82844892017-03-06 10:55:26 -0800170 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
171 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
Joshua Heskethd78b4482015-09-14 16:56:34 -0600172 self.waitUntilSettled()
173
174 # Add a failed result
James E. Blair82844892017-03-06 10:55:26 -0800175 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
176 self.executor_server.failJob('project-test1', B)
177 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
Joshua Heskethd78b4482015-09-14 16:56:34 -0600178 self.waitUntilSettled()
179
180 # Grab the sa tables for resultsdb
James E. Blair82844892017-03-06 10:55:26 -0800181 tenant = self.sched.abide.tenants.get('tenant-one')
Joshua Heskethd78b4482015-09-14 16:56:34 -0600182 reporter1 = _get_reporter_from_connection_name(
James E. Blair82844892017-03-06 10:55:26 -0800183 tenant.layout.pipelines['check'].success_actions,
Joshua Heskethd78b4482015-09-14 16:56:34 -0600184 'resultsdb'
185 )
186
James E. Blair82844892017-03-06 10:55:26 -0800187 conn = self.connections.connections['resultsdb'].engine.connect()
Joshua Heskethd78b4482015-09-14 16:56:34 -0600188 buildsets_resultsdb = conn.execute(sa.sql.select(
189 [reporter1.connection.zuul_buildset_table])).fetchall()
190 # Should have been 2 buildset reported to the resultsdb (both success
191 # and failure report)
192 self.assertEqual(2, len(buildsets_resultsdb))
193
194 # The first one should have passed
195 self.assertEqual('check', buildsets_resultsdb[0]['pipeline'])
196 self.assertEqual('org/project', buildsets_resultsdb[0]['project'])
197 self.assertEqual(1, buildsets_resultsdb[0]['change'])
Tobias Henkel52af4bb2018-01-10 09:45:40 +0100198 self.assertEqual('1', buildsets_resultsdb[0]['patchset'])
Monty Taylor40f7f4d2017-07-27 17:27:43 -0500199 self.assertEqual('SUCCESS', buildsets_resultsdb[0]['result'])
Joshua Heskethd78b4482015-09-14 16:56:34 -0600200 self.assertEqual('Build succeeded.', buildsets_resultsdb[0]['message'])
201
202 # Grab the sa tables for resultsdb_failures
203 reporter2 = _get_reporter_from_connection_name(
James E. Blair82844892017-03-06 10:55:26 -0800204 tenant.layout.pipelines['check'].failure_actions,
Joshua Heskethd78b4482015-09-14 16:56:34 -0600205 'resultsdb_failures'
206 )
207
James E. Blair82844892017-03-06 10:55:26 -0800208 conn = self.connections.connections['resultsdb_failures'].\
209 engine.connect()
Joshua Heskethd78b4482015-09-14 16:56:34 -0600210 buildsets_resultsdb_failures = conn.execute(sa.sql.select(
211 [reporter2.connection.zuul_buildset_table])).fetchall()
212 # The failure db should only have 1 buildset failed
213 self.assertEqual(1, len(buildsets_resultsdb_failures))
214
215 self.assertEqual('check', buildsets_resultsdb_failures[0]['pipeline'])
216 self.assertEqual(
217 'org/project', buildsets_resultsdb_failures[0]['project'])
218 self.assertEqual(2, buildsets_resultsdb_failures[0]['change'])
Tobias Henkel52af4bb2018-01-10 09:45:40 +0100219 self.assertEqual('1', buildsets_resultsdb_failures[0]['patchset'])
Monty Taylor40f7f4d2017-07-27 17:27:43 -0500220 self.assertEqual('FAILURE', buildsets_resultsdb_failures[0]['result'])
Joshua Heskethd78b4482015-09-14 16:56:34 -0600221 self.assertEqual(
222 'Build failed.', buildsets_resultsdb_failures[0]['message'])
223
224
Tobias Henkel94a1d082017-12-09 12:24:52 +0100225class TestSQLConnectionPrefix(TestSQLConnection):
226 config_file = 'zuul-sql-driver-prefix.conf'
227 expected_table_prefix = 'prefix_'
228
229
Joshua Heskethd78b4482015-09-14 16:56:34 -0600230class TestConnectionsBadSQL(ZuulDBTestCase):
James E. Blair82844892017-03-06 10:55:26 -0800231 config_file = 'zuul-sql-driver-bad.conf'
232 tenant_config_file = 'config/sql-driver/main.yaml'
Joshua Heskethd78b4482015-09-14 16:56:34 -0600233
234 def test_unable_to_connect(self):
235 "Test the SQL reporter fails gracefully when unable to connect"
236 self.config.set('zuul', 'layout_config',
237 'tests/fixtures/layout-sql-reporter.yaml')
238 self.sched.reconfigure(self.config)
239
240 # Trigger a reporter. If no errors are raised, the reporter has been
241 # disabled correctly
James E. Blair82844892017-03-06 10:55:26 -0800242 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
243 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
Joshua Heskethd78b4482015-09-14 16:56:34 -0600244 self.waitUntilSettled()
245
Joshua Heskethacccffc2015-03-31 23:38:17 +1100246
247class TestMultipleGerrits(ZuulTestCase):
Jamie Lennoxd2e37332016-12-05 15:26:19 +1100248 config_file = 'zuul-connections-multiple-gerrits.conf'
249 tenant_config_file = 'config/zuul-connections-multiple-gerrits/main.yaml'
Joshua Heskethacccffc2015-03-31 23:38:17 +1100250
251 def test_multiple_project_separate_gerrits(self):
Paul Belanger174a8272017-03-14 13:20:10 -0400252 self.executor_server.hold_jobs_in_build = True
Joshua Heskethacccffc2015-03-31 23:38:17 +1100253
254 A = self.fake_another_gerrit.addFakeChange(
Jamie Lennoxd2e37332016-12-05 15:26:19 +1100255 'org/project1', 'master', 'A')
Joshua Heskethacccffc2015-03-31 23:38:17 +1100256 self.fake_another_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
257
258 self.waitUntilSettled()
259
Jamie Lennoxd2e37332016-12-05 15:26:19 +1100260 self.assertBuilds([dict(name='project-test2',
261 changes='1,1',
262 project='org/project1',
263 pipeline='another_check')])
Joshua Heskethacccffc2015-03-31 23:38:17 +1100264
Jamie Lennoxd2e37332016-12-05 15:26:19 +1100265 # NOTE(jamielennox): the tests back the git repo for both connections
266 # onto the same git repo on the file system. If we just create another
267 # fake change the fake_review_gerrit will try to create another 1,1
268 # change and git will fail to create the ref. Arbitrarily set it to get
269 # around the problem.
270 self.fake_review_gerrit.change_number = 50
271
272 B = self.fake_review_gerrit.addFakeChange(
273 'org/project1', 'master', 'B')
274 self.fake_review_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
275
276 self.waitUntilSettled()
277
278 self.assertBuilds([
279 dict(name='project-test2',
280 changes='1,1',
281 project='org/project1',
282 pipeline='another_check'),
283 dict(name='project-test1',
284 changes='51,1',
285 project='org/project1',
286 pipeline='review_check'),
287 ])
288
Paul Belanger174a8272017-03-14 13:20:10 -0400289 self.executor_server.hold_jobs_in_build = False
290 self.executor_server.release()
Joshua Heskethacccffc2015-03-31 23:38:17 +1100291 self.waitUntilSettled()
Tobias Henkel7df274b2017-05-26 17:41:11 +0200292
Jamie Lennoxb09f4212017-05-03 13:51:38 +1000293 def test_multiple_project_separate_gerrits_common_pipeline(self):
294 self.executor_server.hold_jobs_in_build = True
295
296 A = self.fake_another_gerrit.addFakeChange(
297 'org/project2', 'master', 'A')
298 self.fake_another_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
299
300 self.waitUntilSettled()
301
302 self.assertBuilds([dict(name='project-test2',
303 changes='1,1',
304 project='org/project2',
305 pipeline='common_check')])
306
307 # NOTE(jamielennox): the tests back the git repo for both connections
308 # onto the same git repo on the file system. If we just create another
309 # fake change the fake_review_gerrit will try to create another 1,1
310 # change and git will fail to create the ref. Arbitrarily set it to get
311 # around the problem.
312 self.fake_review_gerrit.change_number = 50
313
314 B = self.fake_review_gerrit.addFakeChange(
315 'org/project2', 'master', 'B')
316 self.fake_review_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
317
318 self.waitUntilSettled()
319
320 self.assertBuilds([
321 dict(name='project-test2',
322 changes='1,1',
323 project='org/project2',
324 pipeline='common_check'),
325 dict(name='project-test1',
326 changes='51,1',
327 project='org/project2',
328 pipeline='common_check'),
329 ])
330
331 self.executor_server.hold_jobs_in_build = False
332 self.executor_server.release()
333 self.waitUntilSettled()
334
Tobias Henkel7df274b2017-05-26 17:41:11 +0200335
336class TestConnectionsMerger(ZuulTestCase):
337 config_file = 'zuul-connections-merger.conf'
338 tenant_config_file = 'config/single-tenant/main.yaml'
339
340 def configure_connections(self):
341 super(TestConnectionsMerger, self).configure_connections(True)
342
343 def test_connections_merger(self):
344 "Test merger only configures source connections"
345
346 self.assertIn("gerrit", self.connections.connections)
347 self.assertIn("github", self.connections.connections)
348 self.assertNotIn("smtp", self.connections.connections)
349 self.assertNotIn("sql", self.connections.connections)
350 self.assertNotIn("timer", self.connections.connections)
351 self.assertNotIn("zuul", self.connections.connections)
Clark Boylana7f724c2017-10-25 11:35:19 -0700352
353
354class TestConnectionsCgit(ZuulTestCase):
355 config_file = 'zuul-connections-cgit.conf'
356 tenant_config_file = 'config/single-tenant/main.yaml'
357
358 def test_cgit_web_url(self):
359 self.assertIn("gerrit", self.connections.connections)
360 conn = self.connections.connections['gerrit']
361 source = conn.source
362 proj = source.getProject('foo/bar')
363 url = conn._getWebUrl(proj, '1')
364 self.assertEqual(url,
365 'https://cgit.example.com/cgit/foo/bar/commit/?id=1')
366
367
368class TestConnectionsGitweb(ZuulTestCase):
369 config_file = 'zuul-connections-gitweb.conf'
370 tenant_config_file = 'config/single-tenant/main.yaml'
371
372 def test_gitweb_url(self):
373 self.assertIn("gerrit", self.connections.connections)
374 conn = self.connections.connections['gerrit']
375 source = conn.source
376 proj = source.getProject('foo/bar')
377 url = conn._getWebUrl(proj, '1')
378 url_should_be = 'https://review.example.com/' \
379 'gitweb?p=foo/bar.git;a=commitdiff;h=1'
380 self.assertEqual(url, url_should_be)