# Copyright 2019 The Chromium Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import os import unittest import mock import version def _ReplaceArgs(args, *replacements): new_args = args[:] for flag, val in replacements: flag_index = args.index(flag) new_args[flag_index + 1] = val return new_args class _VersionTest(unittest.TestCase): """Unittests for the version module. """ _CHROME_VERSION_FILE = os.path.join( os.path.dirname(__file__), os.pardir, os.pardir, 'chrome', 'VERSION') _SCRIPT = os.path.join(os.path.dirname(__file__), 'version.py') _EXAMPLE_VERSION = { 'MAJOR': '74', 'MINOR': '0', 'BUILD': '3720', 'PATCH': '0', } _EXAMPLE_TEMPLATE = ( 'full = "@MAJOR@.@MINOR@.@BUILD@.@PATCH@" ' 'major = "@MAJOR@" minor = "@MINOR@" ' 'build = "@BUILD@" patch = "@PATCH@" version_id = @VERSION_ID@ ') _ANDROID_CHROME_VARS = [ 'chrome_version_code', 'monochrome_version_code', 'trichrome_version_code', 'webview_stable_version_code', 'webview_beta_version_code', 'webview_dev_version_code', ] _EXAMPLE_ANDROID_TEMPLATE = ( _EXAMPLE_TEMPLATE + ''.join( ['%s = "@%s@" ' % (el, el.upper()) for el in _ANDROID_CHROME_VARS])) _EXAMPLE_ARGS = [ '-f', _CHROME_VERSION_FILE, '-t', _EXAMPLE_TEMPLATE, ] _EXAMPLE_ANDROID_ARGS = _ReplaceArgs(_EXAMPLE_ARGS, ['-t', _EXAMPLE_ANDROID_TEMPLATE]) + [ '-a', 'arm', '--os', 'android', ] @staticmethod def _RunBuildOutput(new_version_values={}, get_new_args=lambda old_args: old_args): """Parameterized helper method for running the main testable method in version.py. Keyword arguments: new_version_values -- dict used to update _EXAMPLE_VERSION get_new_args -- lambda for updating _EXAMPLE_ANDROID_ARGS """ with mock.patch('version.FetchValuesFromFile') as \ fetch_values_from_file_mock: fetch_values_from_file_mock.side_effect = (lambda values, file : values.update( dict(_VersionTest._EXAMPLE_VERSION, **new_version_values))) new_args = get_new_args(_VersionTest._EXAMPLE_ARGS) return version.BuildOutput(new_args) def testFetchValuesFromFile(self): """It returns a dict in correct format - { : }, to verify assumption of other tests that mock this function """ result = {} version.FetchValuesFromFile(result, self._CHROME_VERSION_FILE) for key, val in result.items(): self.assertIsInstance(key, str) self.assertIsInstance(val, str) def testBuildOutputAndroid(self): """Assert it gives includes assignments of expected variables""" output = self._RunBuildOutput( get_new_args=lambda args: self._EXAMPLE_ANDROID_ARGS) contents = output['contents'] self.assertRegex(contents, r'\bchrome_version_code = "\d+"\s') self.assertRegex(contents, r'\bmonochrome_version_code = "\d+"\s') self.assertRegex(contents, r'\btrichrome_version_code = "\d+"\s') self.assertRegex(contents, r'\bwebview_stable_version_code = "\d+"\s') self.assertRegex(contents, r'\bwebview_beta_version_code = "\d+"\s') self.assertRegex(contents, r'\bwebview_dev_version_code = "\d+"\s') def testBuildOutputAndroidArchVariantsArm64(self): """Assert 64-bit-specific version codes""" new_template = ( self._EXAMPLE_ANDROID_TEMPLATE + "monochrome_64_32_version_code = \"@MONOCHROME_64_32_VERSION_CODE@\" " "monochrome_64_version_code = \"@MONOCHROME_64_VERSION_CODE@\" " "trichrome_64_32_version_code = \"@TRICHROME_64_32_VERSION_CODE@\" " "trichrome_64_version_code = \"@TRICHROME_64_VERSION_CODE@\" ") args_with_template = _ReplaceArgs(self._EXAMPLE_ANDROID_ARGS, ['-t', new_template]) new_args = _ReplaceArgs(args_with_template, ['-a', 'arm64']) output = self._RunBuildOutput(get_new_args=lambda args: new_args) contents = output['contents'] self.assertRegex(contents, r'\bmonochrome_64_32_version_code = "\d+"\s') self.assertRegex(contents, r'\bmonochrome_64_version_code = "\d+"\s') self.assertRegex(contents, r'\btrichrome_64_32_version_code = "\d+"\s') self.assertRegex(contents, r'\btrichrome_64_version_code = "\d+"\s') def testBuildOutputAndroidArchVariantsX64(self): """Assert 64-bit-specific version codes""" new_template = ( self._EXAMPLE_ANDROID_TEMPLATE + "monochrome_64_32_version_code = \"@MONOCHROME_64_32_VERSION_CODE@\" " "monochrome_64_version_code = \"@MONOCHROME_64_VERSION_CODE@\" " "trichrome_64_32_version_code = \"@TRICHROME_64_32_VERSION_CODE@\" " "trichrome_64_version_code = \"@TRICHROME_64_VERSION_CODE@\" ") args_with_template = _ReplaceArgs(self._EXAMPLE_ANDROID_ARGS, ['-t', new_template]) new_args = _ReplaceArgs(args_with_template, ['-a', 'x64']) output = self._RunBuildOutput(get_new_args=lambda args: new_args) contents = output['contents'] self.assertRegex(contents, r'\bmonochrome_64_32_version_code = "\d+"\s') self.assertRegex(contents, r'\bmonochrome_64_version_code = "\d+"\s') self.assertRegex(contents, r'\btrichrome_64_32_version_code = "\d+"\s') self.assertRegex(contents, r'\btrichrome_64_version_code = "\d+"\s') def testBuildOutputAndroidChromeArchInput(self): """Assert it raises an exception when using an invalid architecture input""" new_args = _ReplaceArgs(self._EXAMPLE_ANDROID_ARGS, ['-a', 'foobar']) # Mock sys.stderr because argparse will print to stderr when we pass # the invalid '-a' value. with self.assertRaises(SystemExit) as cm, mock.patch('sys.stderr'): self._RunBuildOutput(get_new_args=lambda args: new_args) self.assertEqual(cm.exception.code, 2) if __name__ == '__main__': unittest.main()