1#!/usr/bin/env vpython3 2# Copyright 2022 The Chromium Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5"""File for testing compatible_utils.py.""" 6 7import io 8import json 9import os 10import stat 11import tempfile 12import unittest 13import unittest.mock as mock 14 15import compatible_utils 16 17 18@unittest.skipIf(os.name == 'nt', 'Fuchsia tests not supported on Windows') 19class CompatibleUtilsTest(unittest.TestCase): 20 """Test compatible_utils.py methods.""" 21 22 def test_running_unattended_returns_true_if_headless_set(self) -> None: 23 """Test |running_unattended| returns True if CHROME_HEADLESS is set.""" 24 with mock.patch('os.environ', {'SWARMING_SERVER': 0}): 25 self.assertTrue(compatible_utils.running_unattended()) 26 27 with mock.patch('os.environ', {'FOO_HEADLESS': 0}): 28 self.assertFalse(compatible_utils.running_unattended()) 29 30 def test_get_host_arch(self) -> None: 31 """Test |get_host_arch| gets the host architecture and throws 32 exceptions on errors.""" 33 supported_arches = ['x86_64', 'AMD64', 'aarch64'] 34 with mock.patch('platform.machine', side_effect=supported_arches): 35 self.assertEqual(compatible_utils.get_host_arch(), 'x64') 36 self.assertEqual(compatible_utils.get_host_arch(), 'x64') 37 self.assertEqual(compatible_utils.get_host_arch(), 'arm64') 38 39 with mock.patch('platform.machine', return_value=['fake-arch']), \ 40 self.assertRaises(NotImplementedError): 41 compatible_utils.get_host_arch() 42 43 def test_add_exec_to_file(self) -> None: 44 """Test |add_exec_to_file| adds executable bit to file.""" 45 with tempfile.NamedTemporaryFile() as f: 46 original_stat = os.stat(f.name).st_mode 47 self.assertFalse(original_stat & stat.S_IXUSR) 48 49 compatible_utils.add_exec_to_file(f.name) 50 51 new_stat = os.stat(f.name).st_mode 52 self.assertTrue(new_stat & stat.S_IXUSR) 53 54 def test_parse_host_port_splits_address_and_strips_brackets(self) -> None: 55 """Test |parse_host_port| splits ipv4 and ipv6 addresses correctly.""" 56 self.assertEqual(compatible_utils.parse_host_port('hostname:55'), 57 ('hostname', 55)) 58 self.assertEqual(compatible_utils.parse_host_port('192.168.42.40:443'), 59 ('192.168.42.40', 443)) 60 self.assertEqual( 61 compatible_utils.parse_host_port('[2001:db8::1]:8080'), 62 ('2001:db8::1', 8080)) 63 64 def test_map_filter_filter_file_throws_value_error_if_wrong_path(self 65 ) -> None: 66 """Test |map_filter_file| throws ValueError if path is missing 67 FILTER_DIR.""" 68 with self.assertRaises(ValueError): 69 compatible_utils.map_filter_file_to_package_file('foo') 70 71 with self.assertRaises(ValueError): 72 compatible_utils.map_filter_file_to_package_file('some/other/path') 73 74 with self.assertRaises(ValueError): 75 compatible_utils.map_filter_file_to_package_file('filters/file') 76 77 # No error. 78 compatible_utils.map_filter_file_to_package_file( 79 'testing/buildbot/filters/some.filter') 80 81 def test_map_filter_filter_replaces_filter_dir_with_pkg_path(self) -> None: 82 """Test |map_filter_file| throws ValueError if path is missing 83 FILTER_DIR.""" 84 self.assertEqual( 85 '/pkg/testing/buildbot/filters/some.filter', 86 compatible_utils.map_filter_file_to_package_file( 87 'foo/testing/buildbot/filters/some.filter')) 88 89 def test_get_sdk_hash_success(self) -> None: 90 """Test |get_sdk_hash| reads product_bundle.json.""" 91 with mock.patch('builtins.open', 92 return_value=io.StringIO( 93 json.dumps({'product_version': '12345'}))): 94 self.assertEqual( 95 compatible_utils.get_sdk_hash( 96 'third_party/fuchsia-sdk/images-internal/sherlock-release/' 97 'smart_display_max_eng_arrested/'), 98 ('smart_display_max_eng_arrested', '12345')) 99 100 def test_get_sdk_hash_normalize_path(self) -> None: 101 """Test |get_sdk_hash| uses path as product.""" 102 with mock.patch('builtins.open', 103 return_value=io.StringIO( 104 json.dumps({'product_version': '23456'}))): 105 self.assertEqual( 106 compatible_utils.get_sdk_hash( 107 'third_party/fuchsia-sdk/images-internal/sherlock-release/' 108 'smart_display_max_eng_arrested'), 109 ('smart_display_max_eng_arrested', '23456')) 110 111 def test_get_sdk_hash_not_found(self) -> None: 112 """Test |get_sdk_hash| fails if the product_bundle.json does not exist. 113 """ 114 with mock.patch('builtins.open', side_effect=IOError()): 115 self.assertRaises(IOError, compatible_utils.get_sdk_hash, 116 'some/image/dir') 117 118 def test_install_symbols(self): 119 """Test |install_symbols|.""" 120 def trim_noop_prefixes(path): 121 """Helper function to trim no-op path name prefixes that are 122 introduced by os.path.realpath on some platforms. These break 123 the unit tests, but have no actual effect on behavior.""" 124 # These must all end in the path separator character for the 125 # string length computation to be correct on all platforms. 126 noop_prefixes = ['/private/'] 127 for prefix in noop_prefixes: 128 if path.startswith(prefix): 129 return path[len(prefix) - 1:] 130 return path 131 132 with tempfile.TemporaryDirectory() as fuchsia_out_dir: 133 build_id = 'test_build_id' 134 symbol_file = os.path.join(fuchsia_out_dir, '.build-id', 135 build_id[:2], build_id[2:] + '.debug') 136 id_path = os.path.join(fuchsia_out_dir, 'ids.txt') 137 try: 138 binary_relpath = 'path/to/binary' 139 with open(id_path, 'w') as f: 140 f.write(f'{build_id} {binary_relpath}') 141 compatible_utils.install_symbols([id_path], fuchsia_out_dir) 142 self.assertTrue(os.path.islink(symbol_file)) 143 self.assertEqual( 144 trim_noop_prefixes(os.path.realpath(symbol_file)), 145 os.path.join(fuchsia_out_dir, binary_relpath)) 146 147 new_binary_relpath = 'path/to/new/binary' 148 with open(id_path, 'w') as f: 149 f.write(f'{build_id} {new_binary_relpath}') 150 compatible_utils.install_symbols([id_path], fuchsia_out_dir) 151 self.assertTrue(os.path.islink(symbol_file)) 152 self.assertEqual( 153 trim_noop_prefixes(os.path.realpath(symbol_file)), 154 os.path.join(fuchsia_out_dir, new_binary_relpath)) 155 finally: 156 os.remove(id_path) 157 158 159 def test_ssh_keys(self): 160 """Ensures the get_ssh_keys won't return a None.""" 161 self.assertIsNotNone(compatible_utils.get_ssh_keys()) 162 163 164if __name__ == '__main__': 165 unittest.main() 166