| #!/usr/bin/env python |
| # Copyright 2014 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import os |
| import sys |
| import unittest |
| |
| import PRESUBMIT |
| |
| sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
| from PRESUBMIT_test_mocks import MockFile |
| from PRESUBMIT_test_mocks import MockInputApi, MockOutputApi |
| |
| _SDK_BUILD_FILE = 'mojo/public/some/path/BUILD.gn' |
| _EDK_BUILD_FILE = 'mojo/edk/some/path/BUILD.gn' |
| _SERVICE_BUILD_FILE = 'mojo/services/some_service/public/BUILD.gn' |
| _IRRELEVANT_BUILD_FILE = 'mojo/foo/some/path/BUILD.gn' |
| |
| _PACKAGE_BUILDFILES = { |
| 'SDK' : _SDK_BUILD_FILE, |
| 'EDK' : _EDK_BUILD_FILE, |
| 'services' : _SERVICE_BUILD_FILE |
| } |
| |
| class AbsoluteReferencesInBuildFilesTest(unittest.TestCase): |
| """Tests the checking for illegal absolute paths within SDK/EDK buildfiles. |
| """ |
| def setUp(self): |
| self.sdk_absolute_path = '//mojo/public/some/absolute/path' |
| self.sdk_relative_path = 'mojo/public/some/relative/path' |
| self.edk_absolute_path = '//mojo/edk/some/absolute/path' |
| self.edk_relative_path = 'mojo/edk/some/relative/path' |
| self.service_absolute_path = '//mojo/services/some/service' |
| self.service_relative_path = '../../../some/service' |
| self.whitelisted_external_path = '//testing/gtest' |
| self.non_whitelisted_external_path = '//base' |
| |
| def inputApiContainingFileWithPaths(self, filename, paths): |
| """Returns a MockInputApi object with a single file having |filename| as |
| its name and |paths| as its contents, with each path being wrapped in a |
| pair of double-quotes to match the syntax for strings within BUILD.gn |
| files.""" |
| contents = [ '"%s"' % path for path in paths ] |
| mock_file = MockFile(filename, contents) |
| mock_input_api = MockInputApi() |
| mock_input_api.files.append(mock_file) |
| return mock_input_api |
| |
| def checkWarningWithSingleItem(self, |
| warning, |
| expected_message, |
| build_file, |
| line_num, |
| referenced_path): |
| """Checks that |warning| has a message of |expected_message| and a single |
| item whose contents are the absolute path warning item for |
| (build_file, line_num, referenced_path).""" |
| self.assertEqual(expected_message, warning.message) |
| self.assertEqual(1, len(warning.items)) |
| expected_item = PRESUBMIT._PathReferenceInBuildFileWarningItem( |
| build_file, line_num, referenced_path) |
| self.assertEqual(expected_item, warning.items[0]) |
| |
| def checkSDKAbsolutePathWarningWithSingleItem(self, |
| warning, |
| package, |
| build_file, |
| line_num, |
| referenced_path): |
| """Checks that |warning| has the message for an absolute SDK path within |
| |package| and a single item whose contents are the absolute path warning |
| item for (build_file, line_num, referenced_path).""" |
| expected_message = \ |
| PRESUBMIT._ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGES[package] |
| self.checkWarningWithSingleItem(warning, |
| expected_message, |
| build_file, |
| line_num, |
| referenced_path) |
| |
| def _testAbsoluteSDKReferenceInPackage(self, package): |
| """Tests that an absolute SDK path within |package| is flagged.""" |
| buildfile = _PACKAGE_BUILDFILES[package] |
| mock_input_api = self.inputApiContainingFileWithPaths( |
| buildfile, |
| [ self.sdk_relative_path, self.sdk_absolute_path ]) |
| warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) |
| |
| self.assertEqual(1, len(warnings)) |
| self.checkSDKAbsolutePathWarningWithSingleItem(warnings[0], |
| package, |
| buildfile, |
| 2, |
| self.sdk_absolute_path) |
| |
| def _testExternalReferenceInPackage(self, package): |
| """Tests that an illegal external path within |package| is flagged.""" |
| buildfile = _PACKAGE_BUILDFILES[package] |
| mock_input_api = self.inputApiContainingFileWithPaths( |
| buildfile, |
| [ self.non_whitelisted_external_path, self.whitelisted_external_path ]) |
| warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) |
| |
| if package == 'EDK': |
| # All external paths are allowed in the EDK. |
| self.assertEqual(0, len(warnings)) |
| return |
| |
| self.assertEqual(1, len(warnings)) |
| expected_message = PRESUBMIT._ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE |
| self.checkWarningWithSingleItem(warnings[0], |
| expected_message, |
| buildfile, |
| 1, |
| self.non_whitelisted_external_path) |
| |
| def testAbsoluteSDKReferenceInSDKBuildFile(self): |
| """Tests that an absolute SDK path within an SDK buildfile is flagged.""" |
| self._testAbsoluteSDKReferenceInPackage('SDK') |
| |
| def testExternalReferenceInSDKBuildFile(self): |
| """Tests that an illegal external path in an SDK buildfile is flagged.""" |
| self._testExternalReferenceInPackage('SDK') |
| |
| def testAbsoluteEDKReferenceInSDKBuildFile(self): |
| """Tests that an absolute EDK path in an SDK buildfile is flagged.""" |
| mock_input_api = self.inputApiContainingFileWithPaths( |
| _SDK_BUILD_FILE, |
| [ self.edk_absolute_path ]) |
| warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) |
| |
| self.assertEqual(1, len(warnings)) |
| expected_message = PRESUBMIT._ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE |
| self.checkWarningWithSingleItem(warnings[0], |
| expected_message, |
| _SDK_BUILD_FILE, |
| 1, |
| self.edk_absolute_path) |
| |
| def testAbsoluteSDKReferenceInEDKBuildFile(self): |
| """Tests that an absolute SDK path within an EDK buildfile is flagged.""" |
| self._testAbsoluteSDKReferenceInPackage('EDK') |
| |
| def testAbsoluteEDKReferenceInEDKBuildFile(self): |
| """Tests that an absolute EDK path in an EDK buildfile is flagged.""" |
| mock_input_api = self.inputApiContainingFileWithPaths( |
| _EDK_BUILD_FILE, |
| [ self.edk_absolute_path, self.edk_relative_path ]) |
| warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) |
| |
| self.assertEqual(1, len(warnings)) |
| expected_message = PRESUBMIT._ILLEGAL_EDK_ABSOLUTE_PATH_WARNING_MESSAGE |
| self.checkWarningWithSingleItem(warnings[0], |
| expected_message, |
| _EDK_BUILD_FILE, |
| 1, |
| self.edk_absolute_path) |
| |
| def testExternalReferenceInEDKBuildFile(self): |
| """Tests that an external path in an EDK buildfile is not flagged.""" |
| self._testExternalReferenceInPackage('EDK') |
| |
| def testAbsoluteSDKReferenceInServiceBuildFile(self): |
| """Tests that an absolute SDK path within a service's public buildfile is |
| flagged.""" |
| self._testAbsoluteSDKReferenceInPackage("services") |
| |
| def testAbsoluteServiceReferenceInServiceBuildFile(self): |
| """Tests that an absolute path to a service within a service's public |
| buildfile is flagged.""" |
| mock_input_api = self.inputApiContainingFileWithPaths( |
| _SERVICE_BUILD_FILE, |
| [ self.service_relative_path, self.service_absolute_path ]) |
| warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) |
| |
| self.assertEqual(1, len(warnings)) |
| expected_message = \ |
| PRESUBMIT._ILLEGAL_SERVICES_ABSOLUTE_PATH_WARNING_MESSAGE |
| self.checkWarningWithSingleItem(warnings[0], |
| expected_message, |
| _SERVICE_BUILD_FILE, |
| 2, |
| self.service_absolute_path) |
| |
| def testExternalReferenceInServiceBuildFile(self): |
| """Tests that an illegal external path in a service's buildfile is flagged |
| .""" |
| self._testExternalReferenceInPackage("services") |
| |
| def testIrrelevantBuildFile(self): |
| """Tests that nothing is flagged in a non SDK/EDK buildfile.""" |
| mock_input_api = self.inputApiContainingFileWithPaths( |
| _IRRELEVANT_BUILD_FILE, |
| [ self.sdk_absolute_path, |
| self.sdk_relative_path, |
| self.edk_absolute_path, |
| self.edk_relative_path, |
| self.non_whitelisted_external_path, |
| self.whitelisted_external_path ]) |
| warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) |
| self.assertEqual(0, len(warnings)) |
| |
| class SourceSetTypesInBuildFilesTest(unittest.TestCase): |
| """Tests checking of correct source set types within SDK/EDK buildfiles.""" |
| |
| def inputApiContainingFileWithSourceSets(self, filename, source_sets): |
| """Returns a MockInputApi object containing a single file having |filename| |
| as its name and |source_sets| as its contents.""" |
| mock_file = MockFile(filename, source_sets) |
| mock_input_api = MockInputApi() |
| mock_input_api.files.append(mock_file) |
| return mock_input_api |
| |
| def checkWarningWithSingleItem(self, |
| warning, |
| package, |
| build_file, |
| line_num): |
| """Checks that warning has the expected incorrect source set type message |
| for |package| and a single item whose contents are the incorrect source |
| set type item for (build_file, line_num).""" |
| expected_message = \ |
| PRESUBMIT._INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGES[package] |
| self.assertEqual(expected_message, warning.message) |
| self.assertEqual(1, len(warning.items)) |
| expected_item = PRESUBMIT._IncorrectSourceSetTypeWarningItem( |
| build_file, line_num) |
| self.assertEqual(expected_item, warning.items[0]) |
| |
| def _testNakedSourceSetInPackage(self, package): |
| """Tests that a source_set within |package| is flagged.""" |
| buildfile = _PACKAGE_BUILDFILES[package] |
| naked_source_set = 'source_set(' |
| correct_source_set = 'mojo_sdk_source_set(' |
| if package == 'EDK': |
| correct_source_set = 'mojo_edk_source_set(' |
| mock_input_api = self.inputApiContainingFileWithSourceSets( |
| buildfile, |
| [ correct_source_set, naked_source_set ]) |
| warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) |
| |
| self.assertEqual(1, len(warnings)) |
| self.checkWarningWithSingleItem(warnings[0], package, buildfile, 2) |
| |
| def _testWrongTypeOfWrapperSourceSetInPackage(self, package): |
| """Tests that the wrong type of wrapper source_set in |package| is flagged |
| (e.g., mojo_edk_source_set within the SDK).""" |
| buildfile = _PACKAGE_BUILDFILES[package] |
| mock_input_api = self.inputApiContainingFileWithSourceSets( |
| buildfile, |
| [ 'mojo_sdk_source_set(', 'mojo_edk_source_set(' ]) |
| warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) |
| |
| self.assertEqual(1, len(warnings)) |
| warning_line = 2 |
| if package == 'EDK': |
| warning_line = 1 |
| self.checkWarningWithSingleItem(warnings[0], |
| package, |
| buildfile, |
| warning_line) |
| |
| def testNakedSourceSetInSDKBuildFile(self): |
| """Tests that a source_set within the SDK is flagged.""" |
| self._testNakedSourceSetInPackage('SDK') |
| |
| def testPythonSourceSetInSDKBuildFile(self): |
| """Tests that a python_binary_source_set within an SDK buildfile is |
| accepted.""" |
| mock_input_api = self.inputApiContainingFileWithSourceSets( |
| _SDK_BUILD_FILE, |
| [ 'mojo_sdk_source_set(', 'python_binary_source_set(' ]) |
| warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) |
| |
| self.assertEqual(0, len(warnings)) |
| |
| def testEDKSourceSetInSDKBuildFile(self): |
| """Tests that a mojo_edk_source_set within an SDK buildfile is flagged.""" |
| self._testWrongTypeOfWrapperSourceSetInPackage('SDK') |
| |
| def testNakedSourceSetInEDKBuildFile(self): |
| """Tests that a source_set within the EDK is flagged.""" |
| self._testNakedSourceSetInPackage('EDK') |
| |
| def testSDKSourceSetInEDKBuildFile(self): |
| """Tests that a mojo_sdk_source_set within an EDK buildfile is flagged.""" |
| self._testWrongTypeOfWrapperSourceSetInPackage('EDK') |
| |
| def testNakedSourceSetInServiceBuildFile(self): |
| """Tests that a source_set within a service's public buildfile is flagged. |
| """ |
| self._testNakedSourceSetInPackage("services") |
| |
| def testEDKSourceSetInServiceBuildFile(self): |
| """Tests that a mojo_edk_source_set within a service's public buildfile is |
| flagged.""" |
| self._testWrongTypeOfWrapperSourceSetInPackage("services") |
| |
| def testIrrelevantBuildFile(self): |
| """Tests that a source_set in a non-SDK/EDK buildfile isn't flagged.""" |
| mock_input_api = self.inputApiContainingFileWithSourceSets( |
| _IRRELEVANT_BUILD_FILE, |
| [ 'source_set(' ]) |
| warnings = PRESUBMIT._BuildFileChecks(mock_input_api, MockOutputApi()) |
| self.assertEqual(0, len(warnings)) |
| |
| if __name__ == '__main__': |
| unittest.main() |