#!/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.

from typing import Iterable, Optional
import unittest
from unittest import mock

# //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 expectations
from unexpected_passes_common import queries
from unexpected_passes_common import unittest_utils as uu

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

class HelperMethodUnittest(unittest.TestCase):
  def testStripPrefixFromBuildIdValidId(self) -> None:
    self.assertEqual(queries._StripPrefixFromBuildId('build-1'), '1')

  def testStripPrefixFromBuildIdInvalidId(self) -> None:
    with self.assertRaises(AssertionError):
      queries._StripPrefixFromBuildId('build1')
    with self.assertRaises(AssertionError):
      queries._StripPrefixFromBuildId('build-1-2')

  def testConvertActualResultToExpectationFileFormatAbort(self) -> None:
    self.assertEqual(
        queries._ConvertActualResultToExpectationFileFormat('ABORT'), 'Timeout')


class BigQueryQuerierInitUnittest(unittest.TestCase):

  def testInvalidNumSamples(self):
    """Tests that the number of samples is validated."""
    with self.assertRaises(AssertionError):
      uu.CreateGenericQuerier(num_samples=-1)

  def testDefaultSamples(self):
    """Tests that the number of samples is set to a default if not provided."""
    querier = uu.CreateGenericQuerier(num_samples=0)
    self.assertGreater(querier._num_samples, 0)


class GetBuilderGroupedQueryResultsUnittest(unittest.TestCase):

  def setUp(self):
    builders.ClearInstance()
    expectations.ClearInstance()
    uu.RegisterGenericBuildersImplementation()
    uu.RegisterGenericExpectationsImplementation()
    self._querier = uu.CreateGenericQuerier()

  def testUnknownBuilderType(self):
    """Tests behavior when an unknown builder type is provided."""
    with self.assertRaisesRegex(RuntimeError, 'Unknown builder type unknown'):
      for _ in self._querier.GetBuilderGroupedQueryResults('unknown', False):
        pass

  def testQueryRouting(self):
    """Tests that the correct query is used based on inputs."""
    with mock.patch.object(self._querier,
                           '_GetPublicCiQuery',
                           return_value='public_ci') as public_ci_mock:
      with mock.patch.object(self._querier,
                             '_GetInternalCiQuery',
                             return_value='internal_ci') as internal_ci_mock:
        with mock.patch.object(self._querier,
                               '_GetPublicTryQuery',
                               return_value='public_try') as public_try_mock:
          with mock.patch.object(
              self._querier,
              '_GetInternalTryQuery',
              return_value='internal_try') as internal_try_mock:
            all_mocks = [
                public_ci_mock,
                internal_ci_mock,
                public_try_mock,
                internal_try_mock,
            ]
            inputs = [
                (constants.BuilderTypes.CI, False, public_ci_mock),
                (constants.BuilderTypes.CI, True, internal_ci_mock),
                (constants.BuilderTypes.TRY, False, public_try_mock),
                (constants.BuilderTypes.TRY, True, internal_try_mock),
            ]
            for builder_type, internal_status, called_mock in inputs:
              for _ in self._querier.GetBuilderGroupedQueryResults(
                  builder_type, internal_status):
                pass
              for m in all_mocks:
                if m == called_mock:
                  m.assert_called_once()
                else:
                  m.assert_not_called()
              for m in all_mocks:
                m.reset_mock()

  def testNoResults(self):
    """Tests functionality if the query returns no results."""
    returned_builders = []
    with self.assertLogs(level='WARNING') as log_manager:
      with mock.patch.object(self._querier,
                             '_GetPublicCiQuery',
                             return_value=''):
        for builder_name, _, _ in self._querier.GetBuilderGroupedQueryResults(
            constants.BuilderTypes.CI, False):
          returned_builders.append(builder_name)
      for message in log_manager.output:
        if ('Did not get any results for builder type ci and internal status '
            'False. Depending on where tests are run and how frequently '
            'trybots are used for submission, this may be benign') in message:
          break
      else:
        self.fail('Did not find expected log message: %s' % log_manager.output)
      self.assertEqual(len(returned_builders), 0)

  def testHappyPath(self):
    """Tests functionality in the happy path."""
    self._querier.query_results = [
        uu.FakeQueryResult(builder_name='builder_a',
                           id_='build-a',
                           test_id='test_a',
                           status='PASS',
                           typ_tags=['linux', 'unknown_tag'],
                           step_name='step_a'),
        uu.FakeQueryResult(builder_name='builder_b',
                           id_='build-b',
                           test_id='test_b',
                           status='FAIL',
                           typ_tags=['win'],
                           step_name='step_b'),
    ]

    expected_results = [
        ('builder_a',
         [data_types.BaseResult('test_a', ('linux', ), 'Pass', 'step_a',
                                'a')], None),
        ('builder_b',
         [data_types.BaseResult('test_b', ('win', ), 'Failure', 'step_b',
                                'b')], None),
    ]

    results = []
    with mock.patch.object(self._querier, '_GetPublicCiQuery', return_value=''):
      for builder_name, result_list, expectation_files in (
          self._querier.GetBuilderGroupedQueryResults(constants.BuilderTypes.CI,
                                                      False)):
        results.append((builder_name, result_list, expectation_files))

    self.assertEqual(results, expected_results)

  def testHappyPathWithExpectationFiles(self):
    """Tests functionality in the happy path with expectation files provided."""
    self._querier.query_results = [
        uu.FakeQueryResult(builder_name='builder_a',
                           id_='build-a',
                           test_id='test_a',
                           status='PASS',
                           typ_tags=['linux', 'unknown_tag'],
                           step_name='step_a'),
        uu.FakeQueryResult(builder_name='builder_b',
                           id_='build-b',
                           test_id='test_b',
                           status='FAIL',
                           typ_tags=['win'],
                           step_name='step_b'),
    ]

    expected_results = [
        ('builder_a',
         [data_types.BaseResult('test_a', ('linux', ), 'Pass', 'step_a',
                                'a')], list(set(['ef_a']))),
        ('builder_b',
         [data_types.BaseResult('test_b', ('win', ), 'Failure', 'step_b',
                                'b')], list(set(['ef_b', 'ef_c']))),
    ]

    results = []
    with mock.patch.object(self._querier,
                           '_GetRelevantExpectationFilesForQueryResult',
                           side_effect=(['ef_a'], ['ef_b', 'ef_c'])):
      with mock.patch.object(self._querier,
                             '_GetPublicCiQuery',
                             return_value=''):
        for builder_name, result_list, expectation_files in (
            self._querier.GetBuilderGroupedQueryResults(
                constants.BuilderTypes.CI, False)):
          results.append((builder_name, result_list, expectation_files))

    self.assertEqual(results, expected_results)


class FillExpectationMapForBuildersUnittest(unittest.TestCase):
  def setUp(self) -> None:
    self._querier = uu.CreateGenericQuerier()

    expectations.ClearInstance()
    uu.RegisterGenericExpectationsImplementation()

  def testErrorOnMixedBuilders(self) -> None:
    """Tests that providing builders of mixed type is an error."""
    builders_to_fill = [
        data_types.BuilderEntry('ci_builder', constants.BuilderTypes.CI, False),
        data_types.BuilderEntry('try_builder', constants.BuilderTypes.TRY,
                                False)
    ]
    with self.assertRaises(AssertionError):
      self._querier.FillExpectationMapForBuilders(
          data_types.TestExpectationMap({}), builders_to_fill)

  def _runValidResultsTest(self, keep_unmatched_results: bool) -> None:
    self._querier = uu.CreateGenericQuerier(
        keep_unmatched_results=keep_unmatched_results)

    public_results = [
        uu.FakeQueryResult(builder_name='matched_builder',
                           id_='build-build_id',
                           test_id='foo',
                           status='PASS',
                           typ_tags=['win'],
                           step_name='step_name'),
        uu.FakeQueryResult(builder_name='unmatched_builder',
                           id_='build-build_id',
                           test_id='bar',
                           status='PASS',
                           typ_tags=[],
                           step_name='step_name'),
        uu.FakeQueryResult(builder_name='extra_builder',
                           id_='build-build_id',
                           test_id='foo',
                           status='PASS',
                           typ_tags=['win'],
                           step_name='step_name'),
    ]

    internal_results = [
        uu.FakeQueryResult(builder_name='matched_internal',
                           id_='build-build_id',
                           test_id='foo',
                           status='PASS',
                           typ_tags=['win'],
                           step_name='step_name_internal'),
        uu.FakeQueryResult(builder_name='unmatched_internal',
                           id_='build-build_id',
                           test_id='bar',
                           status='PASS',
                           typ_tags=[],
                           step_name='step_name_internal'),
    ]

    builders_to_fill = [
        data_types.BuilderEntry('matched_builder', constants.BuilderTypes.CI,
                                False),
        data_types.BuilderEntry('unmatched_builder', constants.BuilderTypes.CI,
                                False),
        data_types.BuilderEntry('matched_internal', constants.BuilderTypes.CI,
                                True),
        data_types.BuilderEntry('unmatched_internal', constants.BuilderTypes.CI,
                                True),
    ]

    expectation = data_types.Expectation('foo', ['win'], 'RetryOnFailure',
                                         data_types.WildcardType.NON_WILDCARD)
    expectation_map = data_types.TestExpectationMap({
        'foo':
        data_types.ExpectationBuilderMap({
            expectation:
            data_types.BuilderStepMap(),
        }),
    })

    def PublicSideEffect():
      self._querier.query_results = public_results
      return ''

    def InternalSideEffect():
      self._querier.query_results = internal_results
      return ''

    with self.assertLogs(level='WARNING') as log_manager:
      with mock.patch.object(self._querier,
                             '_GetPublicCiQuery',
                             side_effect=PublicSideEffect) as public_mock:
        with mock.patch.object(self._querier,
                               '_GetInternalCiQuery',
                               side_effect=InternalSideEffect) as internal_mock:
          unmatched_results = self._querier.FillExpectationMapForBuilders(
              expectation_map, builders_to_fill)
          public_mock.assert_called_once()
          internal_mock.assert_called_once()

      for message in log_manager.output:
        if ('Did not find a matching builder for name extra_builder and '
            'internal status False. This is normal if the builder is no longer '
            'running tests (e.g. it was experimental).') in message:
          break
      else:
        self.fail('Did not find expected log message')

    stats = data_types.BuildStats()
    stats.AddPassedBuild(frozenset(['win']))
    expected_expectation_map = {
        'foo': {
            expectation: {
                'chromium/ci:matched_builder': {
                    'step_name': stats,
                },
                'chrome/ci:matched_internal': {
                    'step_name_internal': stats,
                },
            },
        },
    }
    self.assertEqual(expectation_map, expected_expectation_map)
    if keep_unmatched_results:
      self.assertEqual(
          unmatched_results, {
              'chromium/ci:unmatched_builder': [
                  data_types.Result('bar', [], 'Pass', 'step_name', 'build_id'),
              ],
              'chrome/ci:unmatched_internal': [
                  data_types.Result('bar', [], 'Pass', 'step_name_internal',
                                    'build_id'),
              ],
          })
    else:
      self.assertEqual(unmatched_results, {})

  def testValidResultsKeepUnmatched(self) -> None:
    """Tests behavior w/ valid results and keeping unmatched results."""
    self._runValidResultsTest(True)

  def testValidResultsDoNotKeepUnmatched(self) -> None:
    """Tests behavior w/ valid results and not keeping unmatched results."""
    self._runValidResultsTest(False)


class ProcessRowsForBuilderUnittest(unittest.TestCase):

  def setUp(self):
    self._querier = uu.CreateGenericQuerier()

  def testHappyPathWithExpectationFiles(self):
    """Tests functionality along the happy path with expectation files."""

    def SideEffect(row: queries.QueryResult) -> Optional[Iterable[str]]:
      if row.step_name == 'step_a1':
        return ['ef_a1']
      if row.step_name == 'step_a2':
        return ['ef_a2']
      if row.step_name == 'step_b':
        return ['ef_b1', 'ef_b2']
      raise RuntimeError('Unexpected row')

    rows = [
        uu.FakeQueryResult(builder_name='unused',
                           id_='build-a',
                           test_id='test_a',
                           status='PASS',
                           typ_tags=['linux', 'unknown_tag'],
                           step_name='step_a1'),
        uu.FakeQueryResult(builder_name='unused',
                           id_='build-a',
                           test_id='test_a',
                           status='FAIL',
                           typ_tags=['linux', 'unknown_tag'],
                           step_name='step_a2'),
        uu.FakeQueryResult(builder_name='unused',
                           id_='build-b',
                           test_id='test_b',
                           status='FAIL',
                           typ_tags=['win'],
                           step_name='step_b'),
    ]

    # Reversed order is expected since results are popped.
    expected_results = [
        data_types.BaseResult(test='test_b',
                              tags=['win'],
                              actual_result='Failure',
                              step='step_b',
                              build_id='b'),
        data_types.BaseResult(test='test_a',
                              tags=['linux'],
                              actual_result='Failure',
                              step='step_a2',
                              build_id='a'),
        data_types.BaseResult(test='test_a',
                              tags=['linux'],
                              actual_result='Pass',
                              step='step_a1',
                              build_id='a'),
    ]

    with mock.patch.object(self._querier,
                           '_GetRelevantExpectationFilesForQueryResult',
                           side_effect=SideEffect):
      results, expectation_files = self._querier._ProcessRowsForBuilder(rows)
    self.assertEqual(results, expected_results)
    self.assertEqual(len(expectation_files), len(set(expectation_files)))
    self.assertEqual(set(expectation_files),
                     set(['ef_a1', 'ef_a2', 'ef_b1', 'ef_b2']))

  def testHappyPathNoneExpectation(self):
    """Tests functionality along the happy path with a None expectation file."""

    # A single None expectation file should cause the resulting return value to
    # become None.
    def SideEffect(row: queries.QueryResult) -> Optional[Iterable[str]]:
      if row.step_name == 'step_a1':
        return ['ef_a1']
      if row.step_name == 'step_a2':
        return ['ef_a2']
      return None

    rows = [
        uu.FakeQueryResult(builder_name='unused',
                           id_='build-a',
                           test_id='test_a',
                           status='PASS',
                           typ_tags=['linux', 'unknown_tag'],
                           step_name='step_a1'),
        uu.FakeQueryResult(builder_name='unused',
                           id_='build-a',
                           test_id='test_a',
                           status='FAIL',
                           typ_tags=['linux', 'unknown_tag'],
                           step_name='step_a2'),
        uu.FakeQueryResult(builder_name='unused',
                           id_='build-b',
                           test_id='test_b',
                           status='FAIL',
                           typ_tags=['win'],
                           step_name='step_b'),
    ]

    # Reversed order is expected since results are popped.
    expected_results = [
        data_types.BaseResult(test='test_b',
                              tags=['win'],
                              actual_result='Failure',
                              step='step_b',
                              build_id='b'),
        data_types.BaseResult(test='test_a',
                              tags=['linux'],
                              actual_result='Failure',
                              step='step_a2',
                              build_id='a'),
        data_types.BaseResult(test='test_a',
                              tags=['linux'],
                              actual_result='Pass',
                              step='step_a1',
                              build_id='a'),
    ]

    with mock.patch.object(self._querier,
                           '_GetRelevantExpectationFilesForQueryResult',
                           side_effect=SideEffect):
      results, expectation_files = self._querier._ProcessRowsForBuilder(rows)
    self.assertEqual(results, expected_results)
    self.assertEqual(expectation_files, None)

  def testHappyPathSkippedResult(self):
    """Tests functionality along the happy path with a skipped result."""

    def SideEffect(row: queries.QueryResult) -> bool:
      if row.step_name == 'step_b':
        return True
      return False

    rows = [
        uu.FakeQueryResult(builder_name='unused',
                           id_='build-a',
                           test_id='test_a',
                           status='PASS',
                           typ_tags=['linux', 'unknown_tag'],
                           step_name='step_a1'),
        uu.FakeQueryResult(builder_name='unused',
                           id_='build-a',
                           test_id='test_a',
                           status='FAIL',
                           typ_tags=['linux', 'unknown_tag'],
                           step_name='step_a2'),
        uu.FakeQueryResult(builder_name='unused',
                           id_='build-b',
                           test_id='test_b',
                           status='FAIL',
                           typ_tags=['win'],
                           step_name='step_b'),
    ]

    # Reversed order is expected since results are popped.
    expected_results = [
        data_types.BaseResult(test='test_a',
                              tags=['linux'],
                              actual_result='Failure',
                              step='step_a2',
                              build_id='a'),
        data_types.BaseResult(test='test_a',
                              tags=['linux'],
                              actual_result='Pass',
                              step='step_a1',
                              build_id='a'),
    ]

    with mock.patch.object(self._querier,
                           '_ShouldSkipOverResult',
                           side_effect=SideEffect):
      results, expectation_files = self._querier._ProcessRowsForBuilder(rows)
    self.assertEqual(results, expected_results)
    self.assertEqual(expectation_files, None)


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