1# Copyright 2019 The Chromium Authors 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import os 6import unittest 7 8import mock 9import version 10 11 12def _ReplaceArgs(args, *replacements): 13 new_args = args[:] 14 for flag, val in replacements: 15 flag_index = args.index(flag) 16 new_args[flag_index + 1] = val 17 return new_args 18 19 20class _VersionTest(unittest.TestCase): 21 """Unittests for the version module. 22 """ 23 24 _CHROME_VERSION_FILE = os.path.join( 25 os.path.dirname(__file__), os.pardir, os.pardir, 'chrome', 'VERSION') 26 27 _SCRIPT = os.path.join(os.path.dirname(__file__), 'version.py') 28 29 _EXAMPLE_VERSION = { 30 'MAJOR': '74', 31 'MINOR': '0', 32 'BUILD': '3720', 33 'PATCH': '0', 34 } 35 36 _EXAMPLE_TEMPLATE = ( 37 'full = "@MAJOR@.@MINOR@.@BUILD@.@PATCH@" ' 38 'major = "@MAJOR@" minor = "@MINOR@" ' 39 'build = "@BUILD@" patch = "@PATCH@" version_id = @VERSION_ID@ ') 40 41 _ANDROID_CHROME_VARS = [ 42 'chrome_version_code', 43 'monochrome_version_code', 44 'trichrome_version_code', 45 'webview_stable_version_code', 46 'webview_beta_version_code', 47 'webview_dev_version_code', 48 ] 49 50 _EXAMPLE_ANDROID_TEMPLATE = ( 51 _EXAMPLE_TEMPLATE + ''.join( 52 ['%s = "@%s@" ' % (el, el.upper()) for el in _ANDROID_CHROME_VARS])) 53 54 _EXAMPLE_ARGS = [ 55 '-f', 56 _CHROME_VERSION_FILE, 57 '-t', 58 _EXAMPLE_TEMPLATE, 59 ] 60 61 _EXAMPLE_ANDROID_ARGS = _ReplaceArgs(_EXAMPLE_ARGS, 62 ['-t', _EXAMPLE_ANDROID_TEMPLATE]) + [ 63 '-a', 64 'arm', 65 '--os', 66 'android', 67 ] 68 69 @staticmethod 70 def _RunBuildOutput(new_version_values={}, 71 get_new_args=lambda old_args: old_args): 72 """Parameterized helper method for running the main testable method in 73 version.py. 74 75 Keyword arguments: 76 new_version_values -- dict used to update _EXAMPLE_VERSION 77 get_new_args -- lambda for updating _EXAMPLE_ANDROID_ARGS 78 """ 79 80 with mock.patch('version.FetchValuesFromFile') as \ 81 fetch_values_from_file_mock: 82 83 fetch_values_from_file_mock.side_effect = (lambda values, file : 84 values.update( 85 dict(_VersionTest._EXAMPLE_VERSION, **new_version_values))) 86 87 new_args = get_new_args(_VersionTest._EXAMPLE_ARGS) 88 return version.BuildOutput(new_args) 89 90 def testFetchValuesFromFile(self): 91 """It returns a dict in correct format - { <str>: <str> }, to verify 92 assumption of other tests that mock this function 93 """ 94 result = {} 95 version.FetchValuesFromFile(result, self._CHROME_VERSION_FILE) 96 97 for key, val in result.items(): 98 self.assertIsInstance(key, str) 99 self.assertIsInstance(val, str) 100 101 def testBuildOutputAndroid(self): 102 """Assert it gives includes assignments of expected variables""" 103 output = self._RunBuildOutput( 104 get_new_args=lambda args: self._EXAMPLE_ANDROID_ARGS) 105 contents = output['contents'] 106 107 self.assertRegex(contents, r'\bchrome_version_code = "\d+"\s') 108 self.assertRegex(contents, r'\bmonochrome_version_code = "\d+"\s') 109 self.assertRegex(contents, r'\btrichrome_version_code = "\d+"\s') 110 self.assertRegex(contents, r'\bwebview_stable_version_code = "\d+"\s') 111 self.assertRegex(contents, r'\bwebview_beta_version_code = "\d+"\s') 112 self.assertRegex(contents, r'\bwebview_dev_version_code = "\d+"\s') 113 114 def testBuildOutputAndroidArchVariantsArm64(self): 115 """Assert 64-bit-specific version codes""" 116 new_template = ( 117 self._EXAMPLE_ANDROID_TEMPLATE + 118 "monochrome_64_32_version_code = \"@MONOCHROME_64_32_VERSION_CODE@\" " 119 "monochrome_64_version_code = \"@MONOCHROME_64_VERSION_CODE@\" " 120 "trichrome_64_32_version_code = \"@TRICHROME_64_32_VERSION_CODE@\" " 121 "trichrome_64_version_code = \"@TRICHROME_64_VERSION_CODE@\" ") 122 args_with_template = _ReplaceArgs(self._EXAMPLE_ANDROID_ARGS, 123 ['-t', new_template]) 124 new_args = _ReplaceArgs(args_with_template, ['-a', 'arm64']) 125 output = self._RunBuildOutput(get_new_args=lambda args: new_args) 126 contents = output['contents'] 127 128 self.assertRegex(contents, r'\bmonochrome_64_32_version_code = "\d+"\s') 129 self.assertRegex(contents, r'\bmonochrome_64_version_code = "\d+"\s') 130 self.assertRegex(contents, r'\btrichrome_64_32_version_code = "\d+"\s') 131 self.assertRegex(contents, r'\btrichrome_64_version_code = "\d+"\s') 132 133 def testBuildOutputAndroidArchVariantsX64(self): 134 """Assert 64-bit-specific version codes""" 135 new_template = ( 136 self._EXAMPLE_ANDROID_TEMPLATE + 137 "monochrome_64_32_version_code = \"@MONOCHROME_64_32_VERSION_CODE@\" " 138 "monochrome_64_version_code = \"@MONOCHROME_64_VERSION_CODE@\" " 139 "trichrome_64_32_version_code = \"@TRICHROME_64_32_VERSION_CODE@\" " 140 "trichrome_64_version_code = \"@TRICHROME_64_VERSION_CODE@\" ") 141 args_with_template = _ReplaceArgs(self._EXAMPLE_ANDROID_ARGS, 142 ['-t', new_template]) 143 new_args = _ReplaceArgs(args_with_template, ['-a', 'x64']) 144 output = self._RunBuildOutput(get_new_args=lambda args: new_args) 145 contents = output['contents'] 146 147 self.assertRegex(contents, r'\bmonochrome_64_32_version_code = "\d+"\s') 148 self.assertRegex(contents, r'\bmonochrome_64_version_code = "\d+"\s') 149 self.assertRegex(contents, r'\btrichrome_64_32_version_code = "\d+"\s') 150 self.assertRegex(contents, r'\btrichrome_64_version_code = "\d+"\s') 151 152 def testBuildOutputAndroidChromeArchInput(self): 153 """Assert it raises an exception when using an invalid architecture input""" 154 new_args = _ReplaceArgs(self._EXAMPLE_ANDROID_ARGS, ['-a', 'foobar']) 155 # Mock sys.stderr because argparse will print to stderr when we pass 156 # the invalid '-a' value. 157 with self.assertRaises(SystemExit) as cm, mock.patch('sys.stderr'): 158 self._RunBuildOutput(get_new_args=lambda args: new_args) 159 160 self.assertEqual(cm.exception.code, 2) 161 162 163if __name__ == '__main__': 164 unittest.main() 165