1# Copyright 2024, The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Class that facilitates testing with ModuleInfo objects. 16 17Contains methods to create module objects representing various types 18of tests that can be run in Atest, as well as the corresponding ModuleInfo 19object, for use in unit tests. 20""" 21 22import pathlib 23import tempfile 24 25from atest import constants 26from atest import module_info 27from atest.test_finders import test_info 28from atest.test_finders.test_info import TestInfo 29from atest.test_runners import atest_tf_test_runner 30from pyfakefs import fake_filesystem_unittest 31 32 33class ModuleInfoTest(fake_filesystem_unittest.TestCase): 34 """Fixture for tests that require interacting with module-info.""" 35 36 def setUp(self): 37 self.setUpPyfakefs() 38 self.product_out_path = pathlib.Path('/src/out/product') 39 self.product_out_path.mkdir(parents=True) 40 41 def create_empty_module_info(self): 42 """Creates an empty ModuleInfo object.""" 43 fake_temp_file = self.product_out_path.joinpath( 44 next(tempfile._get_candidate_names()) 45 ) 46 self.fs.create_file(fake_temp_file, contents='{}') 47 return module_info.load_from_file(module_file=fake_temp_file) 48 49 def create_module_info(self, modules: list[dict] = None): 50 """Creates a ModuleInfo object from the given list of modules.""" 51 mod_info = self.create_empty_module_info() 52 modules = modules or [] 53 54 for m in modules: 55 mod_info.name_to_module_info[m[constants.MODULE_INFO_ID]] = m 56 57 return mod_info 58 59 def assertContainsSubset(self, expected_subset, actual_set): 60 """Checks whether actual iterable is a superset of expected iterable.""" 61 missing = set(expected_subset) - set(actual_set) 62 if not missing: 63 return 64 65 self.fail( 66 f'Missing elements {missing}\n' 67 f'Expected: {expected_subset}\n' 68 f'Actual: {actual_set}' 69 ) 70 71 72def host_jar_module(name, installed): 73 74 return module( 75 name=name, 76 supported_variants=['HOST'], 77 installed=installed, 78 auto_test_config=[], 79 compatibility_suites=[], 80 ) 81 82 83def device_driven_test_module( 84 name, 85 installed=None, 86 compatibility_suites=None, 87 host_deps=None, 88 class_type=None, 89 is_unit_test=None, 90): 91 92 name = name or 'hello_world_test' 93 module_path = 'example_module/project' 94 95 return test_module( 96 name=name, 97 supported_variants=['DEVICE'], 98 compatibility_suites=compatibility_suites, 99 installed=installed or [f'out/product/vsoc_x86/{name}/{name}.apk'], 100 host_deps=host_deps, 101 class_type=class_type or ['APP'], 102 module_path=module_path, 103 is_unit_test=is_unit_test, 104 ) 105 106 107def device_driven_multi_config_test_module( 108 name, 109 installed=None, 110 compatibility_suites=None, 111 host_deps=None, 112 class_type=None, 113): 114 115 module_path = 'example_module/project' 116 return test_module( 117 name=name, 118 supported_variants=['DEVICE'], 119 compatibility_suites=compatibility_suites, 120 installed=installed or [f'out/product/vsoc_x86/{name}/{name}.apk'], 121 auto_test_config=[False], 122 test_configs=[ 123 f'{module_path}/configs/Config1.xml', 124 f'{module_path}/configs/Config2.xml', 125 ], 126 host_deps=host_deps, 127 class_type=class_type or ['APP'], 128 module_path=module_path, 129 ) 130 131 132def robolectric_test_module(name): 133 name = name or 'hello_world_test' 134 return test_module( 135 name=name, 136 supported_variants=['DEVICE'], 137 installed=[f'out/host/linux-x86/{name}/{name}.jar'], 138 compatibility_suites=['robolectric-tests'], 139 ) 140 141 142def host_driven_device_test_module(name, libs=None): 143 name = name or 'hello_world_test' 144 return test_module( 145 name=name, 146 supported_variants=['HOST'], 147 installed=[f'out/host/linux-x86/{name}/{name}.jar'], 148 compatibility_suites=['null-suite'], 149 libs=libs, 150 ) 151 152 153def multi_variant_unit_test_module(name): 154 155 name = name or 'hello_world_test' 156 157 return test_module( 158 name=name, 159 supported_variants=['HOST', 'DEVICE'], 160 installed=[ 161 f'out/host/linux-x86/{name}/{name}.cc', 162 f'out/product/vsoc_x86/{name}/{name}.cc', 163 ], 164 compatibility_suites=['host-unit-tests'], 165 is_unit_test='true', 166 ) 167 168 169def test_module( 170 name, 171 supported_variants, 172 installed, 173 auto_test_config=[True], 174 test_configs=[None], 175 compatibility_suites=None, 176 libs=None, 177 host_deps=None, 178 class_type=None, 179 module_path=None, 180 is_unit_test=None, 181): 182 """Creates a module object which with properties specific to a test module.""" 183 return module( 184 name=name, 185 supported_variants=supported_variants, 186 installed=installed, 187 auto_test_config=auto_test_config, 188 test_configs=test_configs, 189 compatibility_suites=compatibility_suites or ['null-suite'], 190 libs=libs, 191 host_deps=host_deps, 192 class_type=class_type, 193 module_path=[module_path], 194 is_unit_test=is_unit_test, 195 ) 196 197 198def module( 199 name, 200 supported_variants, 201 installed, 202 auto_test_config=None, 203 test_configs=None, 204 compatibility_suites=None, 205 libs=None, 206 host_deps=None, 207 class_type=None, 208 module_path=None, 209 is_unit_test=None, 210): 211 """Creates a ModuleInfo object. 212 213 This substitutes its creation from a module-info file for test purposes. 214 """ 215 216 m = {} 217 218 m[constants.MODULE_INFO_ID] = name 219 m[constants.MODULE_NAME] = name 220 m[constants.MODULE_SUPPORTED_VARIANTS] = supported_variants 221 m[constants.MODULE_INSTALLED] = installed 222 m[constants.MODULE_AUTO_TEST_CONFIG] = auto_test_config or [] 223 m[constants.MODULE_TEST_CONFIG] = test_configs or [] 224 m[constants.MODULE_COMPATIBILITY_SUITES] = compatibility_suites or [] 225 m[constants.MODULE_LIBS] = libs or [] 226 m[constants.MODULE_HOST_DEPS] = host_deps or [] 227 m[constants.MODULE_CLASS] = class_type or [] 228 m[constants.MODULE_PATH] = module_path or [] 229 m[constants.MODULE_IS_UNIT_TEST] = is_unit_test or 'false' 230 231 return m 232