# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Tests for innocent_cls_precq.py"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import datetime

from chromite.lib import build_requests
from chromite.lib import clactions
from chromite.lib import constants
from chromite.lib import cros_test_lib
from chromite.lib import fake_cidb
from google.cloud import datastore  # pylint: disable=E0611,import-error

from exonerator import innocent_cls_cq
from exonerator import innocent_cls_cq_test
from exonerator import innocent_cls_precq
from exonerator import innocent_cls_precq_flake
from testing_utils import fake_datastore


# Make the tests a bit less verbose by making some aliases:
ChangeWithBuild = innocent_cls_cq.ChangeWithBuild
GerritPatchTuple = clactions.GerritPatchTuple
DateTime = innocent_cls_cq_test.DateTime
FakeDatastoreClient = fake_datastore.FakeDatastoreClient


# pylint: disable=protected-access
class TestInnocentCLsPreCQ(cros_test_lib.MockTestCase):
  """Tests the innocent_cls module with a fake MySQL server."""

  default_build_values = {
      'builder_name': 'my builder',
      'buildbot_generation': constants.BUILDBOT_GENERATION,
      'waterfall': 'chromiumos',
      'build_config': 'a build config',
      'bot_hostname': 'bot hostname',
  }

  def setUp(self):
    """Sets up a fake datastore and some fake cidb data."""
    self.build_ids = []
    self.build_requests = []
    self.db = fake_cidb.FakeCIDBConnection()
    # datastore state is global. This resets its state between tests.
    # TODO(phobbs) make the datastore state a fixture object with a .Client()
    # method.
    FakeDatastoreClient.reset_store()
    self.ds = FakeDatastoreClient()
    self._SetupPreCQs()
    self.PatchObject(datastore, 'Client', lambda: self.ds)

  def _SetupPreCQs(self,
                   status=constants.BUILDER_STATUS_FAILED,
                   cl_number=1234):
    """Creates rows in cidb for a finalized BAD_CL annotation."""
    self.build_ids.append(
        self.db.InsertBuild(
            'test_build', 2, 'test_build', 'hostname', status=status))
    action_picked_up = clactions.CLAction.FromGerritPatchAndAction(
        GerritPatchTuple(cl_number, 1, True),
        constants.CL_ACTION_PICKED_UP)
    pre_cq_status = (
        constants.CL_ACTION_PRE_CQ_FAILED
        if status == constants.BUILDER_STATUS_FAILED
        # 'verified' is inserted when a CL passes a given pre-cq builder
        else constants.CL_ACTION_VERIFIED)
    action_failed = clactions.CLAction.FromGerritPatchAndAction(
        GerritPatchTuple(cl_number, 1, True),
        pre_cq_status)

    self.db.InsertCLActions(
        self.build_ids[-1], [action_picked_up, action_failed])

  def _InsertSanityBuild(self, status):
    self.build_ids.append(
        self.db.InsertBuild(
            'test_build', 1, 'test_build', 'hostname', status=status))
    now = datetime.datetime.now() + datetime.timedelta(seconds=1)
    self.build_requests.append(
        build_requests.BuildRequest(
            id=len(self.build_requests),
            build_id=self.build_ids[-1],
            request_build_config='test_build',
            request_build_args='',
            request_buildbucket_id='0',
            request_reason='sanity-pre-cq',
            timestamp=now))
    self.db.InsertBuildRequests([self.build_requests[-1]])

  def test_NewInnocentCLs(self):
    """An innocent CLs will get yielded."""
    self._InsertSanityBuild(constants.BUILDER_STATUS_FAILED)
    new_cls = list(innocent_cls_precq.NewInnocentCLs(self.db, True))
    assert new_cls == [
        [ChangeWithBuild(GerritPatchTuple(1234, 1, internal=True),
                         self.build_ids[0]),]
    ]

  def test_NewInnocentCLsWithNewerPreCQFailure(self):
    """If the CL was picked up after the failure, we don't exonerate."""
    self._InsertSanityBuild(constants.BUILDER_STATUS_FAILED)
    new_build_id = self.db.InsertBuild(
        'test_build', 1, 'test_build', 'hostname',
        status=constants.BUILDER_STATUS_PASSED)
    new_action = clactions.CLAction.FromGerritPatchAndAction(
        GerritPatchTuple(1234, 1, True),
        constants.CL_ACTION_PICKED_UP)

    self.db.InsertCLActions(new_build_id, [new_action])

    new_cls = list(innocent_cls_precq.NewInnocentCLs(self.db, True))
    assert len(new_cls) == 0

  def test_NewInnocentCLsAlreadyForgiven(self):
    """If we already forgave the build, we don't forgive it again."""
    self._InsertSanityBuild(constants.BUILDER_STATUS_FAILED)
    key = self.ds.key(
        innocent_cls_precq.PRECQ_PROCESSED_KEY, self.build_ids[0])
    last_run = datastore.Entity(key=key)
    last_run['1234'] = True
    self.ds.put(last_run)

    new_cls = list(innocent_cls_precq.NewInnocentCLs(self.db, True))
    assert new_cls == []

  def test_NewInnocentCLsCheckpointing(self):
    """Test that checkpointing works.

    We shouldn't get the same CLs back after requesting NewInnocentCLs more
    than once.
    """
    self._InsertSanityBuild(constants.BUILDER_STATUS_FAILED)
    first_pass = list(innocent_cls_precq.NewInnocentCLs(self.db, True))
    second_pass = list(innocent_cls_precq.NewInnocentCLs(self.db, True))
    third_pass = list(innocent_cls_precq.NewInnocentCLs(self.db, True))

    assert first_pass == [
        [ChangeWithBuild(
            GerritPatchTuple(1234, 1, internal=True),
            self.build_ids[0]),]
    ]
    assert second_pass == []
    assert third_pass == []

  def test_PassedSanityBuild(self):
    """If the sanity build passed, don't exonerate any CLs."""
    self._InsertSanityBuild(constants.BUILDER_STATUS_PASSED)
    got = list(innocent_cls_precq.NewInnocentCLs(self.db, True))
    assert got == []

  def test_AlreadyExonerated(self):
    """Don't re-exonerate a CL."""
    self._InsertSanityBuild(constants.BUILDER_STATUS_PASSED)
    action_exonerated = clactions.CLAction.FromGerritPatchAndAction(
        GerritPatchTuple(1234, 1, True),
        constants.CL_ACTION_EXONERATED)
    self.db.InsertCLActions(self.build_ids[0], [action_exonerated])

    got = list(innocent_cls_precq.NewInnocentCLs(self.db, True))
    assert got == []

  def test_NoSanity(self):
    """Test that no CLs are yielded when there isn't a sanity failure."""
    got = list(innocent_cls_precq.NewInnocentCLs(self.db, True))
    assert got == []

  def test_PreCQNaturalSanity(self):
    """Test a "natural" sanity build.

    A natural sanity failure is when a pre-CQ config fails and passes for the
    same patchset.
    """
    # TODO(phobbs) this doesn't do any real testing of the MySQL queries, which
    # are pretty complicated. Add an integration test which subclasses
    # cidb_integration_test.
    self._SetupPreCQs(status=constants.BUILDER_STATUS_PASSED)
    self._SetupPreCQs(cl_number=9999)
    self.PatchObject(
        innocent_cls_precq_flake,
        '_AffectedPreCQBuilds',
        _FakeAffectedPreCQBuilds)
    new_cls = list(innocent_cls_precq.NewInnocentCLs(self.db, True))
    assert new_cls == [
        [ChangeWithBuild(
            GerritPatchTuple(9999, 1, internal=True),
            self.build_ids[-1]),]
    ]


def _FakeAffectedPreCQBuilds(conn, config):
  """Finds the CLs with outstanding failures of |config|.

  Args:
    conn: A FakeCIDBConnection instance.
    config: A build config.

  Yields:
    Tuples of (GerritPatchTuple, build_id) which are the patchsets whose
    latest run of |config| was a failure.
  """
  actions_by_cl = _ActionsByCL(conn)
  builds_by_id = _BuildsById(conn)
  def _BuildForAction(action):
    """Returns the buildTable row associated with given the claction."""
    return builds_by_id[action['build_id']]

  cls_with_outstanding_failures = []
  for cl, actions in actions_by_cl.iteritems():
    actions_for_config = [
        a for a in actions
        if _BuildForAction(a)['build_config'] == config
    ]
    if not actions_for_config:
      continue
    latest_build = max(
        (_BuildForAction(action) for action in actions),
        key=lambda build: build['start_time'])

    actions_for_latest_build = [
        action for action in actions
        if action['build_id'] == latest_build['id']
    ]
    # for each patchset with actions relevant to |config|,
    # if the patchset's last action for |config| was a failure, include it.
    if any(a['action'] == constants.CL_ACTION_PRE_CQ_FAILED
           for a in actions_for_latest_build):
      cls_with_outstanding_failures.append((
          GerritPatchTuple(*cl), latest_build['id']))

  return cls_with_outstanding_failures


def _BuildsById(conn):
  """Returns a mapping of build ids to buildTable rows."""
  builds_by_id = {}
  for build in conn.buildTable:
    builds_by_id[build['id']] = build
  return builds_by_id


def _ActionsByCL(conn):
  """Returns groups of CLActions rows grouped by CL patchset."""
  actions_by_cl = {}
  for action in conn.clActionTable:
    k = (action['change_number'],
         action['patch_number'],
         action['change_source'] == 'internal')
    actions_by_cl.setdefault(k, []).append(action)
  return actions_by_cl
