1*6777b538SAndroid Build Coastguard Worker# Copyright 2020 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker"""Methods related to querying builder information from Buildbucket.""" 5*6777b538SAndroid Build Coastguard Worker 6*6777b538SAndroid Build Coastguard Workerfrom __future__ import print_function 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Workerimport concurrent.futures 9*6777b538SAndroid Build Coastguard Workerimport json 10*6777b538SAndroid Build Coastguard Workerimport logging 11*6777b538SAndroid Build Coastguard Workerimport os 12*6777b538SAndroid Build Coastguard Workerimport subprocess 13*6777b538SAndroid Build Coastguard Workerfrom typing import Any, Dict, Iterable, List, Optional, Set, Tuple 14*6777b538SAndroid Build Coastguard Worker 15*6777b538SAndroid Build Coastguard Workerimport six 16*6777b538SAndroid Build Coastguard Worker 17*6777b538SAndroid Build Coastguard Workerfrom unexpected_passes_common import constants 18*6777b538SAndroid Build Coastguard Workerfrom unexpected_passes_common import data_types 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard WorkerTESTING_BUILDBOT_DIR = os.path.realpath( 21*6777b538SAndroid Build Coastguard Worker os.path.join(os.path.dirname(__file__), '..', 'buildbot')) 22*6777b538SAndroid Build Coastguard WorkerINTERNAL_TESTING_BUILDBOT_DIR = os.path.realpath( 23*6777b538SAndroid Build Coastguard Worker os.path.join(constants.SRC_INTERNAL_DIR, 'testing', 'buildbot')) 24*6777b538SAndroid Build Coastguard Worker 25*6777b538SAndroid Build Coastguard Worker# Public JSON files for internal builders, which should be treated as internal. 26*6777b538SAndroid Build Coastguard WorkerPUBLIC_INTERNAL_JSON_FILES = { 27*6777b538SAndroid Build Coastguard Worker 'chrome.json', 28*6777b538SAndroid Build Coastguard Worker 'chrome.gpu.fyi.json', 29*6777b538SAndroid Build Coastguard Worker 'chromeos.preuprev.json', 30*6777b538SAndroid Build Coastguard Worker 'internal.chrome.fyi.json', 31*6777b538SAndroid Build Coastguard Worker 'internal.chromeos.fyi.json', 32*6777b538SAndroid Build Coastguard Worker} 33*6777b538SAndroid Build Coastguard Worker 34*6777b538SAndroid Build Coastguard WorkerAUTOGENERATED_JSON_KEY = 'AAAAA1 AUTOGENERATED FILE DO NOT EDIT' 35*6777b538SAndroid Build Coastguard Worker 36*6777b538SAndroid Build Coastguard WorkerFakeBuildersDict = Dict[data_types.BuilderEntry, Set[data_types.BuilderEntry]] 37*6777b538SAndroid Build Coastguard Worker 38*6777b538SAndroid Build Coastguard Worker_registered_instance = None 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard Worker 41*6777b538SAndroid Build Coastguard Workerdef GetInstance() -> 'Builders': 42*6777b538SAndroid Build Coastguard Worker return _registered_instance 43*6777b538SAndroid Build Coastguard Worker 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Workerdef RegisterInstance(instance: 'Builders') -> None: 46*6777b538SAndroid Build Coastguard Worker global _registered_instance 47*6777b538SAndroid Build Coastguard Worker assert _registered_instance is None 48*6777b538SAndroid Build Coastguard Worker assert isinstance(instance, Builders) 49*6777b538SAndroid Build Coastguard Worker _registered_instance = instance 50*6777b538SAndroid Build Coastguard Worker 51*6777b538SAndroid Build Coastguard Worker 52*6777b538SAndroid Build Coastguard Workerdef ClearInstance() -> None: 53*6777b538SAndroid Build Coastguard Worker global _registered_instance 54*6777b538SAndroid Build Coastguard Worker _registered_instance = None 55*6777b538SAndroid Build Coastguard Worker 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard Workerclass Builders(): 58*6777b538SAndroid Build Coastguard Worker def __init__(self, suite: Optional[str], include_internal_builders: bool): 59*6777b538SAndroid Build Coastguard Worker """ 60*6777b538SAndroid Build Coastguard Worker Args: 61*6777b538SAndroid Build Coastguard Worker suite: A string containing particular suite of interest if applicable, 62*6777b538SAndroid Build Coastguard Worker such as for Telemetry-based tests. Can be None if not applicable. 63*6777b538SAndroid Build Coastguard Worker include_internal_builders: A boolean indicating whether data from 64*6777b538SAndroid Build Coastguard Worker internal builders should be used in addition to external ones. 65*6777b538SAndroid Build Coastguard Worker """ 66*6777b538SAndroid Build Coastguard Worker self._authenticated = False 67*6777b538SAndroid Build Coastguard Worker self._suite = suite 68*6777b538SAndroid Build Coastguard Worker self._include_internal_builders = include_internal_builders 69*6777b538SAndroid Build Coastguard Worker 70*6777b538SAndroid Build Coastguard Worker def _ProcessJsonFiles(self, files: List[str], are_internal_files: bool, 71*6777b538SAndroid Build Coastguard Worker builder_type: str) -> Set[data_types.BuilderEntry]: 72*6777b538SAndroid Build Coastguard Worker builders = set() 73*6777b538SAndroid Build Coastguard Worker for filepath in files: 74*6777b538SAndroid Build Coastguard Worker if not filepath.endswith('.json'): 75*6777b538SAndroid Build Coastguard Worker continue 76*6777b538SAndroid Build Coastguard Worker if builder_type == constants.BuilderTypes.CI: 77*6777b538SAndroid Build Coastguard Worker if 'tryserver' in filepath: 78*6777b538SAndroid Build Coastguard Worker continue 79*6777b538SAndroid Build Coastguard Worker elif builder_type == constants.BuilderTypes.TRY: 80*6777b538SAndroid Build Coastguard Worker if 'tryserver' not in filepath: 81*6777b538SAndroid Build Coastguard Worker continue 82*6777b538SAndroid Build Coastguard Worker with open(filepath, encoding='utf-8') as f: 83*6777b538SAndroid Build Coastguard Worker buildbot_json = json.load(f) 84*6777b538SAndroid Build Coastguard Worker # Skip any JSON files that don't contain builder information. 85*6777b538SAndroid Build Coastguard Worker if AUTOGENERATED_JSON_KEY not in buildbot_json: 86*6777b538SAndroid Build Coastguard Worker continue 87*6777b538SAndroid Build Coastguard Worker 88*6777b538SAndroid Build Coastguard Worker for builder, test_map in buildbot_json.items(): 89*6777b538SAndroid Build Coastguard Worker # Remove the auto-generated comments. 90*6777b538SAndroid Build Coastguard Worker if 'AAAA' in builder: 91*6777b538SAndroid Build Coastguard Worker continue 92*6777b538SAndroid Build Coastguard Worker # Filter out any builders that don't run the suite in question. 93*6777b538SAndroid Build Coastguard Worker if not self._BuilderRunsTestOfInterest(test_map): 94*6777b538SAndroid Build Coastguard Worker continue 95*6777b538SAndroid Build Coastguard Worker builders.add( 96*6777b538SAndroid Build Coastguard Worker data_types.BuilderEntry(builder, builder_type, are_internal_files)) 97*6777b538SAndroid Build Coastguard Worker return builders 98*6777b538SAndroid Build Coastguard Worker 99*6777b538SAndroid Build Coastguard Worker def GetCiBuilders(self) -> Set[data_types.BuilderEntry]: 100*6777b538SAndroid Build Coastguard Worker """Gets the set of CI builders to query. 101*6777b538SAndroid Build Coastguard Worker 102*6777b538SAndroid Build Coastguard Worker Returns: 103*6777b538SAndroid Build Coastguard Worker A set of data_types.BuilderEntry, each element corresponding to either a 104*6777b538SAndroid Build Coastguard Worker public or internal CI builder to query results from. 105*6777b538SAndroid Build Coastguard Worker """ 106*6777b538SAndroid Build Coastguard Worker ci_builders = set() 107*6777b538SAndroid Build Coastguard Worker 108*6777b538SAndroid Build Coastguard Worker logging.info('Getting CI builders') 109*6777b538SAndroid Build Coastguard Worker ci_builders = self._ProcessJsonFiles(_GetPublicJsonFiles(), False, 110*6777b538SAndroid Build Coastguard Worker constants.BuilderTypes.CI) 111*6777b538SAndroid Build Coastguard Worker if self._include_internal_builders: 112*6777b538SAndroid Build Coastguard Worker ci_builders |= self._ProcessJsonFiles(_GetInternalJsonFiles(), True, 113*6777b538SAndroid Build Coastguard Worker constants.BuilderTypes.CI) 114*6777b538SAndroid Build Coastguard Worker 115*6777b538SAndroid Build Coastguard Worker logging.debug('Got %d CI builders after trimming: %s', len(ci_builders), 116*6777b538SAndroid Build Coastguard Worker ', '.join([b.name for b in ci_builders])) 117*6777b538SAndroid Build Coastguard Worker return ci_builders 118*6777b538SAndroid Build Coastguard Worker 119*6777b538SAndroid Build Coastguard Worker def _BuilderRunsTestOfInterest(self, test_map: Dict[str, Any]) -> bool: 120*6777b538SAndroid Build Coastguard Worker """Determines if a builder runs a test of interest. 121*6777b538SAndroid Build Coastguard Worker 122*6777b538SAndroid Build Coastguard Worker Args: 123*6777b538SAndroid Build Coastguard Worker test_map: A dict, corresponding to a builder's test spec from a 124*6777b538SAndroid Build Coastguard Worker //testing/buildbot JSON file. 125*6777b538SAndroid Build Coastguard Worker suite: A string containing particular suite of interest if applicable, 126*6777b538SAndroid Build Coastguard Worker such as for Telemetry-based tests. Can be None if not applicable. 127*6777b538SAndroid Build Coastguard Worker 128*6777b538SAndroid Build Coastguard Worker Returns: 129*6777b538SAndroid Build Coastguard Worker True if |test_map| contains a test of interest, else False. 130*6777b538SAndroid Build Coastguard Worker """ 131*6777b538SAndroid Build Coastguard Worker raise NotImplementedError() 132*6777b538SAndroid Build Coastguard Worker 133*6777b538SAndroid Build Coastguard Worker def GetTryBuilders(self, ci_builders: Iterable[data_types.BuilderEntry] 134*6777b538SAndroid Build Coastguard Worker ) -> Set[data_types.BuilderEntry]: 135*6777b538SAndroid Build Coastguard Worker """Gets the set of try builders to query. 136*6777b538SAndroid Build Coastguard Worker 137*6777b538SAndroid Build Coastguard Worker A try builder is of interest if it mirrors a builder in |ci_builders| or is 138*6777b538SAndroid Build Coastguard Worker a dedicated try builder. 139*6777b538SAndroid Build Coastguard Worker 140*6777b538SAndroid Build Coastguard Worker Args: 141*6777b538SAndroid Build Coastguard Worker ci_builders: An iterable of data_types.BuilderEntry, each element being a 142*6777b538SAndroid Build Coastguard Worker public or internal CI builder that results will be/were queried from. 143*6777b538SAndroid Build Coastguard Worker 144*6777b538SAndroid Build Coastguard Worker Returns: 145*6777b538SAndroid Build Coastguard Worker A set of data_types.BuilderEntry, each element being the name of a 146*6777b538SAndroid Build Coastguard Worker Chromium try builder to query results from. 147*6777b538SAndroid Build Coastguard Worker """ 148*6777b538SAndroid Build Coastguard Worker logging.info('Getting try builders') 149*6777b538SAndroid Build Coastguard Worker dedicated_try_builders = self._ProcessJsonFiles([ 150*6777b538SAndroid Build Coastguard Worker os.path.join(TESTING_BUILDBOT_DIR, f) 151*6777b538SAndroid Build Coastguard Worker for f in os.listdir(TESTING_BUILDBOT_DIR) 152*6777b538SAndroid Build Coastguard Worker ], False, constants.BuilderTypes.TRY) 153*6777b538SAndroid Build Coastguard Worker if self._include_internal_builders: 154*6777b538SAndroid Build Coastguard Worker dedicated_try_builders |= self._ProcessJsonFiles([ 155*6777b538SAndroid Build Coastguard Worker os.path.join(INTERNAL_TESTING_BUILDBOT_DIR, f) 156*6777b538SAndroid Build Coastguard Worker for f in os.listdir(INTERNAL_TESTING_BUILDBOT_DIR) 157*6777b538SAndroid Build Coastguard Worker ], True, constants.BuilderTypes.TRY) 158*6777b538SAndroid Build Coastguard Worker mirrored_builders = set() 159*6777b538SAndroid Build Coastguard Worker no_output_builders = set() 160*6777b538SAndroid Build Coastguard Worker 161*6777b538SAndroid Build Coastguard Worker with concurrent.futures.ThreadPoolExecutor( 162*6777b538SAndroid Build Coastguard Worker max_workers=os.cpu_count()) as pool: 163*6777b538SAndroid Build Coastguard Worker results_iter = pool.map(self._GetMirroredBuildersForCiBuilder, 164*6777b538SAndroid Build Coastguard Worker ci_builders) 165*6777b538SAndroid Build Coastguard Worker for (builders, found_mirror) in results_iter: 166*6777b538SAndroid Build Coastguard Worker if found_mirror: 167*6777b538SAndroid Build Coastguard Worker mirrored_builders |= builders 168*6777b538SAndroid Build Coastguard Worker else: 169*6777b538SAndroid Build Coastguard Worker no_output_builders |= builders 170*6777b538SAndroid Build Coastguard Worker 171*6777b538SAndroid Build Coastguard Worker if no_output_builders: 172*6777b538SAndroid Build Coastguard Worker raise RuntimeError( 173*6777b538SAndroid Build Coastguard Worker 'Did not get Buildbucket output for the following builders. They may ' 174*6777b538SAndroid Build Coastguard Worker 'need to be added to the GetFakeCiBuilders or ' 175*6777b538SAndroid Build Coastguard Worker 'GetNonChromiumBuilders .\n%s' % 176*6777b538SAndroid Build Coastguard Worker '\n'.join([b.name for b in no_output_builders])) 177*6777b538SAndroid Build Coastguard Worker logging.debug('Got %d try builders: %s', len(mirrored_builders), 178*6777b538SAndroid Build Coastguard Worker mirrored_builders) 179*6777b538SAndroid Build Coastguard Worker return dedicated_try_builders | mirrored_builders 180*6777b538SAndroid Build Coastguard Worker 181*6777b538SAndroid Build Coastguard Worker def _GetMirroredBuildersForCiBuilder( 182*6777b538SAndroid Build Coastguard Worker self, ci_builder: data_types.BuilderEntry 183*6777b538SAndroid Build Coastguard Worker ) -> Tuple[Set[data_types.BuilderEntry], bool]: 184*6777b538SAndroid Build Coastguard Worker """Gets the set of try builders that mirror a CI builder. 185*6777b538SAndroid Build Coastguard Worker 186*6777b538SAndroid Build Coastguard Worker Args: 187*6777b538SAndroid Build Coastguard Worker ci_builder: A data_types.BuilderEntry for a public or internal CI builder. 188*6777b538SAndroid Build Coastguard Worker 189*6777b538SAndroid Build Coastguard Worker Returns: 190*6777b538SAndroid Build Coastguard Worker A tuple (builders, found_mirror). |builders| is a set of 191*6777b538SAndroid Build Coastguard Worker data_types.BuilderEntry, either the set of try builders that mirror 192*6777b538SAndroid Build Coastguard Worker |ci_builder| or |ci_builder|, depending on the value of |found_mirror|. 193*6777b538SAndroid Build Coastguard Worker |found_mirror| is True if mirrors were actually found, in which case 194*6777b538SAndroid Build Coastguard Worker |builders| contains the try builders. Otherwise, |found_mirror| is False 195*6777b538SAndroid Build Coastguard Worker and |builders| contains |ci_builder|. 196*6777b538SAndroid Build Coastguard Worker """ 197*6777b538SAndroid Build Coastguard Worker mirrored_builders = set() 198*6777b538SAndroid Build Coastguard Worker if ci_builder in self.GetNonChromiumBuilders(): 199*6777b538SAndroid Build Coastguard Worker logging.debug('%s is a non-Chromium CI builder', ci_builder.name) 200*6777b538SAndroid Build Coastguard Worker return mirrored_builders, True 201*6777b538SAndroid Build Coastguard Worker 202*6777b538SAndroid Build Coastguard Worker fake_builders = self.GetFakeCiBuilders() 203*6777b538SAndroid Build Coastguard Worker if ci_builder in fake_builders: 204*6777b538SAndroid Build Coastguard Worker mirrored_builders |= fake_builders[ci_builder] 205*6777b538SAndroid Build Coastguard Worker logging.debug('%s is a fake CI builder mirrored by %s', ci_builder.name, 206*6777b538SAndroid Build Coastguard Worker ', '.join(b.name for b in fake_builders[ci_builder])) 207*6777b538SAndroid Build Coastguard Worker return mirrored_builders, True 208*6777b538SAndroid Build Coastguard Worker 209*6777b538SAndroid Build Coastguard Worker bb_output = self._GetBuildbucketOutputForCiBuilder(ci_builder) 210*6777b538SAndroid Build Coastguard Worker if not bb_output: 211*6777b538SAndroid Build Coastguard Worker mirrored_builders.add(ci_builder) 212*6777b538SAndroid Build Coastguard Worker logging.debug('Did not get Buildbucket output for builder %s', 213*6777b538SAndroid Build Coastguard Worker ci_builder.name) 214*6777b538SAndroid Build Coastguard Worker return mirrored_builders, False 215*6777b538SAndroid Build Coastguard Worker 216*6777b538SAndroid Build Coastguard Worker bb_json = json.loads(bb_output) 217*6777b538SAndroid Build Coastguard Worker mirrored = bb_json.get('output', {}).get('properties', 218*6777b538SAndroid Build Coastguard Worker {}).get('mirrored_builders', []) 219*6777b538SAndroid Build Coastguard Worker # The mirror names from Buildbucket include the group separated by :, e.g. 220*6777b538SAndroid Build Coastguard Worker # tryserver.chromium.android:gpu-fyi-try-android-m-nexus-5x-64, so only grab 221*6777b538SAndroid Build Coastguard Worker # the builder name. 222*6777b538SAndroid Build Coastguard Worker for mirror in mirrored: 223*6777b538SAndroid Build Coastguard Worker split = mirror.split(':') 224*6777b538SAndroid Build Coastguard Worker assert len(split) == 2 225*6777b538SAndroid Build Coastguard Worker logging.debug('Got mirrored builder for %s: %s', ci_builder.name, 226*6777b538SAndroid Build Coastguard Worker split[1]) 227*6777b538SAndroid Build Coastguard Worker mirrored_builders.add( 228*6777b538SAndroid Build Coastguard Worker data_types.BuilderEntry(split[1], constants.BuilderTypes.TRY, 229*6777b538SAndroid Build Coastguard Worker ci_builder.is_internal_builder)) 230*6777b538SAndroid Build Coastguard Worker return mirrored_builders, True 231*6777b538SAndroid Build Coastguard Worker 232*6777b538SAndroid Build Coastguard Worker def _GetBuildbucketOutputForCiBuilder(self, 233*6777b538SAndroid Build Coastguard Worker ci_builder: data_types.BuilderEntry 234*6777b538SAndroid Build Coastguard Worker ) -> str: 235*6777b538SAndroid Build Coastguard Worker # Ensure the user is logged in to bb. 236*6777b538SAndroid Build Coastguard Worker if not self._authenticated: 237*6777b538SAndroid Build Coastguard Worker try: 238*6777b538SAndroid Build Coastguard Worker with open(os.devnull, 'w', newline='', encoding='utf-8') as devnull: 239*6777b538SAndroid Build Coastguard Worker subprocess.check_call(['bb', 'auth-info'], 240*6777b538SAndroid Build Coastguard Worker stdout=devnull, 241*6777b538SAndroid Build Coastguard Worker stderr=devnull) 242*6777b538SAndroid Build Coastguard Worker except subprocess.CalledProcessError as e: 243*6777b538SAndroid Build Coastguard Worker six.raise_from( 244*6777b538SAndroid Build Coastguard Worker RuntimeError('You are not logged into bb - run `bb auth-login`.'), 245*6777b538SAndroid Build Coastguard Worker e) 246*6777b538SAndroid Build Coastguard Worker self._authenticated = True 247*6777b538SAndroid Build Coastguard Worker # Split out for ease of testing. 248*6777b538SAndroid Build Coastguard Worker # Get the Buildbucket ID for the most recent completed build for a builder. 249*6777b538SAndroid Build Coastguard Worker p = subprocess.Popen([ 250*6777b538SAndroid Build Coastguard Worker 'bb', 251*6777b538SAndroid Build Coastguard Worker 'ls', 252*6777b538SAndroid Build Coastguard Worker '-id', 253*6777b538SAndroid Build Coastguard Worker '-1', 254*6777b538SAndroid Build Coastguard Worker '-status', 255*6777b538SAndroid Build Coastguard Worker 'ended', 256*6777b538SAndroid Build Coastguard Worker '%s/ci/%s' % (ci_builder.project, ci_builder.name), 257*6777b538SAndroid Build Coastguard Worker ], 258*6777b538SAndroid Build Coastguard Worker stdout=subprocess.PIPE) 259*6777b538SAndroid Build Coastguard Worker # Use the ID to get the most recent build. 260*6777b538SAndroid Build Coastguard Worker bb_output = subprocess.check_output([ 261*6777b538SAndroid Build Coastguard Worker 'bb', 262*6777b538SAndroid Build Coastguard Worker 'get', 263*6777b538SAndroid Build Coastguard Worker '-A', 264*6777b538SAndroid Build Coastguard Worker '-json', 265*6777b538SAndroid Build Coastguard Worker ], 266*6777b538SAndroid Build Coastguard Worker stdin=p.stdout, 267*6777b538SAndroid Build Coastguard Worker text=True) 268*6777b538SAndroid Build Coastguard Worker return bb_output 269*6777b538SAndroid Build Coastguard Worker 270*6777b538SAndroid Build Coastguard Worker def GetIsolateNames(self) -> Set[str]: 271*6777b538SAndroid Build Coastguard Worker """Gets the isolate names that are relevant to this implementation. 272*6777b538SAndroid Build Coastguard Worker 273*6777b538SAndroid Build Coastguard Worker Returns: 274*6777b538SAndroid Build Coastguard Worker A set of strings, each element being the name of an isolate of interest. 275*6777b538SAndroid Build Coastguard Worker """ 276*6777b538SAndroid Build Coastguard Worker raise NotImplementedError() 277*6777b538SAndroid Build Coastguard Worker 278*6777b538SAndroid Build Coastguard Worker def GetFakeCiBuilders(self) -> FakeBuildersDict: 279*6777b538SAndroid Build Coastguard Worker """Gets a mapping of fake CI builders to their mirrored trybots. 280*6777b538SAndroid Build Coastguard Worker 281*6777b538SAndroid Build Coastguard Worker Returns: 282*6777b538SAndroid Build Coastguard Worker A dict of data_types.BuilderEntry -> set(data_types.BuilderEntry). Each 283*6777b538SAndroid Build Coastguard Worker key is a CI builder that doesn't actually exist and each value is a set of 284*6777b538SAndroid Build Coastguard Worker try builders that mirror the CI builder but do exist. 285*6777b538SAndroid Build Coastguard Worker """ 286*6777b538SAndroid Build Coastguard Worker raise NotImplementedError() 287*6777b538SAndroid Build Coastguard Worker 288*6777b538SAndroid Build Coastguard Worker def GetNonChromiumBuilders(self) -> Set[data_types.BuilderEntry]: 289*6777b538SAndroid Build Coastguard Worker """Gets the builders that are not actual Chromium builders. 290*6777b538SAndroid Build Coastguard Worker 291*6777b538SAndroid Build Coastguard Worker These are listed in the Chromium //testing/buildbot files, but aren't under 292*6777b538SAndroid Build Coastguard Worker the Chromium Buildbucket project. These don't use the same recipes as 293*6777b538SAndroid Build Coastguard Worker Chromium builders, and thus don't have the list of trybot mirrors. 294*6777b538SAndroid Build Coastguard Worker 295*6777b538SAndroid Build Coastguard Worker Returns: 296*6777b538SAndroid Build Coastguard Worker A set of data_types.BuilderEntry, each element being a non-Chromium 297*6777b538SAndroid Build Coastguard Worker builder. 298*6777b538SAndroid Build Coastguard Worker """ 299*6777b538SAndroid Build Coastguard Worker raise NotImplementedError() 300*6777b538SAndroid Build Coastguard Worker 301*6777b538SAndroid Build Coastguard Worker 302*6777b538SAndroid Build Coastguard Workerdef _GetPublicJsonFiles() -> List[str]: 303*6777b538SAndroid Build Coastguard Worker return [ 304*6777b538SAndroid Build Coastguard Worker os.path.join(TESTING_BUILDBOT_DIR, f) 305*6777b538SAndroid Build Coastguard Worker for f in os.listdir(TESTING_BUILDBOT_DIR) 306*6777b538SAndroid Build Coastguard Worker if f not in PUBLIC_INTERNAL_JSON_FILES 307*6777b538SAndroid Build Coastguard Worker ] 308*6777b538SAndroid Build Coastguard Worker 309*6777b538SAndroid Build Coastguard Worker 310*6777b538SAndroid Build Coastguard Workerdef _GetInternalJsonFiles() -> List[str]: 311*6777b538SAndroid Build Coastguard Worker internal_files = [ 312*6777b538SAndroid Build Coastguard Worker os.path.join(INTERNAL_TESTING_BUILDBOT_DIR, f) 313*6777b538SAndroid Build Coastguard Worker for f in os.listdir(INTERNAL_TESTING_BUILDBOT_DIR) 314*6777b538SAndroid Build Coastguard Worker ] 315*6777b538SAndroid Build Coastguard Worker public_internal_files = [ 316*6777b538SAndroid Build Coastguard Worker os.path.join(TESTING_BUILDBOT_DIR, f) 317*6777b538SAndroid Build Coastguard Worker for f in os.listdir(TESTING_BUILDBOT_DIR) 318*6777b538SAndroid Build Coastguard Worker if f in PUBLIC_INTERNAL_JSON_FILES 319*6777b538SAndroid Build Coastguard Worker ] 320*6777b538SAndroid Build Coastguard Worker return internal_files + public_internal_files 321