blob: e7879f99f7aef4fb2f3143e3fe8e337e40f4439f [file] [log] [blame]
Henrik Kjellandera18a3bf2017-09-15 11:19:10 +02001#!/usr/bin/env python
2
3# Copyright 2017 The WebRTC project authors. All Rights Reserved.
4#
5# Use of this source code is governed by a BSD-style license
6# that can be found in the LICENSE file in the root of the source
7# tree. An additional intellectual property rights grant can be found
8# in the file PATENTS. All contributing project authors may
9# be found in the AUTHORS file in the root of the source tree.
10
Mirko Bonadeia730c1c2017-09-18 11:33:13 +020011import os
12import shutil
13import tempfile
14import textwrap
charujain9893e252017-09-14 13:33:22 +020015import unittest
16
17import PRESUBMIT
Mirko Bonadei61880182017-10-12 15:12:35 +020018# pylint: disable=line-too-long
19from presubmit_test_mocks import MockInputApi, MockOutputApi, MockFile, MockChange
charujain9893e252017-09-14 13:33:22 +020020
21
Mirko Bonadei7de1eb72017-09-19 10:16:10 +020022class CheckBugEntryFieldTest(unittest.TestCase):
Mirko Bonadei8cc66952020-10-30 10:13:45 +010023 def testCommitMessageBugEntryWithNoError(self):
24 mock_input_api = MockInputApi()
25 mock_output_api = MockOutputApi()
26 mock_input_api.change = MockChange([], ['webrtc:1234'])
27 errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
28 mock_output_api)
29 self.assertEqual(0, len(errors))
charujain9893e252017-09-14 13:33:22 +020030
Mirko Bonadei8cc66952020-10-30 10:13:45 +010031 def testCommitMessageBugEntryReturnError(self):
32 mock_input_api = MockInputApi()
33 mock_output_api = MockOutputApi()
34 mock_input_api.change = MockChange([], ['webrtc:1234', 'webrtc=4321'])
35 errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
36 mock_output_api)
37 self.assertEqual(1, len(errors))
38 self.assertEqual(('Bogus Bug entry: webrtc=4321. Please specify'
39 ' the issue tracker prefix and the issue number,'
40 ' separated by a colon, e.g. webrtc:123 or'
41 ' chromium:12345.'), str(errors[0]))
charujain9893e252017-09-14 13:33:22 +020042
Mirko Bonadei8cc66952020-10-30 10:13:45 +010043 def testCommitMessageBugEntryWithoutPrefix(self):
44 mock_input_api = MockInputApi()
45 mock_output_api = MockOutputApi()
46 mock_input_api.change = MockChange([], ['1234'])
47 errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
48 mock_output_api)
49 self.assertEqual(1, len(errors))
50 self.assertEqual(('Bug entry requires issue tracker prefix, '
51 'e.g. webrtc:1234'), str(errors[0]))
Mirko Bonadei61880182017-10-12 15:12:35 +020052
Mirko Bonadei8cc66952020-10-30 10:13:45 +010053 def testCommitMessageBugEntryIsNone(self):
54 mock_input_api = MockInputApi()
55 mock_output_api = MockOutputApi()
56 mock_input_api.change = MockChange([], ['None'])
57 errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
58 mock_output_api)
59 self.assertEqual(0, len(errors))
charujain9893e252017-09-14 13:33:22 +020060
Mirko Bonadei8cc66952020-10-30 10:13:45 +010061 def testCommitMessageBugEntrySupportInternalBugReference(self):
62 mock_input_api = MockInputApi()
63 mock_output_api = MockOutputApi()
64 mock_input_api.change.BUG = 'b/12345'
65 errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
66 mock_output_api)
67 self.assertEqual(0, len(errors))
68 mock_input_api.change.BUG = 'b/12345, webrtc:1234'
69 errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
70 mock_output_api)
71 self.assertEqual(0, len(errors))
charujain81a58c72017-09-25 13:25:45 +020072
charujain9893e252017-09-14 13:33:22 +020073
Mirko Bonadei7de1eb72017-09-19 10:16:10 +020074class CheckNewlineAtTheEndOfProtoFilesTest(unittest.TestCase):
Mirko Bonadei8cc66952020-10-30 10:13:45 +010075 def setUp(self):
76 self.tmp_dir = tempfile.mkdtemp()
77 self.proto_file_path = os.path.join(self.tmp_dir, 'foo.proto')
78 self.input_api = MockInputApi()
79 self.output_api = MockOutputApi()
Mirko Bonadeia730c1c2017-09-18 11:33:13 +020080
Mirko Bonadei8cc66952020-10-30 10:13:45 +010081 def tearDown(self):
82 shutil.rmtree(self.tmp_dir, ignore_errors=True)
Mirko Bonadeia730c1c2017-09-18 11:33:13 +020083
Mirko Bonadei8cc66952020-10-30 10:13:45 +010084 def testErrorIfProtoFileDoesNotEndWithNewline(self):
85 self._GenerateProtoWithoutNewlineAtTheEnd()
86 self.input_api.files = [MockFile(self.proto_file_path)]
87 errors = PRESUBMIT.CheckNewlineAtTheEndOfProtoFiles(
88 self.input_api, self.output_api, lambda x: True)
89 self.assertEqual(1, len(errors))
90 self.assertEqual(
91 'File %s must end with exactly one newline.' %
92 self.proto_file_path, str(errors[0]))
Mirko Bonadeia730c1c2017-09-18 11:33:13 +020093
Mirko Bonadei8cc66952020-10-30 10:13:45 +010094 def testNoErrorIfProtoFileEndsWithNewline(self):
95 self._GenerateProtoWithNewlineAtTheEnd()
96 self.input_api.files = [MockFile(self.proto_file_path)]
97 errors = PRESUBMIT.CheckNewlineAtTheEndOfProtoFiles(
98 self.input_api, self.output_api, lambda x: True)
99 self.assertEqual(0, len(errors))
Mirko Bonadeia730c1c2017-09-18 11:33:13 +0200100
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100101 def _GenerateProtoWithNewlineAtTheEnd(self):
102 with open(self.proto_file_path, 'w') as f:
103 f.write(
104 textwrap.dedent("""
Mirko Bonadeia730c1c2017-09-18 11:33:13 +0200105 syntax = "proto2";
106 option optimize_for = LITE_RUNTIME;
107 package webrtc.audioproc;
108 """))
109
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100110 def _GenerateProtoWithoutNewlineAtTheEnd(self):
111 with open(self.proto_file_path, 'w') as f:
112 f.write(
113 textwrap.dedent("""
Mirko Bonadeia730c1c2017-09-18 11:33:13 +0200114 syntax = "proto2";
115 option optimize_for = LITE_RUNTIME;
116 package webrtc.audioproc;"""))
117
118
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200119class CheckNoMixingSourcesTest(unittest.TestCase):
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100120 def setUp(self):
121 self.tmp_dir = tempfile.mkdtemp()
122 self.file_path = os.path.join(self.tmp_dir, 'BUILD.gn')
123 self.input_api = MockInputApi()
124 self.output_api = MockOutputApi()
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200125
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100126 def tearDown(self):
127 shutil.rmtree(self.tmp_dir, ignore_errors=True)
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200128
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100129 def testErrorIfCAndCppAreMixed(self):
130 self._AssertNumberOfErrorsWithSources(1, ['foo.c', 'bar.cc', 'bar.h'])
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200131
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100132 def testErrorIfCAndObjCAreMixed(self):
133 self._AssertNumberOfErrorsWithSources(1, ['foo.c', 'bar.m', 'bar.h'])
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200134
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100135 def testErrorIfCAndObjCppAreMixed(self):
136 self._AssertNumberOfErrorsWithSources(1, ['foo.c', 'bar.mm', 'bar.h'])
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200137
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100138 def testErrorIfCppAndObjCAreMixed(self):
139 self._AssertNumberOfErrorsWithSources(1, ['foo.cc', 'bar.m', 'bar.h'])
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200140
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100141 def testErrorIfCppAndObjCppAreMixed(self):
142 self._AssertNumberOfErrorsWithSources(1, ['foo.cc', 'bar.mm', 'bar.h'])
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200143
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100144 def testNoErrorIfOnlyC(self):
145 self._AssertNumberOfErrorsWithSources(0, ['foo.c', 'bar.c', 'bar.h'])
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200146
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100147 def testNoErrorIfOnlyCpp(self):
148 self._AssertNumberOfErrorsWithSources(0, ['foo.cc', 'bar.cc', 'bar.h'])
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200149
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100150 def testNoErrorIfOnlyObjC(self):
151 self._AssertNumberOfErrorsWithSources(0, ['foo.m', 'bar.m', 'bar.h'])
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200152
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100153 def testNoErrorIfOnlyObjCpp(self):
154 self._AssertNumberOfErrorsWithSources(0, ['foo.mm', 'bar.mm', 'bar.h'])
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200155
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100156 def testNoErrorIfObjCAndObjCppAreMixed(self):
157 self._AssertNumberOfErrorsWithSources(0, ['foo.m', 'bar.mm', 'bar.h'])
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200158
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100159 def testNoErrorIfSourcesAreInExclusiveIfBranches(self):
160 self._GenerateBuildFile(
161 textwrap.dedent("""
Mirko Bonadei86d053c2019-10-17 21:32:04 +0200162 rtc_library("bar_foo") {
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200163 if (is_win) {
164 sources = [
165 "bar.cc",
166 ],
167 }
168 if (is_ios) {
169 sources = [
170 "bar.mm",
171 ],
172 }
173 }
Mirko Bonadei86d053c2019-10-17 21:32:04 +0200174 rtc_library("foo_bar") {
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200175 if (is_win) {
176 sources = [
177 "foo.cc",
178 ],
179 }
180 if (is_ios) {
181 sources = [
182 "foo.mm",
183 ],
184 }
185 }
186 """))
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100187 self.input_api.files = [MockFile(self.file_path)]
188 errors = PRESUBMIT.CheckNoMixingSources(self.input_api,
189 [MockFile(self.file_path)],
190 self.output_api)
191 self.assertEqual(0, len(errors))
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200192
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100193 def testErrorIfSourcesAreNotInExclusiveIfBranches(self):
194 self._GenerateBuildFile(
195 textwrap.dedent("""
Mirko Bonadei86d053c2019-10-17 21:32:04 +0200196 rtc_library("bar_foo") {
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200197 if (is_win) {
198 sources = [
199 "bar.cc",
200 ],
201 }
202 if (foo_bar) {
203 sources += [
204 "bar.mm",
205 ],
206 }
207 }
Mirko Bonadei86d053c2019-10-17 21:32:04 +0200208 rtc_library("foo_bar") {
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200209 if (is_win) {
210 sources = [
211 "foo.cc",
212 ],
213 }
214 if (foo_bar) {
215 sources += [
216 "foo.mm",
217 ],
218 }
219 if (is_ios) {
220 sources = [
221 "bar.m",
222 "bar.c",
223 ],
224 }
225 }
226 """))
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100227 self.input_api.files = [MockFile(self.file_path)]
228 errors = PRESUBMIT.CheckNoMixingSources(self.input_api,
229 [MockFile(self.file_path)],
230 self.output_api)
231 self.assertEqual(1, len(errors))
232 self.assertTrue('bar.cc' in str(errors[0]))
233 self.assertTrue('bar.mm' in str(errors[0]))
234 self.assertTrue('foo.cc' in str(errors[0]))
235 self.assertTrue('foo.mm' in str(errors[0]))
236 self.assertTrue('bar.m' in str(errors[0]))
237 self.assertTrue('bar.c' in str(errors[0]))
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200238
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100239 def _AssertNumberOfErrorsWithSources(self, number_of_errors, sources):
240 assert len(
241 sources) == 3, 'This function accepts a list of 3 source files'
242 self._GenerateBuildFile(
243 textwrap.dedent("""
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200244 rtc_static_library("bar_foo") {
245 sources = [
246 "%s",
247 "%s",
248 "%s",
249 ],
250 }
Mirko Bonadei86d053c2019-10-17 21:32:04 +0200251 rtc_library("foo_bar") {
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200252 sources = [
253 "%s",
254 "%s",
255 "%s",
256 ],
257 }
258 """ % (tuple(sources) * 2)))
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100259 self.input_api.files = [MockFile(self.file_path)]
260 errors = PRESUBMIT.CheckNoMixingSources(self.input_api,
261 [MockFile(self.file_path)],
262 self.output_api)
263 self.assertEqual(number_of_errors, len(errors))
264 if number_of_errors == 1:
265 for source in sources:
266 if not source.endswith('.h'):
267 self.assertTrue(source in str(errors[0]))
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200268
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100269 def _GenerateBuildFile(self, content):
270 with open(self.file_path, 'w') as f:
271 f.write(content)
Mirko Bonadei4dc4e252017-09-19 13:49:16 +0200272
273
Mirko Bonadeia6395132021-07-22 17:35:59 +0200274class CheckAssertUsageTest(unittest.TestCase):
275 def setUp(self):
276 self.input_api = MockInputApi()
277 self.output_api = MockOutputApi()
278 self._content_with_assert = [
279 'void Foo() {',
280 ' assert(true);',
281 '}'
282 ]
283 self._content_without_assert = [
284 'void Foo() {',
285 ' RTC_CHECK(true);',
286 '}'
287 ]
288
289 def testDetectsAssertInCcFile(self):
290 self.input_api.files = [
291 MockFile('with_assert.cc', self._content_with_assert),
292 MockFile('without_assert.cc', self._content_without_assert),
293 ]
294 errors = PRESUBMIT.CheckAssertUsage(
295 self.input_api, self.output_api, lambda x: True)
296 self.assertEqual(1, len(errors))
297 self.assertEqual('with_assert.cc', errors[0].items[0])
298
299 def testDetectsAssertInHeaderFile(self):
300 self.input_api.files = [
301 MockFile('with_assert.h', self._content_with_assert),
302 MockFile('without_assert.h', self._content_without_assert),
303 ]
304 errors = PRESUBMIT.CheckAssertUsage(
305 self.input_api, self.output_api, lambda x: True)
306 self.assertEqual(1, len(errors))
307 self.assertEqual('with_assert.h', errors[0].items[0])
308
309 def testDetectsAssertInObjCFile(self):
310 self.input_api.files = [
311 MockFile('with_assert.m', self._content_with_assert),
312 MockFile('without_assert.m', self._content_without_assert),
313 ]
314 errors = PRESUBMIT.CheckAssertUsage(
315 self.input_api, self.output_api, lambda x: True)
316 self.assertEqual(1, len(errors))
317 self.assertEqual('with_assert.m', errors[0].items[0])
318
319 def testDetectsAssertInObjCppFile(self):
320 self.input_api.files = [
321 MockFile('with_assert.mm', self._content_with_assert),
322 MockFile('without_assert.mm', self._content_without_assert),
323 ]
324 errors = PRESUBMIT.CheckAssertUsage(
325 self.input_api, self.output_api, lambda x: True)
326 self.assertEqual(1, len(errors))
327 self.assertEqual('with_assert.mm', errors[0].items[0])
328
329 def testDoesntDetectAssertInOtherFiles(self):
330 self.input_api.files = [
331 MockFile('with_assert.cpp', self._content_with_assert),
332 ]
333 errors = PRESUBMIT.CheckAssertUsage(
334 self.input_api, self.output_api, lambda x: True)
335 self.assertEqual(0, len(errors))
336
337
charujain9893e252017-09-14 13:33:22 +0200338if __name__ == '__main__':
Mirko Bonadei8cc66952020-10-30 10:13:45 +0100339 unittest.main()