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"""Container class for build context with utility functions.""" 16*9e94795aSAndroid Build Coastguard Worker 17*9e94795aSAndroid Build Coastguard Workerimport re 18*9e94795aSAndroid Build Coastguard Worker 19*9e94795aSAndroid Build Coastguard Worker 20*9e94795aSAndroid Build Coastguard Workerclass BuildContext: 21*9e94795aSAndroid Build Coastguard Worker 22*9e94795aSAndroid Build Coastguard Worker def __init__(self, build_context_dict: dict[str, any]): 23*9e94795aSAndroid Build Coastguard Worker self.enabled_build_features = set() 24*9e94795aSAndroid Build Coastguard Worker for opt in build_context_dict.get('enabledBuildFeatures', []): 25*9e94795aSAndroid Build Coastguard Worker self.enabled_build_features.add(opt.get('name')) 26*9e94795aSAndroid Build Coastguard Worker self.test_infos = set() 27*9e94795aSAndroid Build Coastguard Worker for test_info_dict in build_context_dict.get('testContext', dict()).get( 28*9e94795aSAndroid Build Coastguard Worker 'testInfos', [] 29*9e94795aSAndroid Build Coastguard Worker ): 30*9e94795aSAndroid Build Coastguard Worker self.test_infos.add(self.TestInfo(test_info_dict)) 31*9e94795aSAndroid Build Coastguard Worker 32*9e94795aSAndroid Build Coastguard Worker def build_target_used(self, target: str) -> bool: 33*9e94795aSAndroid Build Coastguard Worker return any(test.build_target_used(target) for test in self.test_infos) 34*9e94795aSAndroid Build Coastguard Worker 35*9e94795aSAndroid Build Coastguard Worker class TestInfo: 36*9e94795aSAndroid Build Coastguard Worker 37*9e94795aSAndroid Build Coastguard Worker _DOWNLOAD_OPTS = { 38*9e94795aSAndroid Build Coastguard Worker 'test-config-only-zip', 39*9e94795aSAndroid Build Coastguard Worker 'test-zip-file-filter', 40*9e94795aSAndroid Build Coastguard Worker 'extra-host-shared-lib-zip', 41*9e94795aSAndroid Build Coastguard Worker 'sandbox-tests-zips', 42*9e94795aSAndroid Build Coastguard Worker 'additional-files-filter', 43*9e94795aSAndroid Build Coastguard Worker 'cts-package-name', 44*9e94795aSAndroid Build Coastguard Worker } 45*9e94795aSAndroid Build Coastguard Worker 46*9e94795aSAndroid Build Coastguard Worker def __init__(self, test_info_dict: dict[str, any]): 47*9e94795aSAndroid Build Coastguard Worker self.is_test_mapping = False 48*9e94795aSAndroid Build Coastguard Worker self.test_mapping_test_groups = set() 49*9e94795aSAndroid Build Coastguard Worker self.file_download_options = set() 50*9e94795aSAndroid Build Coastguard Worker self.name = test_info_dict.get('name') 51*9e94795aSAndroid Build Coastguard Worker self.command = test_info_dict.get('command') 52*9e94795aSAndroid Build Coastguard Worker self.extra_options = test_info_dict.get('extraOptions') 53*9e94795aSAndroid Build Coastguard Worker for opt in test_info_dict.get('extraOptions', []): 54*9e94795aSAndroid Build Coastguard Worker key = opt.get('key') 55*9e94795aSAndroid Build Coastguard Worker if key == 'test-mapping-test-group': 56*9e94795aSAndroid Build Coastguard Worker self.is_test_mapping = True 57*9e94795aSAndroid Build Coastguard Worker self.test_mapping_test_groups.update(opt.get('values', set())) 58*9e94795aSAndroid Build Coastguard Worker 59*9e94795aSAndroid Build Coastguard Worker if key in self._DOWNLOAD_OPTS: 60*9e94795aSAndroid Build Coastguard Worker self.file_download_options.update(opt.get('values', set())) 61*9e94795aSAndroid Build Coastguard Worker 62*9e94795aSAndroid Build Coastguard Worker def build_target_used(self, target: str) -> bool: 63*9e94795aSAndroid Build Coastguard Worker # For all of a targets' outputs, check if any of the regexes used by tests 64*9e94795aSAndroid Build Coastguard Worker # to download artifacts would match it. If any of them do then this target 65*9e94795aSAndroid Build Coastguard Worker # is necessary. 66*9e94795aSAndroid Build Coastguard Worker regex = r'\b(%s)\b' % re.escape(target) 67*9e94795aSAndroid Build Coastguard Worker return any(re.search(regex, opt) for opt in self.file_download_options) 68