1*9e94795aSAndroid Build Coastguard Worker# Copyright 2024, The Android Open Source Project 2*9e94795aSAndroid Build Coastguard Worker# 3*9e94795aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*9e94795aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*9e94795aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*9e94795aSAndroid Build Coastguard Worker# 7*9e94795aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*9e94795aSAndroid Build Coastguard Worker# 9*9e94795aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*9e94795aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*9e94795aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9e94795aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*9e94795aSAndroid Build Coastguard Worker# limitations under the License. 14*9e94795aSAndroid Build Coastguard Worker 15*9e94795aSAndroid Build Coastguard Worker"""Tests for optimized_targets.py""" 16*9e94795aSAndroid Build Coastguard Worker 17*9e94795aSAndroid Build Coastguard Workerimport json 18*9e94795aSAndroid Build Coastguard Workerimport logging 19*9e94795aSAndroid Build Coastguard Workerimport os 20*9e94795aSAndroid Build Coastguard Workerimport pathlib 21*9e94795aSAndroid Build Coastguard Workerimport re 22*9e94795aSAndroid Build Coastguard Workerimport subprocess 23*9e94795aSAndroid Build Coastguard Workerimport textwrap 24*9e94795aSAndroid Build Coastguard Workerimport unittest 25*9e94795aSAndroid Build Coastguard Workerfrom unittest import mock 26*9e94795aSAndroid Build Coastguard Workerfrom build_context import BuildContext 27*9e94795aSAndroid Build Coastguard Workerimport optimized_targets 28*9e94795aSAndroid Build Coastguard Workerfrom pyfakefs import fake_filesystem_unittest 29*9e94795aSAndroid Build Coastguard Worker 30*9e94795aSAndroid Build Coastguard Worker 31*9e94795aSAndroid Build Coastguard Workerclass GeneralTestsOptimizerTest(fake_filesystem_unittest.TestCase): 32*9e94795aSAndroid Build Coastguard Worker 33*9e94795aSAndroid Build Coastguard Worker def setUp(self): 34*9e94795aSAndroid Build Coastguard Worker self.setUpPyfakefs() 35*9e94795aSAndroid Build Coastguard Worker 36*9e94795aSAndroid Build Coastguard Worker os_environ_patcher = mock.patch.dict('os.environ', {}) 37*9e94795aSAndroid Build Coastguard Worker self.addCleanup(os_environ_patcher.stop) 38*9e94795aSAndroid Build Coastguard Worker self.mock_os_environ = os_environ_patcher.start() 39*9e94795aSAndroid Build Coastguard Worker 40*9e94795aSAndroid Build Coastguard Worker self._setup_working_build_env() 41*9e94795aSAndroid Build Coastguard Worker self._write_change_info_file() 42*9e94795aSAndroid Build Coastguard Worker test_mapping_dir = pathlib.Path('/project/path/file/path') 43*9e94795aSAndroid Build Coastguard Worker test_mapping_dir.mkdir(parents=True) 44*9e94795aSAndroid Build Coastguard Worker self._write_test_mapping_file() 45*9e94795aSAndroid Build Coastguard Worker 46*9e94795aSAndroid Build Coastguard Worker def _setup_working_build_env(self): 47*9e94795aSAndroid Build Coastguard Worker self.change_info_file = pathlib.Path('/tmp/change_info') 48*9e94795aSAndroid Build Coastguard Worker self._write_soong_ui_file() 49*9e94795aSAndroid Build Coastguard Worker self._host_out_testcases = pathlib.Path('/tmp/top/host_out_testcases') 50*9e94795aSAndroid Build Coastguard Worker self._host_out_testcases.mkdir(parents=True) 51*9e94795aSAndroid Build Coastguard Worker self._target_out_testcases = pathlib.Path('/tmp/top/target_out_testcases') 52*9e94795aSAndroid Build Coastguard Worker self._target_out_testcases.mkdir(parents=True) 53*9e94795aSAndroid Build Coastguard Worker self._product_out = pathlib.Path('/tmp/top/product_out') 54*9e94795aSAndroid Build Coastguard Worker self._product_out.mkdir(parents=True) 55*9e94795aSAndroid Build Coastguard Worker self._soong_host_out = pathlib.Path('/tmp/top/soong_host_out') 56*9e94795aSAndroid Build Coastguard Worker self._soong_host_out.mkdir(parents=True) 57*9e94795aSAndroid Build Coastguard Worker self._host_out = pathlib.Path('/tmp/top/host_out') 58*9e94795aSAndroid Build Coastguard Worker self._host_out.mkdir(parents=True) 59*9e94795aSAndroid Build Coastguard Worker 60*9e94795aSAndroid Build Coastguard Worker self._dist_dir = pathlib.Path('/tmp/top/out/dist') 61*9e94795aSAndroid Build Coastguard Worker self._dist_dir.mkdir(parents=True) 62*9e94795aSAndroid Build Coastguard Worker 63*9e94795aSAndroid Build Coastguard Worker self.mock_os_environ.update({ 64*9e94795aSAndroid Build Coastguard Worker 'CHANGE_INFO': str(self.change_info_file), 65*9e94795aSAndroid Build Coastguard Worker 'TOP': '/tmp/top', 66*9e94795aSAndroid Build Coastguard Worker 'DIST_DIR': '/tmp/top/out/dist', 67*9e94795aSAndroid Build Coastguard Worker }) 68*9e94795aSAndroid Build Coastguard Worker 69*9e94795aSAndroid Build Coastguard Worker def _write_soong_ui_file(self): 70*9e94795aSAndroid Build Coastguard Worker soong_path = pathlib.Path('/tmp/top/build/soong') 71*9e94795aSAndroid Build Coastguard Worker soong_path.mkdir(parents=True) 72*9e94795aSAndroid Build Coastguard Worker with open(os.path.join(soong_path, 'soong_ui.bash'), 'w') as f: 73*9e94795aSAndroid Build Coastguard Worker f.write(""" 74*9e94795aSAndroid Build Coastguard Worker #/bin/bash 75*9e94795aSAndroid Build Coastguard Worker echo HOST_OUT_TESTCASES='/tmp/top/host_out_testcases' 76*9e94795aSAndroid Build Coastguard Worker echo TARGET_OUT_TESTCASES='/tmp/top/target_out_testcases' 77*9e94795aSAndroid Build Coastguard Worker echo PRODUCT_OUT='/tmp/top/product_out' 78*9e94795aSAndroid Build Coastguard Worker echo SOONG_HOST_OUT='/tmp/top/soong_host_out' 79*9e94795aSAndroid Build Coastguard Worker echo HOST_OUT='/tmp/top/host_out' 80*9e94795aSAndroid Build Coastguard Worker """) 81*9e94795aSAndroid Build Coastguard Worker os.chmod(os.path.join(soong_path, 'soong_ui.bash'), 0o666) 82*9e94795aSAndroid Build Coastguard Worker 83*9e94795aSAndroid Build Coastguard Worker def _write_change_info_file(self): 84*9e94795aSAndroid Build Coastguard Worker change_info_contents = { 85*9e94795aSAndroid Build Coastguard Worker 'changes': [{ 86*9e94795aSAndroid Build Coastguard Worker 'projectPath': '/project/path', 87*9e94795aSAndroid Build Coastguard Worker 'revisions': [{ 88*9e94795aSAndroid Build Coastguard Worker 'fileInfos': [{ 89*9e94795aSAndroid Build Coastguard Worker 'path': 'file/path/file_name', 90*9e94795aSAndroid Build Coastguard Worker }], 91*9e94795aSAndroid Build Coastguard Worker }], 92*9e94795aSAndroid Build Coastguard Worker }] 93*9e94795aSAndroid Build Coastguard Worker } 94*9e94795aSAndroid Build Coastguard Worker 95*9e94795aSAndroid Build Coastguard Worker with open(self.change_info_file, 'w') as f: 96*9e94795aSAndroid Build Coastguard Worker json.dump(change_info_contents, f) 97*9e94795aSAndroid Build Coastguard Worker 98*9e94795aSAndroid Build Coastguard Worker def _write_test_mapping_file(self): 99*9e94795aSAndroid Build Coastguard Worker test_mapping_contents = { 100*9e94795aSAndroid Build Coastguard Worker 'test-mapping-group': [ 101*9e94795aSAndroid Build Coastguard Worker { 102*9e94795aSAndroid Build Coastguard Worker 'name': 'test_mapping_module', 103*9e94795aSAndroid Build Coastguard Worker }, 104*9e94795aSAndroid Build Coastguard Worker ], 105*9e94795aSAndroid Build Coastguard Worker } 106*9e94795aSAndroid Build Coastguard Worker 107*9e94795aSAndroid Build Coastguard Worker with open('/project/path/file/path/TEST_MAPPING', 'w') as f: 108*9e94795aSAndroid Build Coastguard Worker json.dump(test_mapping_contents, f) 109*9e94795aSAndroid Build Coastguard Worker 110*9e94795aSAndroid Build Coastguard Worker def test_general_tests_optimized(self): 111*9e94795aSAndroid Build Coastguard Worker optimizer = self._create_general_tests_optimizer() 112*9e94795aSAndroid Build Coastguard Worker 113*9e94795aSAndroid Build Coastguard Worker build_targets = optimizer.get_build_targets() 114*9e94795aSAndroid Build Coastguard Worker 115*9e94795aSAndroid Build Coastguard Worker expected_build_targets = set( 116*9e94795aSAndroid Build Coastguard Worker optimized_targets.GeneralTestsOptimizer._REQUIRED_MODULES 117*9e94795aSAndroid Build Coastguard Worker ) 118*9e94795aSAndroid Build Coastguard Worker expected_build_targets.add('test_mapping_module') 119*9e94795aSAndroid Build Coastguard Worker 120*9e94795aSAndroid Build Coastguard Worker self.assertSetEqual(build_targets, expected_build_targets) 121*9e94795aSAndroid Build Coastguard Worker 122*9e94795aSAndroid Build Coastguard Worker def test_no_change_info_no_optimization(self): 123*9e94795aSAndroid Build Coastguard Worker del os.environ['CHANGE_INFO'] 124*9e94795aSAndroid Build Coastguard Worker 125*9e94795aSAndroid Build Coastguard Worker optimizer = self._create_general_tests_optimizer() 126*9e94795aSAndroid Build Coastguard Worker 127*9e94795aSAndroid Build Coastguard Worker build_targets = optimizer.get_build_targets() 128*9e94795aSAndroid Build Coastguard Worker 129*9e94795aSAndroid Build Coastguard Worker self.assertSetEqual(build_targets, {'general-tests'}) 130*9e94795aSAndroid Build Coastguard Worker 131*9e94795aSAndroid Build Coastguard Worker def test_mapping_groups_unused_module_not_built(self): 132*9e94795aSAndroid Build Coastguard Worker test_context = self._create_test_context() 133*9e94795aSAndroid Build Coastguard Worker test_context['testInfos'][0]['extraOptions'] = [ 134*9e94795aSAndroid Build Coastguard Worker { 135*9e94795aSAndroid Build Coastguard Worker 'key': 'additional-files-filter', 136*9e94795aSAndroid Build Coastguard Worker 'values': ['general-tests.zip'], 137*9e94795aSAndroid Build Coastguard Worker }, 138*9e94795aSAndroid Build Coastguard Worker { 139*9e94795aSAndroid Build Coastguard Worker 'key': 'test-mapping-test-group', 140*9e94795aSAndroid Build Coastguard Worker 'values': ['unused-test-mapping-group'], 141*9e94795aSAndroid Build Coastguard Worker }, 142*9e94795aSAndroid Build Coastguard Worker ] 143*9e94795aSAndroid Build Coastguard Worker optimizer = self._create_general_tests_optimizer( 144*9e94795aSAndroid Build Coastguard Worker build_context=self._create_build_context(test_context=test_context) 145*9e94795aSAndroid Build Coastguard Worker ) 146*9e94795aSAndroid Build Coastguard Worker 147*9e94795aSAndroid Build Coastguard Worker build_targets = optimizer.get_build_targets() 148*9e94795aSAndroid Build Coastguard Worker 149*9e94795aSAndroid Build Coastguard Worker expected_build_targets = set( 150*9e94795aSAndroid Build Coastguard Worker optimized_targets.GeneralTestsOptimizer._REQUIRED_MODULES 151*9e94795aSAndroid Build Coastguard Worker ) 152*9e94795aSAndroid Build Coastguard Worker self.assertSetEqual(build_targets, expected_build_targets) 153*9e94795aSAndroid Build Coastguard Worker 154*9e94795aSAndroid Build Coastguard Worker def test_general_tests_used_by_non_test_mapping_test_no_optimization(self): 155*9e94795aSAndroid Build Coastguard Worker test_context = self._create_test_context() 156*9e94795aSAndroid Build Coastguard Worker test_context['testInfos'][0]['extraOptions'] = [{ 157*9e94795aSAndroid Build Coastguard Worker 'key': 'additional-files-filter', 158*9e94795aSAndroid Build Coastguard Worker 'values': ['general-tests.zip'], 159*9e94795aSAndroid Build Coastguard Worker }] 160*9e94795aSAndroid Build Coastguard Worker optimizer = self._create_general_tests_optimizer( 161*9e94795aSAndroid Build Coastguard Worker build_context=self._create_build_context(test_context=test_context) 162*9e94795aSAndroid Build Coastguard Worker ) 163*9e94795aSAndroid Build Coastguard Worker 164*9e94795aSAndroid Build Coastguard Worker build_targets = optimizer.get_build_targets() 165*9e94795aSAndroid Build Coastguard Worker 166*9e94795aSAndroid Build Coastguard Worker self.assertSetEqual(build_targets, {'general-tests'}) 167*9e94795aSAndroid Build Coastguard Worker 168*9e94795aSAndroid Build Coastguard Worker def test_malformed_change_info_raises(self): 169*9e94795aSAndroid Build Coastguard Worker with open(self.change_info_file, 'w') as f: 170*9e94795aSAndroid Build Coastguard Worker f.write('not change info') 171*9e94795aSAndroid Build Coastguard Worker 172*9e94795aSAndroid Build Coastguard Worker optimizer = self._create_general_tests_optimizer() 173*9e94795aSAndroid Build Coastguard Worker 174*9e94795aSAndroid Build Coastguard Worker with self.assertRaises(json.decoder.JSONDecodeError): 175*9e94795aSAndroid Build Coastguard Worker build_targets = optimizer.get_build_targets() 176*9e94795aSAndroid Build Coastguard Worker 177*9e94795aSAndroid Build Coastguard Worker def test_malformed_test_mapping_raises(self): 178*9e94795aSAndroid Build Coastguard Worker with open('/project/path/file/path/TEST_MAPPING', 'w') as f: 179*9e94795aSAndroid Build Coastguard Worker f.write('not test mapping') 180*9e94795aSAndroid Build Coastguard Worker 181*9e94795aSAndroid Build Coastguard Worker optimizer = self._create_general_tests_optimizer() 182*9e94795aSAndroid Build Coastguard Worker 183*9e94795aSAndroid Build Coastguard Worker with self.assertRaises(json.decoder.JSONDecodeError): 184*9e94795aSAndroid Build Coastguard Worker build_targets = optimizer.get_build_targets() 185*9e94795aSAndroid Build Coastguard Worker 186*9e94795aSAndroid Build Coastguard Worker @mock.patch('subprocess.run') 187*9e94795aSAndroid Build Coastguard Worker def test_packaging_outputs_success(self, subprocess_run): 188*9e94795aSAndroid Build Coastguard Worker subprocess_run.return_value = self._get_soong_vars_output() 189*9e94795aSAndroid Build Coastguard Worker optimizer = self._create_general_tests_optimizer() 190*9e94795aSAndroid Build Coastguard Worker self._set_up_build_outputs(['test_mapping_module']) 191*9e94795aSAndroid Build Coastguard Worker 192*9e94795aSAndroid Build Coastguard Worker targets = optimizer.get_build_targets() 193*9e94795aSAndroid Build Coastguard Worker package_commands = optimizer.get_package_outputs_commands() 194*9e94795aSAndroid Build Coastguard Worker 195*9e94795aSAndroid Build Coastguard Worker self._verify_soong_zip_commands(package_commands, ['test_mapping_module']) 196*9e94795aSAndroid Build Coastguard Worker 197*9e94795aSAndroid Build Coastguard Worker @mock.patch('subprocess.run') 198*9e94795aSAndroid Build Coastguard Worker def test_get_soong_dumpvars_fails_raises(self, subprocess_run): 199*9e94795aSAndroid Build Coastguard Worker subprocess_run.return_value = self._get_soong_vars_output(return_code=-1) 200*9e94795aSAndroid Build Coastguard Worker optimizer = self._create_general_tests_optimizer() 201*9e94795aSAndroid Build Coastguard Worker self._set_up_build_outputs(['test_mapping_module']) 202*9e94795aSAndroid Build Coastguard Worker 203*9e94795aSAndroid Build Coastguard Worker targets = optimizer.get_build_targets() 204*9e94795aSAndroid Build Coastguard Worker 205*9e94795aSAndroid Build Coastguard Worker with self.assertRaisesRegex(RuntimeError, 'Soong dumpvars failed!'): 206*9e94795aSAndroid Build Coastguard Worker package_commands = optimizer.get_package_outputs_commands() 207*9e94795aSAndroid Build Coastguard Worker 208*9e94795aSAndroid Build Coastguard Worker @mock.patch('subprocess.run') 209*9e94795aSAndroid Build Coastguard Worker def test_get_soong_dumpvars_bad_output_raises(self, subprocess_run): 210*9e94795aSAndroid Build Coastguard Worker subprocess_run.return_value = self._get_soong_vars_output( 211*9e94795aSAndroid Build Coastguard Worker stdout='This output is bad' 212*9e94795aSAndroid Build Coastguard Worker ) 213*9e94795aSAndroid Build Coastguard Worker optimizer = self._create_general_tests_optimizer() 214*9e94795aSAndroid Build Coastguard Worker self._set_up_build_outputs(['test_mapping_module']) 215*9e94795aSAndroid Build Coastguard Worker 216*9e94795aSAndroid Build Coastguard Worker targets = optimizer.get_build_targets() 217*9e94795aSAndroid Build Coastguard Worker 218*9e94795aSAndroid Build Coastguard Worker with self.assertRaisesRegex( 219*9e94795aSAndroid Build Coastguard Worker RuntimeError, 'Error parsing soong dumpvars output' 220*9e94795aSAndroid Build Coastguard Worker ): 221*9e94795aSAndroid Build Coastguard Worker package_commands = optimizer.get_package_outputs_commands() 222*9e94795aSAndroid Build Coastguard Worker 223*9e94795aSAndroid Build Coastguard Worker def _create_general_tests_optimizer(self, build_context: BuildContext = None): 224*9e94795aSAndroid Build Coastguard Worker if not build_context: 225*9e94795aSAndroid Build Coastguard Worker build_context = self._create_build_context() 226*9e94795aSAndroid Build Coastguard Worker return optimized_targets.GeneralTestsOptimizer( 227*9e94795aSAndroid Build Coastguard Worker 'general-tests', build_context, None 228*9e94795aSAndroid Build Coastguard Worker ) 229*9e94795aSAndroid Build Coastguard Worker 230*9e94795aSAndroid Build Coastguard Worker def _create_build_context( 231*9e94795aSAndroid Build Coastguard Worker self, 232*9e94795aSAndroid Build Coastguard Worker general_tests_optimized: bool = True, 233*9e94795aSAndroid Build Coastguard Worker test_context: dict[str, any] = None, 234*9e94795aSAndroid Build Coastguard Worker ) -> BuildContext: 235*9e94795aSAndroid Build Coastguard Worker if not test_context: 236*9e94795aSAndroid Build Coastguard Worker test_context = self._create_test_context() 237*9e94795aSAndroid Build Coastguard Worker build_context_dict = {} 238*9e94795aSAndroid Build Coastguard Worker build_context_dict['enabledBuildFeatures'] = [{'name': 'optimized_build'}] 239*9e94795aSAndroid Build Coastguard Worker if general_tests_optimized: 240*9e94795aSAndroid Build Coastguard Worker build_context_dict['enabledBuildFeatures'].append( 241*9e94795aSAndroid Build Coastguard Worker {'name': 'general_tests_optimized'} 242*9e94795aSAndroid Build Coastguard Worker ) 243*9e94795aSAndroid Build Coastguard Worker build_context_dict['testContext'] = test_context 244*9e94795aSAndroid Build Coastguard Worker return BuildContext(build_context_dict) 245*9e94795aSAndroid Build Coastguard Worker 246*9e94795aSAndroid Build Coastguard Worker def _create_test_context(self): 247*9e94795aSAndroid Build Coastguard Worker return { 248*9e94795aSAndroid Build Coastguard Worker 'testInfos': [ 249*9e94795aSAndroid Build Coastguard Worker { 250*9e94795aSAndroid Build Coastguard Worker 'name': 'atp_test', 251*9e94795aSAndroid Build Coastguard Worker 'target': 'test_target', 252*9e94795aSAndroid Build Coastguard Worker 'branch': 'branch', 253*9e94795aSAndroid Build Coastguard Worker 'extraOptions': [ 254*9e94795aSAndroid Build Coastguard Worker { 255*9e94795aSAndroid Build Coastguard Worker 'key': 'additional-files-filter', 256*9e94795aSAndroid Build Coastguard Worker 'values': ['general-tests.zip'], 257*9e94795aSAndroid Build Coastguard Worker }, 258*9e94795aSAndroid Build Coastguard Worker { 259*9e94795aSAndroid Build Coastguard Worker 'key': 'test-mapping-test-group', 260*9e94795aSAndroid Build Coastguard Worker 'values': ['test-mapping-group'], 261*9e94795aSAndroid Build Coastguard Worker }, 262*9e94795aSAndroid Build Coastguard Worker ], 263*9e94795aSAndroid Build Coastguard Worker 'command': '/tf/command', 264*9e94795aSAndroid Build Coastguard Worker 'extraBuildTargets': [ 265*9e94795aSAndroid Build Coastguard Worker 'extra_build_target', 266*9e94795aSAndroid Build Coastguard Worker ], 267*9e94795aSAndroid Build Coastguard Worker }, 268*9e94795aSAndroid Build Coastguard Worker ], 269*9e94795aSAndroid Build Coastguard Worker } 270*9e94795aSAndroid Build Coastguard Worker 271*9e94795aSAndroid Build Coastguard Worker def _get_soong_vars_output( 272*9e94795aSAndroid Build Coastguard Worker self, return_code: int = 0, stdout: str = '' 273*9e94795aSAndroid Build Coastguard Worker ) -> subprocess.CompletedProcess: 274*9e94795aSAndroid Build Coastguard Worker return_value = subprocess.CompletedProcess(args=[], returncode=return_code) 275*9e94795aSAndroid Build Coastguard Worker if not stdout: 276*9e94795aSAndroid Build Coastguard Worker stdout = textwrap.dedent(f"""\ 277*9e94795aSAndroid Build Coastguard Worker HOST_OUT_TESTCASES='{self._host_out_testcases}' 278*9e94795aSAndroid Build Coastguard Worker TARGET_OUT_TESTCASES='{self._target_out_testcases}' 279*9e94795aSAndroid Build Coastguard Worker PRODUCT_OUT='{self._product_out}' 280*9e94795aSAndroid Build Coastguard Worker SOONG_HOST_OUT='{self._soong_host_out}' 281*9e94795aSAndroid Build Coastguard Worker HOST_OUT='{self._host_out}'""") 282*9e94795aSAndroid Build Coastguard Worker 283*9e94795aSAndroid Build Coastguard Worker return_value.stdout = stdout 284*9e94795aSAndroid Build Coastguard Worker return return_value 285*9e94795aSAndroid Build Coastguard Worker 286*9e94795aSAndroid Build Coastguard Worker def _set_up_build_outputs(self, targets: list[str]): 287*9e94795aSAndroid Build Coastguard Worker for target in targets: 288*9e94795aSAndroid Build Coastguard Worker host_dir = self._host_out_testcases / target 289*9e94795aSAndroid Build Coastguard Worker host_dir.mkdir() 290*9e94795aSAndroid Build Coastguard Worker (host_dir / f'{target}.config').touch() 291*9e94795aSAndroid Build Coastguard Worker (host_dir / f'test_file').touch() 292*9e94795aSAndroid Build Coastguard Worker 293*9e94795aSAndroid Build Coastguard Worker target_dir = self._target_out_testcases / target 294*9e94795aSAndroid Build Coastguard Worker target_dir.mkdir() 295*9e94795aSAndroid Build Coastguard Worker (target_dir / f'{target}.config').touch() 296*9e94795aSAndroid Build Coastguard Worker (target_dir / f'test_file').touch() 297*9e94795aSAndroid Build Coastguard Worker 298*9e94795aSAndroid Build Coastguard Worker def _verify_soong_zip_commands(self, commands: list[str], targets: list[str]): 299*9e94795aSAndroid Build Coastguard Worker """Verify the structure of the zip commands. 300*9e94795aSAndroid Build Coastguard Worker 301*9e94795aSAndroid Build Coastguard Worker Zip commands have to start with the soong_zip binary path, then are followed 302*9e94795aSAndroid Build Coastguard Worker by a couple of options and the name of the file being zipped. Depending on 303*9e94795aSAndroid Build Coastguard Worker which zip we are creating look for a few essential items being added in 304*9e94795aSAndroid Build Coastguard Worker those zips. 305*9e94795aSAndroid Build Coastguard Worker 306*9e94795aSAndroid Build Coastguard Worker Args: 307*9e94795aSAndroid Build Coastguard Worker commands: list of command lists 308*9e94795aSAndroid Build Coastguard Worker targets: list of targets expected to be in general-tests.zip 309*9e94795aSAndroid Build Coastguard Worker """ 310*9e94795aSAndroid Build Coastguard Worker for command in commands: 311*9e94795aSAndroid Build Coastguard Worker self.assertEqual( 312*9e94795aSAndroid Build Coastguard Worker '/tmp/top/prebuilts/build-tools/linux-x86/bin/soong_zip', 313*9e94795aSAndroid Build Coastguard Worker command[0], 314*9e94795aSAndroid Build Coastguard Worker ) 315*9e94795aSAndroid Build Coastguard Worker self.assertEqual('-d', command[1]) 316*9e94795aSAndroid Build Coastguard Worker self.assertEqual('-o', command[2]) 317*9e94795aSAndroid Build Coastguard Worker match (command[3]): 318*9e94795aSAndroid Build Coastguard Worker case '/tmp/top/out/dist/general-tests_configs.zip': 319*9e94795aSAndroid Build Coastguard Worker self.assertIn(f'{self._host_out}/host_general-tests_list', command) 320*9e94795aSAndroid Build Coastguard Worker self.assertIn( 321*9e94795aSAndroid Build Coastguard Worker f'{self._product_out}/target_general-tests_list', command 322*9e94795aSAndroid Build Coastguard Worker ) 323*9e94795aSAndroid Build Coastguard Worker return 324*9e94795aSAndroid Build Coastguard Worker case '/tmp/top/out/dist/general-tests_list.zip': 325*9e94795aSAndroid Build Coastguard Worker self.assertIn('-f', command) 326*9e94795aSAndroid Build Coastguard Worker self.assertIn(f'{self._host_out}/general-tests_list', command) 327*9e94795aSAndroid Build Coastguard Worker return 328*9e94795aSAndroid Build Coastguard Worker case '/tmp/top/out/dist/general-tests.zip': 329*9e94795aSAndroid Build Coastguard Worker for target in targets: 330*9e94795aSAndroid Build Coastguard Worker self.assertIn(f'{self._host_out_testcases}/{target}', command) 331*9e94795aSAndroid Build Coastguard Worker self.assertIn(f'{self._target_out_testcases}/{target}', command) 332*9e94795aSAndroid Build Coastguard Worker self.assertIn( 333*9e94795aSAndroid Build Coastguard Worker f'{self._soong_host_out}/framework/cts-tradefed.jar', command 334*9e94795aSAndroid Build Coastguard Worker ) 335*9e94795aSAndroid Build Coastguard Worker self.assertIn( 336*9e94795aSAndroid Build Coastguard Worker f'{self._soong_host_out}/framework/compatibility-host-util.jar', 337*9e94795aSAndroid Build Coastguard Worker command, 338*9e94795aSAndroid Build Coastguard Worker ) 339*9e94795aSAndroid Build Coastguard Worker self.assertIn( 340*9e94795aSAndroid Build Coastguard Worker f'{self._soong_host_out}/framework/vts-tradefed.jar', command 341*9e94795aSAndroid Build Coastguard Worker ) 342*9e94795aSAndroid Build Coastguard Worker return 343*9e94795aSAndroid Build Coastguard Worker case _: 344*9e94795aSAndroid Build Coastguard Worker self.fail(f'malformed command: {command}') 345*9e94795aSAndroid Build Coastguard Worker 346*9e94795aSAndroid Build Coastguard Worker 347*9e94795aSAndroid Build Coastguard Workerif __name__ == '__main__': 348*9e94795aSAndroid Build Coastguard Worker # Setup logging to be silent so unit tests can pass through TF. 349*9e94795aSAndroid Build Coastguard Worker logging.disable(logging.ERROR) 350*9e94795aSAndroid Build Coastguard Worker unittest.main() 351