• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env vpython3
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
11from __future__ import absolute_import
12import os
13import shutil
14import tempfile
15import textwrap
16import unittest
17
18import PRESUBMIT
19# pylint: disable=line-too-long
20from presubmit_test_mocks import MockInputApi, MockOutputApi, MockFile, MockChange
21
22
23class CheckBugEntryFieldTest(unittest.TestCase):
24  def testCommitMessageBugEntryWithNoError(self):
25    mock_input_api = MockInputApi()
26    mock_output_api = MockOutputApi()
27    mock_input_api.change = MockChange([], ['webrtc:1234'])
28    errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
29                                                  mock_output_api)
30    self.assertEqual(0, len(errors))
31
32  def testCommitMessageBugEntryReturnError(self):
33    mock_input_api = MockInputApi()
34    mock_output_api = MockOutputApi()
35    mock_input_api.change = MockChange([], ['webrtc:1234', 'webrtc=4321'])
36    errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
37                                                  mock_output_api)
38    self.assertEqual(1, len(errors))
39    self.assertEqual(('Bogus Bug entry: webrtc=4321. Please specify'
40                      ' the issue tracker prefix and the issue number,'
41                      ' separated by a colon, e.g. webrtc:123 or'
42                      ' chromium:12345.'), str(errors[0]))
43
44  def testCommitMessageBugEntryWithoutPrefix(self):
45    mock_input_api = MockInputApi()
46    mock_output_api = MockOutputApi()
47    mock_input_api.change = MockChange([], ['1234'])
48    errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
49                                                  mock_output_api)
50    self.assertEqual(1, len(errors))
51    self.assertEqual(('Bug entry requires issue tracker prefix, '
52                      'e.g. webrtc:1234'), str(errors[0]))
53
54  def testCommitMessageBugEntryIsNone(self):
55    mock_input_api = MockInputApi()
56    mock_output_api = MockOutputApi()
57    mock_input_api.change = MockChange([], ['None'])
58    errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
59                                                  mock_output_api)
60    self.assertEqual(0, len(errors))
61
62  def testCommitMessageBugEntrySupportInternalBugReference(self):
63    mock_input_api = MockInputApi()
64    mock_output_api = MockOutputApi()
65    mock_input_api.change.BUG = 'b/12345'
66    errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
67                                                  mock_output_api)
68    self.assertEqual(0, len(errors))
69    mock_input_api.change.BUG = 'b/12345, webrtc:1234'
70    errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
71                                                  mock_output_api)
72    self.assertEqual(0, len(errors))
73
74
75class CheckNewlineAtTheEndOfProtoFilesTest(unittest.TestCase):
76  def setUp(self):
77    self.tmp_dir = tempfile.mkdtemp()
78    self.proto_file_path = os.path.join(self.tmp_dir, 'foo.proto')
79    self.input_api = MockInputApi()
80    self.output_api = MockOutputApi()
81
82  def tearDown(self):
83    shutil.rmtree(self.tmp_dir, ignore_errors=True)
84
85  def testErrorIfProtoFileDoesNotEndWithNewline(self):
86    self._GenerateProtoWithoutNewlineAtTheEnd()
87    self.input_api.files = [MockFile(self.proto_file_path)]
88    errors = PRESUBMIT.CheckNewlineAtTheEndOfProtoFiles(
89        self.input_api, self.output_api, lambda x: True)
90    self.assertEqual(1, len(errors))
91    self.assertEqual(
92        'File %s must end with exactly one newline.' % self.proto_file_path,
93        str(errors[0]))
94
95  def testNoErrorIfProtoFileEndsWithNewline(self):
96    self._GenerateProtoWithNewlineAtTheEnd()
97    self.input_api.files = [MockFile(self.proto_file_path)]
98    errors = PRESUBMIT.CheckNewlineAtTheEndOfProtoFiles(
99        self.input_api, self.output_api, lambda x: True)
100    self.assertEqual(0, len(errors))
101
102  def _GenerateProtoWithNewlineAtTheEnd(self):
103    with open(self.proto_file_path, 'w') as f:
104      f.write(
105          textwrap.dedent("""
106        syntax = "proto2";
107        option optimize_for = LITE_RUNTIME;
108        package webrtc.audioproc;
109      """))
110
111  def _GenerateProtoWithoutNewlineAtTheEnd(self):
112    with open(self.proto_file_path, 'w') as f:
113      f.write(
114          textwrap.dedent("""
115        syntax = "proto2";
116        option optimize_for = LITE_RUNTIME;
117        package webrtc.audioproc;"""))
118
119
120class CheckNoMixingSourcesTest(unittest.TestCase):
121  def setUp(self):
122    self.tmp_dir = tempfile.mkdtemp()
123    self.file_path = os.path.join(self.tmp_dir, 'BUILD.gn')
124    self.input_api = MockInputApi()
125    self.output_api = MockOutputApi()
126
127  def tearDown(self):
128    shutil.rmtree(self.tmp_dir, ignore_errors=True)
129
130  def testErrorIfCAndCppAreMixed(self):
131    self._AssertNumberOfErrorsWithSources(1, ['foo.c', 'bar.cc', 'bar.h'])
132
133  def testErrorIfCAndObjCAreMixed(self):
134    self._AssertNumberOfErrorsWithSources(1, ['foo.c', 'bar.m', 'bar.h'])
135
136  def testErrorIfCAndObjCppAreMixed(self):
137    self._AssertNumberOfErrorsWithSources(1, ['foo.c', 'bar.mm', 'bar.h'])
138
139  def testErrorIfCppAndObjCAreMixed(self):
140    self._AssertNumberOfErrorsWithSources(1, ['foo.cc', 'bar.m', 'bar.h'])
141
142  def testErrorIfCppAndObjCppAreMixed(self):
143    self._AssertNumberOfErrorsWithSources(1, ['foo.cc', 'bar.mm', 'bar.h'])
144
145  def testNoErrorIfOnlyC(self):
146    self._AssertNumberOfErrorsWithSources(0, ['foo.c', 'bar.c', 'bar.h'])
147
148  def testNoErrorIfOnlyCpp(self):
149    self._AssertNumberOfErrorsWithSources(0, ['foo.cc', 'bar.cc', 'bar.h'])
150
151  def testNoErrorIfOnlyObjC(self):
152    self._AssertNumberOfErrorsWithSources(0, ['foo.m', 'bar.m', 'bar.h'])
153
154  def testNoErrorIfOnlyObjCpp(self):
155    self._AssertNumberOfErrorsWithSources(0, ['foo.mm', 'bar.mm', 'bar.h'])
156
157  def testNoErrorIfObjCAndObjCppAreMixed(self):
158    self._AssertNumberOfErrorsWithSources(0, ['foo.m', 'bar.mm', 'bar.h'])
159
160  def testNoErrorIfSourcesAreInExclusiveIfBranches(self):
161    self._GenerateBuildFile(
162        textwrap.dedent("""
163      rtc_library("bar_foo") {
164        if (is_win) {
165          sources = [
166            "bar.cc",
167          ],
168        }
169        if (is_ios) {
170          sources = [
171            "bar.mm",
172          ],
173        }
174      }
175      rtc_library("foo_bar") {
176        if (is_win) {
177          sources = [
178            "foo.cc",
179          ],
180        }
181        if (is_ios) {
182          sources = [
183            "foo.mm",
184          ],
185        }
186      }
187    """))
188    self.input_api.files = [MockFile(self.file_path)]
189    errors = PRESUBMIT.CheckNoMixingSources(self.input_api,
190                                            [MockFile(self.file_path)],
191                                            self.output_api)
192    self.assertEqual(0, len(errors))
193
194  def testErrorIfSourcesAreNotInExclusiveIfBranches(self):
195    self._GenerateBuildFile(
196        textwrap.dedent("""
197      rtc_library("bar_foo") {
198        if (is_win) {
199          sources = [
200            "bar.cc",
201          ],
202        }
203        if (foo_bar) {
204          sources += [
205            "bar.mm",
206          ],
207        }
208      }
209      rtc_library("foo_bar") {
210        if (is_win) {
211          sources = [
212            "foo.cc",
213          ],
214        }
215        if (foo_bar) {
216          sources += [
217            "foo.mm",
218          ],
219        }
220        if (is_ios) {
221          sources = [
222            "bar.m",
223            "bar.c",
224          ],
225        }
226      }
227    """))
228    self.input_api.files = [MockFile(self.file_path)]
229    errors = PRESUBMIT.CheckNoMixingSources(self.input_api,
230                                            [MockFile(self.file_path)],
231                                            self.output_api)
232    self.assertEqual(1, len(errors))
233    self.assertTrue('bar.cc' in str(errors[0]))
234    self.assertTrue('bar.mm' in str(errors[0]))
235    self.assertTrue('foo.cc' in str(errors[0]))
236    self.assertTrue('foo.mm' in str(errors[0]))
237    self.assertTrue('bar.m' in str(errors[0]))
238    self.assertTrue('bar.c' in str(errors[0]))
239
240  def _AssertNumberOfErrorsWithSources(self, number_of_errors, sources):
241    assert len(sources) == 3, 'This function accepts a list of 3 source files'
242    self._GenerateBuildFile(
243        textwrap.dedent("""
244      rtc_static_library("bar_foo") {
245        sources = [
246          "%s",
247          "%s",
248          "%s",
249        ],
250      }
251      rtc_library("foo_bar") {
252        sources = [
253          "%s",
254          "%s",
255          "%s",
256        ],
257      }
258    """ % (tuple(sources) * 2)))
259    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]))
268
269  def _GenerateBuildFile(self, content):
270    with open(self.file_path, 'w') as f:
271      f.write(content)
272
273
274class CheckAssertUsageTest(unittest.TestCase):
275  def setUp(self):
276    self.input_api = MockInputApi()
277    self.output_api = MockOutputApi()
278    self._content_with_assert = ['void Foo() {', '    assert(true);', '}']
279    self._content_without_assert = ['void Foo() {', '    RTC_CHECK(true);', '}']
280
281  def testDetectsAssertInCcFile(self):
282    self.input_api.files = [
283        MockFile('with_assert.cc', self._content_with_assert),
284        MockFile('without_assert.cc', self._content_without_assert),
285    ]
286    errors = PRESUBMIT.CheckAssertUsage(self.input_api,
287                                        self.output_api, lambda x: True)
288    self.assertEqual(1, len(errors))
289    self.assertEqual('with_assert.cc', errors[0].items[0])
290
291  def testDetectsAssertInHeaderFile(self):
292    self.input_api.files = [
293        MockFile('with_assert.h', self._content_with_assert),
294        MockFile('without_assert.h', self._content_without_assert),
295    ]
296    errors = PRESUBMIT.CheckAssertUsage(self.input_api,
297                                        self.output_api, lambda x: True)
298    self.assertEqual(1, len(errors))
299    self.assertEqual('with_assert.h', errors[0].items[0])
300
301  def testDetectsAssertInObjCFile(self):
302    self.input_api.files = [
303        MockFile('with_assert.m', self._content_with_assert),
304        MockFile('without_assert.m', self._content_without_assert),
305    ]
306    errors = PRESUBMIT.CheckAssertUsage(self.input_api,
307                                        self.output_api, lambda x: True)
308    self.assertEqual(1, len(errors))
309    self.assertEqual('with_assert.m', errors[0].items[0])
310
311  def testDetectsAssertInObjCppFile(self):
312    self.input_api.files = [
313        MockFile('with_assert.mm', self._content_with_assert),
314        MockFile('without_assert.mm', self._content_without_assert),
315    ]
316    errors = PRESUBMIT.CheckAssertUsage(self.input_api,
317                                        self.output_api, lambda x: True)
318    self.assertEqual(1, len(errors))
319    self.assertEqual('with_assert.mm', errors[0].items[0])
320
321  def testDoesntDetectAssertInOtherFiles(self):
322    self.input_api.files = [
323        MockFile('with_assert.cpp', self._content_with_assert),
324    ]
325    errors = PRESUBMIT.CheckAssertUsage(self.input_api,
326                                        self.output_api, lambda x: True)
327    self.assertEqual(0, len(errors))
328
329
330if __name__ == '__main__':
331  unittest.main()
332