#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS 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()
