#!/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()