#!/usr/bin/env python3
#
# Copyright (C) 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tests for bisection-search module."""

import unittest

from unittest.mock import Mock

from bisection_search import BugSearch
from bisection_search import Dex2OatWrapperTestable
from bisection_search import FatalError
from bisection_search import MANDATORY_PASSES


class BisectionTestCase(unittest.TestCase):
  """BugSearch method test case.

  Integer constants were chosen arbitrarily. They should be large enough and
  random enough to ensure binary search does nontrivial work.

  Attributes:
    _METHODS: list of strings, methods compiled by testable
    _PASSES: list of strings, passes run by testable
    _FAILING_METHOD: string, name of method which fails in some tests
    _FAILING_PASS: string, name of pass which fails in some tests
    _MANDATORY_PASS: string, name of a mandatory pass
  """
  _METHODS_COUNT = 1293
  _PASSES_COUNT = 573
  _FAILING_METHOD_IDX = 237
  _FAILING_PASS_IDX = 444
  _METHODS = ['method_{0}'.format(i) for i in range(_METHODS_COUNT)]
  _PASSES = ['pass_{0}'.format(i) for i in range(_PASSES_COUNT)]
  _FAILING_METHOD = _METHODS[_FAILING_METHOD_IDX]
  _FAILING_PASS = _PASSES[_FAILING_PASS_IDX]
  _MANDATORY_PASS = MANDATORY_PASSES[0]

  def setUp(self):
    self.testable_mock = Mock(spec=Dex2OatWrapperTestable)
    self.testable_mock.GetAllMethods.return_value = self._METHODS
    self.testable_mock.GetAllPassesForMethod.return_value = self._PASSES

  def MethodFailsForAllPasses(self, compiled_methods, run_passes=None):
    return self._FAILING_METHOD not in compiled_methods

  def MethodFailsForAPass(self, compiled_methods, run_passes=None):
    return (self._FAILING_METHOD not in compiled_methods or
            (run_passes is not None and self._FAILING_PASS not in run_passes))

  def testNeverFails(self):
    self.testable_mock.Test.return_value = True
    res = BugSearch(self.testable_mock)
    self.assertEqual(res, (None, None))

  def testAlwaysFails(self):
    self.testable_mock.Test.return_value = False
    with self.assertRaises(FatalError):
      BugSearch(self.testable_mock)

  def testAMethodFailsForAllPasses(self):
    self.testable_mock.Test.side_effect = self.MethodFailsForAllPasses
    res = BugSearch(self.testable_mock)
    self.assertEqual(res, (self._FAILING_METHOD, None))

  def testAMethodFailsForAPass(self):
    self.testable_mock.Test.side_effect = self.MethodFailsForAPass
    res = BugSearch(self.testable_mock)
    self.assertEqual(res, (self._FAILING_METHOD, self._FAILING_PASS))

  def testMandatoryPassPresent(self):
    self.testable_mock.GetAllPassesForMethod.return_value += (
        [self._MANDATORY_PASS])
    self.testable_mock.Test.side_effect = self.MethodFailsForAPass
    BugSearch(self.testable_mock)
    for (ordered_args, keyword_args) in self.testable_mock.Test.call_args_list:
      passes = None
      if 'run_passes' in keyword_args:
        passes = keyword_args['run_passes']
      if len(ordered_args) > 1:  # run_passes passed as ordered argument
        passes = ordered_args[1]
      if passes is not None:
        self.assertIn(self._MANDATORY_PASS, passes)

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