#!/usr/bin/env vpython3
# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import json
import os
from typing import Any, Dict, Set, Tuple
import unittest
from unittest import mock

# vpython-provided modules.
from pyfakefs import fake_filesystem_unittest  # pylint: disable=import-error

# //testing imports.
from unexpected_passes_common import builders
from unexpected_passes_common import constants
from unexpected_passes_common import data_types
from unexpected_passes_common import unittest_utils

# Protected access is allowed for unittests.
# pylint: disable=protected-access

class FakeFilesystemTestCaseWithFileCreation(fake_filesystem_unittest.TestCase):
  def CreateFile(self, *args, **kwargs):
    # TODO(crbug.com/40160566): Remove this and just use fs.create_file() when
    # Catapult is updated to a newer version of pyfakefs that is compatible with
    # Chromium's version.
    if hasattr(self.fs, 'create_file'):
      self.fs.create_file(*args, **kwargs)
    else:
      self.fs.CreateFile(*args, **kwargs)


class GetCiBuildersUnittest(FakeFilesystemTestCaseWithFileCreation):
  def setUp(self) -> None:
    self._builders_instance = unittest_utils.GenericBuilders(
        suite='webgl_conformance')
    self._isolate_patcher = mock.patch.object(
        self._builders_instance,
        'GetIsolateNames',
        return_value={'telemetry_gpu_integration_test'})
    self._isolate_mock = self._isolate_patcher.start()
    self.addCleanup(self._isolate_patcher.stop)

  def testJsonContentLoaded(self) -> None:
    """Tests that the correct JSON data is loaded in."""
    self.setUpPyfakefs()
    gpu_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'Android Release (Nexus 5X)': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
        'GPU Linux Builder': {},
    }
    gpu_fyi_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'ANGLE GPU Android Release (Nexus 5X)': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
        'GPU FYI Linux Builder': {},
    }
    ci_infra_config_json = {
        'Infra Config GPU': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
    }
    # Should be ignored.
    tryserver_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'Trybot': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
    }
    # Also should be ignored.
    try_infra_config_json = {
        'Infra Config Try': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
    }
    # Also should be ignored.
    not_buildbot_json = {
        'Not buildbot': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
    }

    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'chromium.gpu.json'),
                    contents=json.dumps(gpu_json))
    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'chromium.gpu.fyi.json'),
                    contents=json.dumps(gpu_fyi_json))
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'ci',
                                 'Infra Config GPU', 'targets',
                                 'infra.gpu.json'),
                    contents=json.dumps(ci_infra_config_json))
    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'tryserver.gpu.json'),
                    contents=json.dumps(tryserver_json))
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'try',
                                 'Infra Config Try', 'targets',
                                 'infra.gpu.json'),
                    contents=json.dumps(try_infra_config_json))
    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'not_buildbot.json'),
                    contents=json.dumps(not_buildbot_json))

    gpu_builders = self._builders_instance.GetCiBuilders()
    self.assertEqual(
        gpu_builders,
        set([
            data_types.BuilderEntry('Android Release (Nexus 5X)',
                                    constants.BuilderTypes.CI, False),
            data_types.BuilderEntry('ANGLE GPU Android Release (Nexus 5X)',
                                    constants.BuilderTypes.CI, False),
            data_types.BuilderEntry('Infra Config GPU',
                                    constants.BuilderTypes.CI, False),
            data_types.BuilderEntry('GPU Linux Builder',
                                    constants.BuilderTypes.CI, False),
            data_types.BuilderEntry('GPU FYI Linux Builder',
                                    constants.BuilderTypes.CI, False),
        ]))

  def testPublicInternalBuilders(self) -> None:
    """Tests that public internal builders are treated as internal."""
    self.setUpPyfakefs()
    gpu_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'Android Release (Nexus 5X)': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
        'GPU Linux Builder': {},
    }
    gpu_internal_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'Android Chrome Release (Nexus 5X)': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
        'GPU Chrome Linux Builder': {},
    }
    internal_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'Android Internal Release (Nexus 5X)': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
        'GPU Internal Linux Builder': {},
    }
    internal_infra_config_json = {
        'Infra Config Internal': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
    }

    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'chromium.gpu.json'),
                    contents=json.dumps(gpu_json))
    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'chrome.gpu.fyi.json'),
                    contents=json.dumps(gpu_internal_json))
    self.CreateFile(os.path.join(builders.INTERNAL_TESTING_BUILDBOT_DIR,
                                 'internal.json'),
                    contents=json.dumps(internal_json))
    self.CreateFile(os.path.join(builders.INTERNAL_INFRA_CONFIG_BUILDERS_DIR,
                                 'ci', 'Infra Config Internal', 'targets',
                                 'infra.config.json'),
                    contents=json.dumps(internal_infra_config_json))

    # Dummy file so that pyfakefs doesn't complain when we check for public
    # infra/config files.
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'ci',
                                 'Fake', 'targets', 'fake.json'),
                    contents=json.dumps({}))

    gpu_builders = self._builders_instance.GetCiBuilders()
    self.assertEqual(
        gpu_builders,
        set([
            data_types.BuilderEntry('Android Release (Nexus 5X)',
                                    constants.BuilderTypes.CI, False),
            data_types.BuilderEntry('GPU Linux Builder',
                                    constants.BuilderTypes.CI, False),
        ]))

    internal_instance = unittest_utils.GenericBuilders(
        suite='webgl_conformance', include_internal_builders=True)
    with mock.patch.object(internal_instance,
                           'GetIsolateNames',
                           return_value={'telemetry_gpu_integration_test'}):
      gpu_builders = internal_instance.GetCiBuilders()
    self.assertEqual(
        gpu_builders,
        set([
            data_types.BuilderEntry('Android Release (Nexus 5X)',
                                    constants.BuilderTypes.CI, False),
            data_types.BuilderEntry('Android Chrome Release (Nexus 5X)',
                                    constants.BuilderTypes.CI, True),
            data_types.BuilderEntry('Android Internal Release (Nexus 5X)',
                                    constants.BuilderTypes.CI, True),
            data_types.BuilderEntry('GPU Linux Builder',
                                    constants.BuilderTypes.CI, False),
            data_types.BuilderEntry('GPU Chrome Linux Builder',
                                    constants.BuilderTypes.CI, True),
            data_types.BuilderEntry('GPU Internal Linux Builder',
                                    constants.BuilderTypes.CI, True),
            data_types.BuilderEntry('Infra Config Internal',
                                    constants.BuilderTypes.CI, True)
        ]))

  def testFilterBySuite(self) -> None:
    """Tests that only builders that run the given suite are returned."""

    def SideEffect(tm: Dict[str, Any]) -> bool:
      tests = tm.get('isolated_scripts', [])
      for t in tests:
        if t.get('isolate_name') == 'foo_integration_test':
          if 'webgl_conformance' in t.get('args', []):
            return True
      return False

    self.setUpPyfakefs()
    gpu_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'Android Tester': {
            'isolated_scripts': [
                {
                    'args': [
                        'webgl_conformance',
                    ],
                    'isolate_name': 'not_telemetry',
                },
            ],
        },
        'Linux Tester': {
            'isolated_scripts': [
                {
                    'args': [
                        'not_a_suite',
                    ],
                    'isolate_name': 'foo_integration_test',
                },
            ],
        },
        'Windows Tester': {
            'isolated_scripts': [
                {
                    'args': [
                        'webgl_conformance',
                    ],
                    'isolate_name': 'foo_integration_test',
                },
            ],
        },
    }
    matching_infra_config_json = {
        'Matching Infra Config': {
            'isolated_scripts': [
                {
                    'args': [
                        'webgl_conformance',
                    ],
                    'isolate_name': 'foo_integration_test',
                },
            ],
        },
    }
    not_matching_infra_config_json = {
        'Not Matching Infra Config': {
            'isolated_scripts': [
                {
                    'args': [
                        'not_a_suite',
                    ],
                    'isolate_name': 'foo_integration_test',
                },
            ],
        },
    }

    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'chromium.json'),
                    contents=json.dumps(gpu_json))
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'ci',
                                 'Matching Infra Config', 'targets',
                                 'infra.config.json'),
                    contents=json.dumps(matching_infra_config_json))
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'ci',
                                 'Not Matching Infra Config', 'targets',
                                 'infra.config.json'),
                    contents=json.dumps(not_matching_infra_config_json))

    with mock.patch.object(self._builders_instance,
                           '_BuilderRunsTestOfInterest',
                           side_effect=SideEffect):
      gpu_builders = self._builders_instance.GetCiBuilders()
    self.assertEqual(
        gpu_builders, {
            data_types.BuilderEntry('Windows Tester', constants.BuilderTypes.CI,
                                    False),
            data_types.BuilderEntry('Matching Infra Config',
                                    constants.BuilderTypes.CI, False),
        })

  def testRealContentCanBeLoaded(self) -> None:
    """Tests that *something* from the real JSON files can be loaded."""
    # This directory is not available on swarming, so if it doesn't exist, just
    # skip the test.
    if not os.path.exists(builders.TESTING_BUILDBOT_DIR):
      return
    self.assertNotEqual(len(self._builders_instance.GetCiBuilders()), 0)


class GetMirroredBuildersForCiBuilderUnittest(unittest.TestCase):
  def setUp(self) -> None:
    self._builders_instance = builders.Builders('suite', False)
    self._bb_patcher = mock.patch.object(self._builders_instance,
                                         '_GetBuildbucketOutputForCiBuilder')
    self._bb_mock = self._bb_patcher.start()
    self.addCleanup(self._bb_patcher.stop)
    self._fake_ci_patcher = mock.patch.object(self._builders_instance,
                                              'GetFakeCiBuilders',
                                              return_value={})
    self._fake_ci_mock = self._fake_ci_patcher.start()
    self.addCleanup(self._fake_ci_patcher.stop)
    self._non_chromium_patcher = mock.patch.object(
        self._builders_instance,
        'GetNonChromiumBuilders',
        return_value={'foo_non_chromium'})
    self._non_chromium_mock = self._non_chromium_patcher.start()
    self.addCleanup(self._non_chromium_patcher.stop)

  def testFakeCiBuilder(self) -> None:
    """Tests that a fake CI builder gets properly mapped."""
    self._fake_ci_mock.return_value = {
        data_types.BuilderEntry('foo_ci', constants.BuilderTypes.CI, False):
        {data_types.BuilderEntry('foo_try', constants.BuilderTypes.TRY, False)}
    }
    try_builder, found_mirror = (
        self._builders_instance._GetMirroredBuildersForCiBuilder(
            data_types.BuilderEntry('foo_ci', constants.BuilderTypes.CI,
                                    False)))
    self.assertTrue(found_mirror)
    self.assertEqual(
        try_builder,
        set([
            data_types.BuilderEntry('foo_try', constants.BuilderTypes.TRY,
                                    False)
        ]))
    self._bb_mock.assert_not_called()

  def testNoBuildbucketOutput(self) -> None:
    """Tests that a failure to get Buildbucket output is surfaced."""
    self._bb_mock.return_value = ''
    builder_entry = data_types.BuilderEntry('nonexistent',
                                            constants.BuilderTypes.CI, False)
    try_builder, found_mirror = (
        self._builders_instance._GetMirroredBuildersForCiBuilder(builder_entry))
    self.assertFalse(found_mirror)
    self.assertEqual(try_builder, set([builder_entry]))

  def testBuildbucketOutput(self):
    """Tests that Buildbucket output is parsed correctly."""
    self._bb_mock.return_value = json.dumps({
        'output': {
            'properties': {
                'mirrored_builders': [
                    'try:foo_try',
                    'try:bar_try',
                ]
            }
        }
    })
    try_builders, found_mirror = (
        self._builders_instance._GetMirroredBuildersForCiBuilder(
            data_types.BuilderEntry('foo_ci', constants.BuilderTypes.CI,
                                    False)))
    self.assertTrue(found_mirror)
    self.assertEqual(
        try_builders,
        set([
            data_types.BuilderEntry('foo_try', constants.BuilderTypes.TRY,
                                    False),
            data_types.BuilderEntry('bar_try', constants.BuilderTypes.TRY,
                                    False)
        ]))

  def testBuildbucketOutputInternal(self) -> None:
    """Tests that internal Buildbucket output is parsed correctly."""
    self._bb_mock.return_value = json.dumps({
        'output': {
            'properties': {
                'mirrored_builders': [
                    'try:foo_try',
                    'try:bar_try',
                ]
            }
        }
    })
    try_builders, found_mirror = (
        self._builders_instance._GetMirroredBuildersForCiBuilder(
            data_types.BuilderEntry('foo_ci', constants.BuilderTypes.CI, True)))
    self.assertTrue(found_mirror)
    self.assertEqual(
        try_builders,
        set([
            data_types.BuilderEntry('foo_try', constants.BuilderTypes.TRY,
                                    True),
            data_types.BuilderEntry('bar_try', constants.BuilderTypes.TRY, True)
        ]))


class GetTryBuildersUnittest(FakeFilesystemTestCaseWithFileCreation):
  def setUp(self) -> None:
    self._builders_instance = builders.Builders('suite', False)
    self._get_patcher = mock.patch.object(self._builders_instance,
                                          '_GetMirroredBuildersForCiBuilder')
    self._get_mock = self._get_patcher.start()
    self.addCleanup(self._get_patcher.stop)
    self._runs_test_patcher = mock.patch.object(self._builders_instance,
                                                '_BuilderRunsTestOfInterest')
    self._runs_test_mock = self._runs_test_patcher.start()
    self.addCleanup(self._runs_test_patcher.stop)

    self.setUpPyfakefs()
    # Make sure the directory exists.
    self.CreateFile(
        os.path.join(builders.TESTING_BUILDBOT_DIR, 'placeholder.txt'))

  def testMirrorNoOutputCausesFailure(self) -> None:
    """Tests that a failure to get Buildbot output raises an exception."""
    # Create a dummy file so that pyfakefs does not complain about a directory
    # not existing.
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'try',
                                 'Fake', 'targets', 'fake.json'),
                    contents=json.dumps({}))
    builder = data_types.BuilderEntry('foo_ci', constants.BuilderTypes.CI,
                                      False)
    self._get_mock.return_value = (set([builder]), False)
    self._runs_test_mock.return_value = True
    with self.assertRaises(RuntimeError):
      self._builders_instance.GetTryBuilders([builder])

  def testMirrorOutputReturned(self) -> None:
    """Tests that parsed, mirrored builders get returned on success."""

    def SideEffect(ci_builder: data_types.BuilderEntry
                   ) -> Tuple[Set[data_types.BuilderEntry], bool]:
      b = [
          data_types.BuilderEntry(ci_builder.name.replace('ci', 'try'),
                                  constants.BuilderTypes.TRY, False),
          data_types.BuilderEntry(ci_builder.name.replace('ci', 'try2'),
                                  constants.BuilderTypes.TRY, False),
      ]
      return set(b), True

    # Create a dummy file so that pyfakefs does not complain about a directory
    # not existing.
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'try',
                                 'Fake', 'targets', 'fake.json'),
                    contents=json.dumps({}))

    self._get_mock.side_effect = SideEffect
    self._runs_test_mock.return_value = False
    mirrored_builders = self._builders_instance.GetTryBuilders([
        data_types.BuilderEntry('foo_ci', constants.BuilderTypes.CI, False),
        data_types.BuilderEntry('bar_ci', constants.BuilderTypes.CI, False),
    ])
    self.assertEqual(
        mirrored_builders,
        set([
            data_types.BuilderEntry('foo_try', constants.BuilderTypes.TRY,
                                    False),
            data_types.BuilderEntry('foo_try2', constants.BuilderTypes.TRY,
                                    False),
            data_types.BuilderEntry('bar_try', constants.BuilderTypes.TRY,
                                    False),
            data_types.BuilderEntry('bar_try2', constants.BuilderTypes.TRY,
                                    False),
        ]))

  def testDedicatedJsonContentLoaded(self) -> None:
    """Tests that tryserver JSON content is loaded."""

    def SideEffect(test_spec: Dict[str, Any]) -> bool:
      # Treat non-empty test specs as valid.
      return bool(test_spec)

    self._runs_test_mock.side_effect = SideEffect
    # Should be ignored.
    gpu_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'Android Release (Nexus 5X)': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
        'GPU Linux Builder': {},
    }
    # Should be ignored.
    gpu_fyi_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'ANGLE GPU Android Release (Nexus 5X)': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
        'GPU FYI Linux Builder': {},
    }
    # Also should be ignored.
    ci_infra_config_json = {
        'CI Infra Config': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
    }
    tryserver_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'Trybot': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
        'Trybot Empty': {},
    }
    try_infra_config_json = {
        'Mirrored CI Infra Config': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
    }
    # Also should be ignored.
    not_buildbot_json = {
        'Not buildbot': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
    }

    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'chromium.gpu.json'),
                    contents=json.dumps(gpu_json))
    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'chromium.gpu.fyi.json'),
                    contents=json.dumps(gpu_fyi_json))
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'ci',
                                 'CI Infra Config', 'targets',
                                 'infra.config.json'),
                    contents=json.dumps(ci_infra_config_json))
    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'tryserver.gpu.json'),
                    contents=json.dumps(tryserver_json))
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'try',
                                 'Try Infra Config', 'targets',
                                 'infra.config.json'),
                    contents=json.dumps(try_infra_config_json))
    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'not_buildbot.json'),
                    contents=json.dumps(not_buildbot_json))

    gpu_builders = self._builders_instance.GetTryBuilders({})
    self.assertEqual(
        gpu_builders, {
            data_types.BuilderEntry('Trybot', constants.BuilderTypes.TRY,
                                    False),
            data_types.BuilderEntry('Try Infra Config',
                                    constants.BuilderTypes.TRY, False),
        })

  def testDedicatedFilterBySuite(self) -> None:
    """Tests that only builders that run the given suite are returned."""

    def SideEffect(tm: Dict[str, Any]) -> bool:
      tests = tm.get('isolated_scripts', [])
      for t in tests:
        if t.get('isolate_name') == 'foo_integration_test':
          if 'webgl_conformance' in t.get('args', []):
            return True
      return False

    self._runs_test_mock.side_effect = SideEffect
    gpu_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'Android Tester': {
            'isolated_scripts': [
                {
                    'args': [
                        'webgl_conformance',
                    ],
                    'isolate_name': 'not_telemetry',
                },
            ],
        },
        'Linux Tester': {
            'isolated_scripts': [
                {
                    'args': [
                        'not_a_suite',
                    ],
                    'isolate_name': 'foo_integration_test',
                },
            ],
        },
        'Windows Tester': {
            'isolated_scripts': [
                {
                    'args': [
                        'webgl_conformance',
                    ],
                    'isolate_name': 'foo_integration_test',
                },
            ],
        },
    }
    matching_infra_config_json = {
        'Matching Infra Config Mirrored CI': {
            'isolated_scripts': [
                {
                    'args': [
                        'webgl_conformance',
                    ],
                    'isolate_name': 'foo_integration_test',
                },
            ],
        },
    }
    not_matching_infra_config_json = {
        'Not Matching Infra Config': {
            'isolated_scripts': [
                {
                    'args': [
                        'not_a_suite',
                    ],
                    'isolate_name': 'foo_integration_test',
                },
            ],
        },
    }

    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'tryserver.chromium.json'),
                    contents=json.dumps(gpu_json))
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'try',
                                 'Matching Infra Config', 'targets',
                                 'infra.config.json'),
                    contents=json.dumps(matching_infra_config_json))
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'try',
                                 'Not Matching Infra Config', 'targets',
                                 'infra.config.json'),
                    contents=json.dumps(not_matching_infra_config_json))


    gpu_builders = self._builders_instance.GetTryBuilders({})
    self.assertEqual(
        gpu_builders, {
            data_types.BuilderEntry('Windows Tester',
                                    constants.BuilderTypes.TRY, False),
            data_types.BuilderEntry('Matching Infra Config',
                                    constants.BuilderTypes.TRY, False),
        })

  def testDedicatedAndMirroredCombined(self) -> None:
    """Tests that both dedicated and mirrored trybots are returned."""

    def SideEffect(_: Any) -> Tuple[Set[data_types.BuilderEntry], bool]:
      return set({
          data_types.BuilderEntry('mirrored_trybot', constants.BuilderTypes.TRY,
                                  False)
      }), True

    self._get_mock.side_effect = SideEffect
    self._runs_test_mock.return_value = True
    tryserver_json = {
        'AAAAA1 AUTOGENERATED FILE DO NOT EDIT': {},
        'Trybot': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
    }
    infra_config_json = {
        'Infra Config Mirrored CI': {
            'isolated_scripts': [{
                'args': [
                    'webgl_conformance',
                ],
                'isolate_name':
                'telemetry_gpu_integration_test',
            }],
        },
    }

    self.CreateFile(os.path.join(builders.TESTING_BUILDBOT_DIR,
                                 'tryserver.chromium.json'),
                    contents=json.dumps(tryserver_json))
    self.CreateFile(os.path.join(builders.INFRA_CONFIG_BUILDERS_DIR, 'try',
                                 'Infra Config', 'targets',
                                 'infra.config.json'),
                    contents=json.dumps(infra_config_json))

    try_builders = self._builders_instance.GetTryBuilders({
        data_types.BuilderEntry('ci_builder', constants.BuilderTypes.CI, False)
    })
    self.assertEqual(
        try_builders, {
            data_types.BuilderEntry('mirrored_trybot',
                                    constants.BuilderTypes.TRY, False),
            data_types.BuilderEntry('Trybot', constants.BuilderTypes.TRY,
                                    False),
            data_types.BuilderEntry('Infra Config', constants.BuilderTypes.TRY,
                                    False),
        })


if __name__ == '__main__':
  unittest.main(verbosity=2)
