| # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import unittest |
| import subprocess |
| |
| bisect_builds = __import__('bisect-builds') |
| |
| |
| class FakeProcess: |
| called_num_times = 0 |
| |
| def __init__(self, returncode): |
| self.returncode = returncode |
| FakeProcess.called_num_times += 1 |
| |
| def communicate(self): |
| return ('', '') |
| |
| |
| class BisectTest(unittest.TestCase): |
| |
| patched = [] |
| max_rev = 10000 |
| fake_process_return_code = 0 |
| |
| def monkey_patch(self, obj, name, new): |
| self.patched.append((obj, name, getattr(obj, name))) |
| setattr(obj, name, new) |
| |
| def clear_patching(self): |
| for obj, name, old in self.patched: |
| setattr(obj, name, old) |
| self.patched = [] |
| |
| def setUp(self): |
| FakeProcess.called_num_times = 0 |
| self.fake_process_return_code = 0 |
| self.monkey_patch(bisect_builds.DownloadJob, 'Start', lambda *args: None) |
| self.monkey_patch(bisect_builds.DownloadJob, 'Stop', lambda *args: None) |
| self.monkey_patch(bisect_builds.DownloadJob, 'WaitFor', lambda *args: None) |
| self.monkey_patch(bisect_builds, 'UnzipFilenameToDir', lambda *args: None) |
| self.monkey_patch( |
| subprocess, 'Popen', |
| lambda *args, **kwargs: FakeProcess(self.fake_process_return_code)) |
| self.monkey_patch(bisect_builds.PathContext, 'ParseDirectoryIndex', |
| lambda *args: range(self.max_rev)) |
| |
| def tearDown(self): |
| self.clear_patching() |
| |
| def bisect(self, good_rev, bad_rev, evaluate, num_runs=1): |
| base_url = bisect_builds.CHROMIUM_BASE_URL |
| archive = 'linux' |
| asan = False |
| use_local_cache = False |
| context = bisect_builds.PathContext(base_url, archive, good_rev, bad_rev, |
| asan, use_local_cache) |
| (minrev, maxrev, _) = bisect_builds.Bisect( |
| context=context, |
| evaluate=evaluate, |
| num_runs=num_runs, |
| profile=None, |
| try_args=[]) |
| return (minrev, maxrev) |
| |
| def testBisectConsistentAnswer(self): |
| self.assertEqual(self.bisect(1000, 100, lambda *args: 'g'), (100, 101)) |
| self.assertEqual(self.bisect(100, 1000, lambda *args: 'b'), (100, 101)) |
| self.assertEqual(self.bisect(2000, 200, lambda *args: 'b'), (1999, 2000)) |
| self.assertEqual(self.bisect(200, 2000, lambda *args: 'g'), (1999, 2000)) |
| |
| def testBisectMultipleRunsEarlyReturn(self): |
| self.fake_process_return_code = 1 |
| self.assertEqual(self.bisect(1, 3, lambda *args: 'b', num_runs=10), (1, 2)) |
| self.assertEqual(FakeProcess.called_num_times, 1) |
| |
| def testBisectAllRunsWhenAllSucceed(self): |
| self.assertEqual(self.bisect(1, 3, lambda *args: 'b', num_runs=10), (1, 2)) |
| self.assertEqual(FakeProcess.called_num_times, 10) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |