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