PRESUBMIT_test.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #!/usr/bin/env vpython3
  2. # Copyright 2017 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. #
  6. # Note: running this test requires installing the package python-mock.
  7. # pylint: disable=C0103
  8. # pylint: disable=F0401
  9. import PRESUBMIT
  10. import os.path
  11. import subprocess
  12. import sys
  13. import unittest
  14. sys.path.append(
  15. os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..'))
  16. import mock
  17. from PRESUBMIT_test_mocks import MockInputApi
  18. from PRESUBMIT_test_mocks import MockOutputApi
  19. from PRESUBMIT_test_mocks import MockAffectedFile
  20. class Capture(object):
  21. """Class to capture a call argument that can be tested later on."""
  22. def __init__(self):
  23. self.value = None
  24. def __eq__(self, other):
  25. self.value = other
  26. return True
  27. class PresubmitTest(unittest.TestCase):
  28. @mock.patch('subprocess.Popen')
  29. def testCheckChangeOnUploadWithBlinkAndChromiumFiles(self, _):
  30. """This verifies that CheckChangeOnUpload will only call
  31. check_blink_style.py on non-test files.
  32. """
  33. diff_file_blink_h = ['some diff']
  34. diff_file_chromium_h = ['another diff']
  35. diff_file_test_expectations = ['more diff']
  36. mock_input_api = MockInputApi()
  37. mock_input_api.files = [
  38. MockAffectedFile('file_blink.h', diff_file_blink_h),
  39. MockAffectedFile('file_chromium.h', diff_file_chromium_h),
  40. MockAffectedFile(
  41. mock_input_api.os_path.join('web_tests', 'TestExpectations'),
  42. diff_file_test_expectations)
  43. ]
  44. # Access to a protected member _CheckStyle
  45. # pylint: disable=W0212
  46. PRESUBMIT._CheckStyle(mock_input_api, MockOutputApi())
  47. capture = Capture()
  48. # pylint: disable=E1101
  49. subprocess.Popen.assert_called_with(capture, stderr=-1)
  50. self.assertEqual(5, len(capture.value))
  51. self.assertEqual(
  52. mock_input_api.os_path.join('..', '..', 'file_blink.h'),
  53. capture.value[3])
  54. @mock.patch('subprocess.Popen')
  55. def testCheckChangeOnUploadWithEmptyAffectedFileList(self, _):
  56. """This verifies that CheckChangeOnUpload will skip calling
  57. check_blink_style.py if the affected file list is empty.
  58. """
  59. diff_file_chromium1_h = ['some diff']
  60. diff_file_chromium2_h = ['another diff']
  61. diff_file_layout_test_html = ['more diff']
  62. mock_input_api = MockInputApi()
  63. mock_input_api.files = []
  64. # Access to a protected member _CheckStyle
  65. # pylint: disable=W0212
  66. PRESUBMIT._CheckStyle(mock_input_api, MockOutputApi())
  67. self.assertEqual(0, subprocess.Popen.call_count)
  68. def test_FilterPaths(self):
  69. """This verifies that _FilterPaths removes expected paths."""
  70. diff_file_chromium1_h = ['some diff']
  71. diff_web_tests_html = ['more diff']
  72. diff_presubmit = ['morer diff']
  73. diff_test_expectations = ['morest diff']
  74. mock_input_api = MockInputApi()
  75. mock_input_api.files = [
  76. MockAffectedFile('file_chromium1.h', diff_file_chromium1_h),
  77. MockAffectedFile(
  78. mock_input_api.os_path.join('web_tests', 'some_tests.html'),
  79. diff_web_tests_html),
  80. MockAffectedFile(
  81. mock_input_api.os_path.join('web_tests', 'TestExpectations'),
  82. diff_test_expectations),
  83. # Note that this path must have a slash, whereas most other paths
  84. # must have os-standard path separators.
  85. MockAffectedFile('blink/PRESUBMIT', diff_presubmit),
  86. ]
  87. # Access to a protected member _FilterPaths
  88. # pylint: disable=W0212
  89. filtered = PRESUBMIT._FilterPaths(mock_input_api)
  90. self.assertEqual([
  91. mock_input_api.os_path.join('..', '..', 'file_chromium1.h'),
  92. ], filtered)
  93. def testCheckPublicHeaderWithBlinkMojo(self):
  94. """This verifies that _CheckForWrongMojomIncludes detects -blink mojo
  95. headers in public files.
  96. """
  97. mock_input_api = MockInputApi()
  98. potentially_bad_content = \
  99. '#include "public/platform/modules/cache_storage.mojom-blink.h"'
  100. mock_input_api.files = [
  101. MockAffectedFile(
  102. mock_input_api.os_path.join('third_party', 'blink', 'public',
  103. 'a_header.h'),
  104. [potentially_bad_content], None)
  105. ]
  106. # Access to a protected member _CheckForWrongMojomIncludes
  107. # pylint: disable=W0212
  108. errors = PRESUBMIT._CheckForWrongMojomIncludes(mock_input_api,
  109. MockOutputApi())
  110. self.assertEqual(
  111. 'Public blink headers using Blink variant mojoms found. ' +
  112. 'You must include .mojom-forward.h or .mojom-shared.h instead:',
  113. errors[0].message)
  114. def testCheckInternalHeaderWithBlinkMojo(self):
  115. """This verifies that _CheckForWrongMojomIncludes accepts -blink mojo
  116. headers in blink internal files.
  117. """
  118. mock_input_api = MockInputApi()
  119. potentially_bad_content = """
  120. #include "public/platform/modules/cache_storage.mojom-blink.h"
  121. #include "public/platform/modules/cache_storage.mojom-blink-forward.h"
  122. #include "public/platform/modules/cache_storage.mojom-blink-test-utils.h"
  123. """
  124. mock_input_api.files = [
  125. MockAffectedFile(
  126. mock_input_api.os_path.join('third_party', 'blink', 'renderer',
  127. 'core', 'a_header.h'),
  128. [potentially_bad_content], None)
  129. ]
  130. # Access to a protected member _CheckForWrongMojomIncludes
  131. # pylint: disable=W0212
  132. errors = PRESUBMIT._CheckForWrongMojomIncludes(mock_input_api,
  133. MockOutputApi())
  134. self.assertEqual([], errors)
  135. class CxxDependencyTest(unittest.TestCase):
  136. allow_list = [
  137. 'base::OnceCallback<void()>',
  138. 'base::RepeatingCallback<void()>',
  139. 'gfx::ColorSpace',
  140. 'gfx::CubicBezier',
  141. 'gfx::ICCProfile',
  142. 'gfx::Point',
  143. 'gfx::Rect',
  144. 'scoped_refptr<base::SingleThreadTaskRunner>',
  145. ]
  146. disallow_list = [
  147. 'content::RenderFrame',
  148. 'gfx::Canvas',
  149. 'net::IPEndPoint',
  150. 'ui::Clipboard',
  151. ]
  152. disallow_message = []
  153. def runCheck(self, filename, file_contents):
  154. mock_input_api = MockInputApi()
  155. mock_input_api.files = [
  156. MockAffectedFile(filename, file_contents),
  157. ]
  158. # Access to a protected member
  159. # pylint: disable=W0212
  160. return PRESUBMIT._CheckForForbiddenChromiumCode(
  161. mock_input_api, MockOutputApi())
  162. # References in comments should never be checked.
  163. def testCheckCommentsIgnored(self):
  164. filename = 'third_party/blink/renderer/core/frame/frame.cc'
  165. for item in self.allow_list:
  166. errors = self.runCheck(filename, ['// %s' % item])
  167. self.assertEqual([], errors)
  168. for item in self.disallow_list:
  169. errors = self.runCheck(filename, ['// %s' % item])
  170. self.assertEqual([], errors)
  171. # References in Test files should never be checked.
  172. def testCheckTestsIgnored(self):
  173. filename = 'third_party/blink/rendere/core/frame/frame_test.cc'
  174. for item in self.allow_list:
  175. errors = self.runCheck(filename, ['// %s' % item])
  176. self.assertEqual([], errors)
  177. for item in self.disallow_list:
  178. errors = self.runCheck(filename, ['// %s' % item])
  179. self.assertEqual([], errors)
  180. # core, modules, public, et cetera should all have dependency enforcement.
  181. def testCheckCoreEnforcement(self):
  182. filename = 'third_party/blink/renderer/core/frame/frame.cc'
  183. for item in self.allow_list:
  184. errors = self.runCheck(filename, ['%s' % item])
  185. self.assertEqual([], errors)
  186. for item in self.disallow_list:
  187. errors = self.runCheck(filename, ['%s' % item])
  188. self.assertEqual(1, len(errors))
  189. self.assertRegex(errors[0].message,
  190. r'^[^:]+:\d+ uses disallowed identifier .+$')
  191. def testCheckModulesEnforcement(self):
  192. filename = 'third_party/blink/renderer/modules/modules_initializer.cc'
  193. for item in self.allow_list:
  194. errors = self.runCheck(filename, ['%s' % item])
  195. self.assertEqual([], errors)
  196. for item in self.disallow_list:
  197. errors = self.runCheck(filename, ['%s' % item])
  198. self.assertEqual(1, len(errors))
  199. self.assertRegex(errors[0].message,
  200. r'^[^:]+:\d+ uses disallowed identifier .+$')
  201. def testCheckPublicEnforcement(self):
  202. filename = 'third_party/blink/renderer/public/platform/web_thread.h'
  203. for item in self.allow_list:
  204. errors = self.runCheck(filename, ['%s' % item])
  205. self.assertEqual([], errors)
  206. for item in self.disallow_list:
  207. errors = self.runCheck(filename, ['%s' % item])
  208. self.assertEqual(1, len(errors))
  209. self.assertRegex(errors[0].message,
  210. r'^[^:]+:\d+ uses disallowed identifier .+$')
  211. # platform and controller should be opted out of enforcement, but aren't
  212. # currently checked because the PRESUBMIT test mocks are missing too
  213. # much functionality...
  214. # External module checks should not affect CSS files.
  215. def testCheckCSSIgnored(self):
  216. filename = 'third_party/blink/renderer/someFile.css'
  217. errors = self.runCheck(filename,
  218. ['.toolbar::after { color: pink; }\n'])
  219. self.assertEqual([], errors)
  220. if __name__ == '__main__':
  221. unittest.main()