1*795d594fSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*795d594fSAndroid Build Coastguard Worker# 3*795d594fSAndroid Build Coastguard Worker# Copyright (C) 2016 The Android Open Source Project 4*795d594fSAndroid Build Coastguard Worker# 5*795d594fSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*795d594fSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*795d594fSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*795d594fSAndroid Build Coastguard Worker# 9*795d594fSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*795d594fSAndroid Build Coastguard Worker# 11*795d594fSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*795d594fSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*795d594fSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*795d594fSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*795d594fSAndroid Build Coastguard Worker# limitations under the License. 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker"""Tests for bisection-search module.""" 18*795d594fSAndroid Build Coastguard Worker 19*795d594fSAndroid Build Coastguard Workerimport unittest 20*795d594fSAndroid Build Coastguard Worker 21*795d594fSAndroid Build Coastguard Workerfrom unittest.mock import Mock 22*795d594fSAndroid Build Coastguard Worker 23*795d594fSAndroid Build Coastguard Workerfrom bisection_search import BugSearch 24*795d594fSAndroid Build Coastguard Workerfrom bisection_search import Dex2OatWrapperTestable 25*795d594fSAndroid Build Coastguard Workerfrom bisection_search import FatalError 26*795d594fSAndroid Build Coastguard Workerfrom bisection_search import MANDATORY_PASSES 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Workerclass BisectionTestCase(unittest.TestCase): 30*795d594fSAndroid Build Coastguard Worker """BugSearch method test case. 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker Integer constants were chosen arbitrarily. They should be large enough and 33*795d594fSAndroid Build Coastguard Worker random enough to ensure binary search does nontrivial work. 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker Attributes: 36*795d594fSAndroid Build Coastguard Worker _METHODS: list of strings, methods compiled by testable 37*795d594fSAndroid Build Coastguard Worker _PASSES: list of strings, passes run by testable 38*795d594fSAndroid Build Coastguard Worker _FAILING_METHOD: string, name of method which fails in some tests 39*795d594fSAndroid Build Coastguard Worker _FAILING_PASS: string, name of pass which fails in some tests 40*795d594fSAndroid Build Coastguard Worker _MANDATORY_PASS: string, name of a mandatory pass 41*795d594fSAndroid Build Coastguard Worker """ 42*795d594fSAndroid Build Coastguard Worker _METHODS_COUNT = 1293 43*795d594fSAndroid Build Coastguard Worker _PASSES_COUNT = 573 44*795d594fSAndroid Build Coastguard Worker _FAILING_METHOD_IDX = 237 45*795d594fSAndroid Build Coastguard Worker _FAILING_PASS_IDX = 444 46*795d594fSAndroid Build Coastguard Worker _METHODS = ['method_{0}'.format(i) for i in range(_METHODS_COUNT)] 47*795d594fSAndroid Build Coastguard Worker _PASSES = ['pass_{0}'.format(i) for i in range(_PASSES_COUNT)] 48*795d594fSAndroid Build Coastguard Worker _FAILING_METHOD = _METHODS[_FAILING_METHOD_IDX] 49*795d594fSAndroid Build Coastguard Worker _FAILING_PASS = _PASSES[_FAILING_PASS_IDX] 50*795d594fSAndroid Build Coastguard Worker _MANDATORY_PASS = MANDATORY_PASSES[0] 51*795d594fSAndroid Build Coastguard Worker 52*795d594fSAndroid Build Coastguard Worker def setUp(self): 53*795d594fSAndroid Build Coastguard Worker self.testable_mock = Mock(spec=Dex2OatWrapperTestable) 54*795d594fSAndroid Build Coastguard Worker self.testable_mock.GetAllMethods.return_value = self._METHODS 55*795d594fSAndroid Build Coastguard Worker self.testable_mock.GetAllPassesForMethod.return_value = self._PASSES 56*795d594fSAndroid Build Coastguard Worker 57*795d594fSAndroid Build Coastguard Worker def MethodFailsForAllPasses(self, compiled_methods, run_passes=None): 58*795d594fSAndroid Build Coastguard Worker return self._FAILING_METHOD not in compiled_methods 59*795d594fSAndroid Build Coastguard Worker 60*795d594fSAndroid Build Coastguard Worker def MethodFailsForAPass(self, compiled_methods, run_passes=None): 61*795d594fSAndroid Build Coastguard Worker return (self._FAILING_METHOD not in compiled_methods or 62*795d594fSAndroid Build Coastguard Worker (run_passes is not None and self._FAILING_PASS not in run_passes)) 63*795d594fSAndroid Build Coastguard Worker 64*795d594fSAndroid Build Coastguard Worker def testNeverFails(self): 65*795d594fSAndroid Build Coastguard Worker self.testable_mock.Test.return_value = True 66*795d594fSAndroid Build Coastguard Worker res = BugSearch(self.testable_mock) 67*795d594fSAndroid Build Coastguard Worker self.assertEqual(res, (None, None)) 68*795d594fSAndroid Build Coastguard Worker 69*795d594fSAndroid Build Coastguard Worker def testAlwaysFails(self): 70*795d594fSAndroid Build Coastguard Worker self.testable_mock.Test.return_value = False 71*795d594fSAndroid Build Coastguard Worker with self.assertRaises(FatalError): 72*795d594fSAndroid Build Coastguard Worker BugSearch(self.testable_mock) 73*795d594fSAndroid Build Coastguard Worker 74*795d594fSAndroid Build Coastguard Worker def testAMethodFailsForAllPasses(self): 75*795d594fSAndroid Build Coastguard Worker self.testable_mock.Test.side_effect = self.MethodFailsForAllPasses 76*795d594fSAndroid Build Coastguard Worker res = BugSearch(self.testable_mock) 77*795d594fSAndroid Build Coastguard Worker self.assertEqual(res, (self._FAILING_METHOD, None)) 78*795d594fSAndroid Build Coastguard Worker 79*795d594fSAndroid Build Coastguard Worker def testAMethodFailsForAPass(self): 80*795d594fSAndroid Build Coastguard Worker self.testable_mock.Test.side_effect = self.MethodFailsForAPass 81*795d594fSAndroid Build Coastguard Worker res = BugSearch(self.testable_mock) 82*795d594fSAndroid Build Coastguard Worker self.assertEqual(res, (self._FAILING_METHOD, self._FAILING_PASS)) 83*795d594fSAndroid Build Coastguard Worker 84*795d594fSAndroid Build Coastguard Worker def testMandatoryPassPresent(self): 85*795d594fSAndroid Build Coastguard Worker self.testable_mock.GetAllPassesForMethod.return_value += ( 86*795d594fSAndroid Build Coastguard Worker [self._MANDATORY_PASS]) 87*795d594fSAndroid Build Coastguard Worker self.testable_mock.Test.side_effect = self.MethodFailsForAPass 88*795d594fSAndroid Build Coastguard Worker BugSearch(self.testable_mock) 89*795d594fSAndroid Build Coastguard Worker for (ordered_args, keyword_args) in self.testable_mock.Test.call_args_list: 90*795d594fSAndroid Build Coastguard Worker passes = None 91*795d594fSAndroid Build Coastguard Worker if 'run_passes' in keyword_args: 92*795d594fSAndroid Build Coastguard Worker passes = keyword_args['run_passes'] 93*795d594fSAndroid Build Coastguard Worker if len(ordered_args) > 1: # run_passes passed as ordered argument 94*795d594fSAndroid Build Coastguard Worker passes = ordered_args[1] 95*795d594fSAndroid Build Coastguard Worker if passes is not None: 96*795d594fSAndroid Build Coastguard Worker self.assertIn(self._MANDATORY_PASS, passes) 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Workerif __name__ == '__main__': 99*795d594fSAndroid Build Coastguard Worker unittest.main() 100