#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2019 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 modifying a tryjob."""

from __future__ import print_function

import json
import unittest
import unittest.mock as mock

import get_llvm_hash
import modify_a_tryjob
import test_helpers
import update_packages_and_run_tests
import update_tryjob_status


class ModifyATryjobTest(unittest.TestCase):
  """Unittests for modifying a tryjob."""

  def testNoTryjobsInStatusFile(self):
    bisect_test_contents = {'start': 369410, 'end': 369420, 'jobs': []}

    # Create a temporary .JSON file to simulate a .JSON file that has bisection
    # contents.
    with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
      with open(temp_json_file, 'w') as f:
        test_helpers.WritePrettyJsonFile(bisect_test_contents, f)

      revision_to_modify = 369411

      args_output = test_helpers.ArgsOutputTest()
      args_output.builders = None
      args_output.options = None

      # Verify the exception is raised there are no tryjobs in the status file
      # and the mode is not to 'add' a tryjob.
      with self.assertRaises(SystemExit) as err:
        modify_a_tryjob.PerformTryjobModification(
            revision_to_modify, modify_a_tryjob.ModifyTryjob.REMOVE,
            temp_json_file, args_output.extra_change_lists, args_output.options,
            args_output.builders, args_output.chroot_path, args_output.verbose)

      self.assertEqual(str(err.exception), 'No tryjobs in %s' % temp_json_file)

  # Simulate the behavior of `FindTryjobIndex()` when the index of the tryjob
  # was not found.
  @mock.patch.object(update_tryjob_status, 'FindTryjobIndex', return_value=None)
  def testNoTryjobIndexFound(self, mock_find_tryjob_index):
    bisect_test_contents = {
        'start': 369410,
        'end': 369420,
        'jobs': [{
            'rev': 369411,
            'status': 'pending',
            'buildbucket_id': 1200
        }]
    }

    # Create a temporary .JSON file to simulate a .JSON file that has bisection
    # contents.
    with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
      with open(temp_json_file, 'w') as f:
        test_helpers.WritePrettyJsonFile(bisect_test_contents, f)

      revision_to_modify = 369412

      args_output = test_helpers.ArgsOutputTest()
      args_output.builders = None
      args_output.options = None

      # Verify the exception is raised when the index of the tryjob was not
      # found in the status file and the mode is not to 'add' a tryjob.
      with self.assertRaises(ValueError) as err:
        modify_a_tryjob.PerformTryjobModification(
            revision_to_modify, modify_a_tryjob.ModifyTryjob.REMOVE,
            temp_json_file, args_output.extra_change_lists, args_output.options,
            args_output.builders, args_output.chroot_path, args_output.verbose)

      self.assertEqual(
          str(err.exception), 'Unable to find tryjob for %d in %s' %
          (revision_to_modify, temp_json_file))

    mock_find_tryjob_index.assert_called_once()

  # Simulate the behavior of `FindTryjobIndex()` when the index of the tryjob
  # was found.
  @mock.patch.object(update_tryjob_status, 'FindTryjobIndex', return_value=0)
  def testSuccessfullyRemovedTryjobInStatusFile(self, mock_find_tryjob_index):
    bisect_test_contents = {
        'start': 369410,
        'end': 369420,
        'jobs': [{
            'rev': 369414,
            'status': 'pending',
            'buildbucket_id': 1200
        }]
    }

    # Create a temporary .JSON file to simulate a .JSON file that has bisection
    # contents.
    with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
      with open(temp_json_file, 'w') as f:
        test_helpers.WritePrettyJsonFile(bisect_test_contents, f)

      revision_to_modify = 369414

      args_output = test_helpers.ArgsOutputTest()
      args_output.builders = None
      args_output.options = None

      modify_a_tryjob.PerformTryjobModification(
          revision_to_modify, modify_a_tryjob.ModifyTryjob.REMOVE,
          temp_json_file, args_output.extra_change_lists, args_output.options,
          args_output.builders, args_output.chroot_path, args_output.verbose)

      # Verify that the tryjob was removed from the status file.
      with open(temp_json_file) as status_file:
        bisect_contents = json.load(status_file)

        expected_file_contents = {'start': 369410, 'end': 369420, 'jobs': []}

        self.assertDictEqual(bisect_contents, expected_file_contents)

    mock_find_tryjob_index.assert_called_once()

  # Simulate the behavior of `RunTryJobs()` when successfully submitted a
  # tryjob.
  @mock.patch.object(update_packages_and_run_tests, 'RunTryJobs')
  # Simulate the behavior of `FindTryjobIndex()` when the index of the tryjob
  # was found.
  @mock.patch.object(update_tryjob_status, 'FindTryjobIndex', return_value=0)
  def testSuccessfullyRelaunchedTryjob(self, mock_find_tryjob_index,
                                       mock_run_tryjob):

    bisect_test_contents = {
        'start':
            369410,
        'end':
            369420,
        'jobs': [{
            'rev': 369411,
            'status': 'bad',
            'link': 'https://some_tryjob_link.com',
            'buildbucket_id': 1200,
            'cl': 123,
            'extra_cls': None,
            'options': None,
            'builder': ['some-builder-tryjob']
        }]
    }

    tryjob_result = [{
        'link': 'https://some_new_tryjob_link.com',
        'buildbucket_id': 20
    }]

    mock_run_tryjob.return_value = tryjob_result

    # Create a temporary .JSON file to simulate a .JSON file that has bisection
    # contents.
    with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
      with open(temp_json_file, 'w') as f:
        test_helpers.WritePrettyJsonFile(bisect_test_contents, f)

      revision_to_modify = 369411

      args_output = test_helpers.ArgsOutputTest()
      args_output.builders = None
      args_output.options = None

      modify_a_tryjob.PerformTryjobModification(
          revision_to_modify, modify_a_tryjob.ModifyTryjob.RELAUNCH,
          temp_json_file, args_output.extra_change_lists, args_output.options,
          args_output.builders, args_output.chroot_path, args_output.verbose)

      # Verify that the tryjob's information was updated after submtting the
      # tryjob.
      with open(temp_json_file) as status_file:
        bisect_contents = json.load(status_file)

        expected_file_contents = {
            'start':
                369410,
            'end':
                369420,
            'jobs': [{
                'rev': 369411,
                'status': 'pending',
                'link': 'https://some_new_tryjob_link.com',
                'buildbucket_id': 20,
                'cl': 123,
                'extra_cls': None,
                'options': None,
                'builder': ['some-builder-tryjob']
            }]
        }

        self.assertDictEqual(bisect_contents, expected_file_contents)

    mock_find_tryjob_index.assert_called_once()

    mock_run_tryjob.assert_called_once()

  # Simulate the behavior of `FindTryjobIndex()` when the index of the tryjob
  # was found.
  @mock.patch.object(update_tryjob_status, 'FindTryjobIndex', return_value=0)
  def testAddingTryjobThatAlreadyExists(self, mock_find_tryjob_index):
    bisect_test_contents = {
        'start': 369410,
        'end': 369420,
        'jobs': [{
            'rev': 369411,
            'status': 'bad',
            'builder': ['some-builder']
        }]
    }

    # Create a temporary .JSON file to simulate a .JSON file that has bisection
    # contents.
    with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
      with open(temp_json_file, 'w') as f:
        test_helpers.WritePrettyJsonFile(bisect_test_contents, f)

      revision_to_add = 369411

      # Index of the tryjob in 'jobs' list.
      tryjob_index = 0

      args_output = test_helpers.ArgsOutputTest()
      args_output.options = None

      # Verify the exception is raised when the tryjob that is going to added
      # already exists in the status file (found its index).
      with self.assertRaises(ValueError) as err:
        modify_a_tryjob.PerformTryjobModification(
            revision_to_add, modify_a_tryjob.ModifyTryjob.ADD, temp_json_file,
            args_output.extra_change_lists, args_output.options,
            args_output.builders, args_output.chroot_path, args_output.verbose)

      self.assertEqual(
          str(err.exception), 'Tryjob already exists (index is %d) in %s.' %
          (tryjob_index, temp_json_file))

    mock_find_tryjob_index.assert_called_once()

  # Simulate the behavior of `FindTryjobIndex()` when the tryjob was not found.
  @mock.patch.object(update_tryjob_status, 'FindTryjobIndex', return_value=None)
  def testSuccessfullyDidNotAddTryjobOutsideOfBisectionBounds(
      self, mock_find_tryjob_index):

    bisect_test_contents = {
        'start': 369410,
        'end': 369420,
        'jobs': [{
            'rev': 369411,
            'status': 'bad'
        }]
    }

    # Create a temporary .JSON file to simulate a .JSON file that has bisection
    # contents.
    with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
      with open(temp_json_file, 'w') as f:
        test_helpers.WritePrettyJsonFile(bisect_test_contents, f)

      # Add a revision that is outside of 'start' and 'end'.
      revision_to_add = 369450

      args_output = test_helpers.ArgsOutputTest()
      args_output.options = None

      # Verify the exception is raised when adding a tryjob that does not exist
      # and is not within 'start' and 'end'.
      with self.assertRaises(ValueError) as err:
        modify_a_tryjob.PerformTryjobModification(
            revision_to_add, modify_a_tryjob.ModifyTryjob.ADD, temp_json_file,
            args_output.extra_change_lists, args_output.options,
            args_output.builders, args_output.chroot_path, args_output.verbose)

      self.assertEqual(
          str(err.exception), 'Failed to add tryjob to %s' % temp_json_file)

    mock_find_tryjob_index.assert_called_once()

  # Simulate the behavior of `AddTryjob()` when successfully submitted the
  # tryjob and constructed the tryjob information (a dictionary).
  @mock.patch.object(modify_a_tryjob, 'AddTryjob')
  # Simulate the behavior of `GetLLVMHashAndVersionFromSVNOption()` when
  # successfully retrieved the git hash of the revision to launch a tryjob for.
  @mock.patch.object(
      get_llvm_hash,
      'GetLLVMHashAndVersionFromSVNOption',
      return_value=('a123testhash1', 369418))
  # Simulate the behavior of `FindTryjobIndex()` when the tryjob was not found.
  @mock.patch.object(update_tryjob_status, 'FindTryjobIndex', return_value=None)
  def testSuccessfullyAddedTryjob(self, mock_find_tryjob_index,
                                  mock_get_llvm_hash, mock_add_tryjob):

    bisect_test_contents = {
        'start': 369410,
        'end': 369420,
        'jobs': [{
            'rev': 369411,
            'status': 'bad'
        }]
    }

    # Create a temporary .JSON file to simulate a .JSON file that has bisection
    # contents.
    with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
      with open(temp_json_file, 'w') as f:
        test_helpers.WritePrettyJsonFile(bisect_test_contents, f)

      # Add a revision that is outside of 'start' and 'end'.
      revision_to_add = 369418

      args_output = test_helpers.ArgsOutputTest()
      args_output.options = None

      new_tryjob_info = {
          'rev': revision_to_add,
          'status': 'pending',
          'options': args_output.options,
          'extra_cls': args_output.extra_change_lists,
          'builder': args_output.builders
      }

      mock_add_tryjob.return_value = new_tryjob_info

      modify_a_tryjob.PerformTryjobModification(
          revision_to_add, modify_a_tryjob.ModifyTryjob.ADD, temp_json_file,
          args_output.extra_change_lists, args_output.options,
          args_output.builders, args_output.chroot_path, args_output.verbose)

      # Verify that the tryjob was added to the status file.
      with open(temp_json_file) as status_file:
        bisect_contents = json.load(status_file)

        expected_file_contents = {
            'start': 369410,
            'end': 369420,
            'jobs': [{
                'rev': 369411,
                'status': 'bad'
            }, new_tryjob_info]
        }

        self.assertDictEqual(bisect_contents, expected_file_contents)

    mock_find_tryjob_index.assert_called_once()

    mock_get_llvm_hash.assert_called_once_with(revision_to_add)

    mock_add_tryjob.assert_called_once()

  # Simulate the behavior of `FindTryjobIndex()` when the tryjob was found.
  @mock.patch.object(update_tryjob_status, 'FindTryjobIndex', return_value=0)
  def testModifyATryjobOptionDoesNotExist(self, mock_find_tryjob_index):
    bisect_test_contents = {
        'start': 369410,
        'end': 369420,
        'jobs': [{
            'rev': 369414,
            'status': 'bad'
        }]
    }

    # Create a temporary .JSON file to simulate a .JSON file that has bisection
    # contents.
    with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
      with open(temp_json_file, 'w') as f:
        test_helpers.WritePrettyJsonFile(bisect_test_contents, f)

      # Add a revision that is outside of 'start' and 'end'.
      revision_to_modify = 369414

      args_output = test_helpers.ArgsOutputTest()
      args_output.builders = None
      args_output.options = None

      # Verify the exception is raised when the modify a tryjob option does not
      # exist.
      with self.assertRaises(ValueError) as err:
        modify_a_tryjob.PerformTryjobModification(
            revision_to_modify, 'remove_link', temp_json_file,
            args_output.extra_change_lists, args_output.options,
            args_output.builders, args_output.chroot_path, args_output.verbose)

      self.assertEqual(
          str(err.exception),
          'Invalid "modify_tryjob" option provided: remove_link')

      mock_find_tryjob_index.assert_called_once()


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