blob: 142a248650ef1a6b16741072c3e4f8f6f83481bf [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)
James E. Blair8b5408c2016-08-08 15:37:46 -070042 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)
James E. Blair8b5408c2016-08-08 15:37:46 -070054 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'
63
64 def test_sql_tables_created(self, metadata_table=None):
Joshua Heskethd78b4482015-09-14 16:56:34 -060065 "Test the tables for storing results are created properly"
66 buildset_table = 'zuul_buildset'
67 build_table = 'zuul_build'
68
69 insp = sa.engine.reflection.Inspector(
James E. Blair82844892017-03-06 10:55:26 -080070 self.connections.connections['resultsdb'].engine)
Joshua Heskethd78b4482015-09-14 16:56:34 -060071
72 self.assertEqual(9, len(insp.get_columns(buildset_table)))
73 self.assertEqual(10, len(insp.get_columns(build_table)))
74
James E. Blair82844892017-03-06 10:55:26 -080075 def test_sql_results(self):
Joshua Heskethd78b4482015-09-14 16:56:34 -060076 "Test results are entered into an sql table"
77 # Grab the sa tables
James E. Blair82844892017-03-06 10:55:26 -080078 tenant = self.sched.abide.tenants.get('tenant-one')
Joshua Heskethd78b4482015-09-14 16:56:34 -060079 reporter = _get_reporter_from_connection_name(
James E. Blair82844892017-03-06 10:55:26 -080080 tenant.layout.pipelines['check'].success_actions,
Joshua Heskethd78b4482015-09-14 16:56:34 -060081 'resultsdb'
82 )
83
84 # Add a success result
James E. Blair82844892017-03-06 10:55:26 -080085 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
86 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
Joshua Heskethd78b4482015-09-14 16:56:34 -060087 self.waitUntilSettled()
88
89 # Add a failed result for a negative score
James E. Blair82844892017-03-06 10:55:26 -080090 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
91
92 self.executor_server.failJob('project-test1', B)
93 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
Joshua Heskethd78b4482015-09-14 16:56:34 -060094 self.waitUntilSettled()
95
James E. Blair82844892017-03-06 10:55:26 -080096 conn = self.connections.connections['resultsdb'].engine.connect()
Joshua Heskethd78b4482015-09-14 16:56:34 -060097 result = conn.execute(
98 sa.sql.select([reporter.connection.zuul_buildset_table]))
99
100 buildsets = result.fetchall()
101 self.assertEqual(2, len(buildsets))
102 buildset0 = buildsets[0]
103 buildset1 = buildsets[1]
104
105 self.assertEqual('check', buildset0['pipeline'])
106 self.assertEqual('org/project', buildset0['project'])
107 self.assertEqual(1, buildset0['change'])
108 self.assertEqual(1, buildset0['patchset'])
109 self.assertEqual(1, buildset0['score'])
110 self.assertEqual('Build succeeded.', buildset0['message'])
111
112 buildset0_builds = conn.execute(
113 sa.sql.select([reporter.connection.zuul_build_table]).
114 where(
115 reporter.connection.zuul_build_table.c.buildset_id ==
116 buildset0['id']
117 )
118 ).fetchall()
119
120 # Check the first result, which should be the project-merge job
121 self.assertEqual('project-merge', buildset0_builds[0]['job_name'])
122 self.assertEqual("SUCCESS", buildset0_builds[0]['result'])
James E. Blair82844892017-03-06 10:55:26 -0800123 self.assertEqual('https://server/job/project-merge/0/',
Joshua Heskethd78b4482015-09-14 16:56:34 -0600124 buildset0_builds[0]['log_url'])
125
126 self.assertEqual('check', buildset1['pipeline'])
127 self.assertEqual('org/project', buildset1['project'])
128 self.assertEqual(2, buildset1['change'])
129 self.assertEqual(1, buildset1['patchset'])
130 self.assertEqual(-1, buildset1['score'])
131 self.assertEqual('Build failed.', buildset1['message'])
132
133 buildset1_builds = conn.execute(
134 sa.sql.select([reporter.connection.zuul_build_table]).
135 where(
136 reporter.connection.zuul_build_table.c.buildset_id ==
137 buildset1['id']
138 )
139 ).fetchall()
140
141 # Check the second last result, which should be the project-test1 job
142 # which failed
143 self.assertEqual('project-test1', buildset1_builds[-2]['job_name'])
144 self.assertEqual("FAILURE", buildset1_builds[-2]['result'])
James E. Blair82844892017-03-06 10:55:26 -0800145 self.assertEqual('https://server/job/project-test1/0/',
Joshua Heskethd78b4482015-09-14 16:56:34 -0600146 buildset1_builds[-2]['log_url'])
147
Joshua Heskethd78b4482015-09-14 16:56:34 -0600148 def test_multiple_sql_connections(self):
149 "Test putting results in different databases"
Joshua Heskethd78b4482015-09-14 16:56:34 -0600150 # Add a successful result
James E. Blair82844892017-03-06 10:55:26 -0800151 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
152 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
Joshua Heskethd78b4482015-09-14 16:56:34 -0600153 self.waitUntilSettled()
154
155 # Add a failed result
James E. Blair82844892017-03-06 10:55:26 -0800156 B = self.fake_gerrit.addFakeChange('org/project', 'master', 'B')
157 self.executor_server.failJob('project-test1', B)
158 self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
Joshua Heskethd78b4482015-09-14 16:56:34 -0600159 self.waitUntilSettled()
160
161 # Grab the sa tables for resultsdb
James E. Blair82844892017-03-06 10:55:26 -0800162 tenant = self.sched.abide.tenants.get('tenant-one')
Joshua Heskethd78b4482015-09-14 16:56:34 -0600163 reporter1 = _get_reporter_from_connection_name(
James E. Blair82844892017-03-06 10:55:26 -0800164 tenant.layout.pipelines['check'].success_actions,
Joshua Heskethd78b4482015-09-14 16:56:34 -0600165 'resultsdb'
166 )
167
James E. Blair82844892017-03-06 10:55:26 -0800168 conn = self.connections.connections['resultsdb'].engine.connect()
Joshua Heskethd78b4482015-09-14 16:56:34 -0600169 buildsets_resultsdb = conn.execute(sa.sql.select(
170 [reporter1.connection.zuul_buildset_table])).fetchall()
171 # Should have been 2 buildset reported to the resultsdb (both success
172 # and failure report)
173 self.assertEqual(2, len(buildsets_resultsdb))
174
175 # The first one should have passed
176 self.assertEqual('check', buildsets_resultsdb[0]['pipeline'])
177 self.assertEqual('org/project', buildsets_resultsdb[0]['project'])
178 self.assertEqual(1, buildsets_resultsdb[0]['change'])
179 self.assertEqual(1, buildsets_resultsdb[0]['patchset'])
180 self.assertEqual(1, buildsets_resultsdb[0]['score'])
181 self.assertEqual('Build succeeded.', buildsets_resultsdb[0]['message'])
182
183 # Grab the sa tables for resultsdb_failures
184 reporter2 = _get_reporter_from_connection_name(
James E. Blair82844892017-03-06 10:55:26 -0800185 tenant.layout.pipelines['check'].failure_actions,
Joshua Heskethd78b4482015-09-14 16:56:34 -0600186 'resultsdb_failures'
187 )
188
James E. Blair82844892017-03-06 10:55:26 -0800189 conn = self.connections.connections['resultsdb_failures'].\
190 engine.connect()
Joshua Heskethd78b4482015-09-14 16:56:34 -0600191 buildsets_resultsdb_failures = conn.execute(sa.sql.select(
192 [reporter2.connection.zuul_buildset_table])).fetchall()
193 # The failure db should only have 1 buildset failed
194 self.assertEqual(1, len(buildsets_resultsdb_failures))
195
196 self.assertEqual('check', buildsets_resultsdb_failures[0]['pipeline'])
197 self.assertEqual(
198 'org/project', buildsets_resultsdb_failures[0]['project'])
199 self.assertEqual(2, buildsets_resultsdb_failures[0]['change'])
200 self.assertEqual(1, buildsets_resultsdb_failures[0]['patchset'])
201 self.assertEqual(-1, buildsets_resultsdb_failures[0]['score'])
202 self.assertEqual(
203 'Build failed.', buildsets_resultsdb_failures[0]['message'])
204
205
206class TestConnectionsBadSQL(ZuulDBTestCase):
James E. Blair82844892017-03-06 10:55:26 -0800207 config_file = 'zuul-sql-driver-bad.conf'
208 tenant_config_file = 'config/sql-driver/main.yaml'
Joshua Heskethd78b4482015-09-14 16:56:34 -0600209
210 def test_unable_to_connect(self):
211 "Test the SQL reporter fails gracefully when unable to connect"
212 self.config.set('zuul', 'layout_config',
213 'tests/fixtures/layout-sql-reporter.yaml')
214 self.sched.reconfigure(self.config)
215
216 # Trigger a reporter. If no errors are raised, the reporter has been
217 # disabled correctly
James E. Blair82844892017-03-06 10:55:26 -0800218 A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
219 self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
Joshua Heskethd78b4482015-09-14 16:56:34 -0600220 self.waitUntilSettled()
221
Joshua Heskethacccffc2015-03-31 23:38:17 +1100222
223class TestMultipleGerrits(ZuulTestCase):
Jamie Lennoxd2e37332016-12-05 15:26:19 +1100224 config_file = 'zuul-connections-multiple-gerrits.conf'
225 tenant_config_file = 'config/zuul-connections-multiple-gerrits/main.yaml'
Joshua Heskethacccffc2015-03-31 23:38:17 +1100226
227 def test_multiple_project_separate_gerrits(self):
Paul Belanger174a8272017-03-14 13:20:10 -0400228 self.executor_server.hold_jobs_in_build = True
Joshua Heskethacccffc2015-03-31 23:38:17 +1100229
230 A = self.fake_another_gerrit.addFakeChange(
Jamie Lennoxd2e37332016-12-05 15:26:19 +1100231 'org/project1', 'master', 'A')
Joshua Heskethacccffc2015-03-31 23:38:17 +1100232 self.fake_another_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
233
234 self.waitUntilSettled()
235
Jamie Lennoxd2e37332016-12-05 15:26:19 +1100236 self.assertBuilds([dict(name='project-test2',
237 changes='1,1',
238 project='org/project1',
239 pipeline='another_check')])
Joshua Heskethacccffc2015-03-31 23:38:17 +1100240
Jamie Lennoxd2e37332016-12-05 15:26:19 +1100241 # NOTE(jamielennox): the tests back the git repo for both connections
242 # onto the same git repo on the file system. If we just create another
243 # fake change the fake_review_gerrit will try to create another 1,1
244 # change and git will fail to create the ref. Arbitrarily set it to get
245 # around the problem.
246 self.fake_review_gerrit.change_number = 50
247
248 B = self.fake_review_gerrit.addFakeChange(
249 'org/project1', 'master', 'B')
250 self.fake_review_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
251
252 self.waitUntilSettled()
253
254 self.assertBuilds([
255 dict(name='project-test2',
256 changes='1,1',
257 project='org/project1',
258 pipeline='another_check'),
259 dict(name='project-test1',
260 changes='51,1',
261 project='org/project1',
262 pipeline='review_check'),
263 ])
264
Paul Belanger174a8272017-03-14 13:20:10 -0400265 self.executor_server.hold_jobs_in_build = False
266 self.executor_server.release()
Joshua Heskethacccffc2015-03-31 23:38:17 +1100267 self.waitUntilSettled()
Tobias Henkel7df274b2017-05-26 17:41:11 +0200268
Jamie Lennoxb09f4212017-05-03 13:51:38 +1000269 def test_multiple_project_separate_gerrits_common_pipeline(self):
270 self.executor_server.hold_jobs_in_build = True
271
272 A = self.fake_another_gerrit.addFakeChange(
273 'org/project2', 'master', 'A')
274 self.fake_another_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
275
276 self.waitUntilSettled()
277
278 self.assertBuilds([dict(name='project-test2',
279 changes='1,1',
280 project='org/project2',
281 pipeline='common_check')])
282
283 # NOTE(jamielennox): the tests back the git repo for both connections
284 # onto the same git repo on the file system. If we just create another
285 # fake change the fake_review_gerrit will try to create another 1,1
286 # change and git will fail to create the ref. Arbitrarily set it to get
287 # around the problem.
288 self.fake_review_gerrit.change_number = 50
289
290 B = self.fake_review_gerrit.addFakeChange(
291 'org/project2', 'master', 'B')
292 self.fake_review_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
293
294 self.waitUntilSettled()
295
296 self.assertBuilds([
297 dict(name='project-test2',
298 changes='1,1',
299 project='org/project2',
300 pipeline='common_check'),
301 dict(name='project-test1',
302 changes='51,1',
303 project='org/project2',
304 pipeline='common_check'),
305 ])
306
307 self.executor_server.hold_jobs_in_build = False
308 self.executor_server.release()
309 self.waitUntilSettled()
310
Tobias Henkel7df274b2017-05-26 17:41:11 +0200311
312class TestConnectionsMerger(ZuulTestCase):
313 config_file = 'zuul-connections-merger.conf'
314 tenant_config_file = 'config/single-tenant/main.yaml'
315
316 def configure_connections(self):
317 super(TestConnectionsMerger, self).configure_connections(True)
318
319 def test_connections_merger(self):
320 "Test merger only configures source connections"
321
322 self.assertIn("gerrit", self.connections.connections)
323 self.assertIn("github", self.connections.connections)
324 self.assertNotIn("smtp", self.connections.connections)
325 self.assertNotIn("sql", self.connections.connections)
326 self.assertNotIn("timer", self.connections.connections)
327 self.assertNotIn("zuul", self.connections.connections)