xref: /aosp_15_r20/external/cronet/testing/unexpected_passes_common/builders.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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