bisect_test.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. # Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. # Use of this source code is governed by a BSD-style license that can be
  3. # found in the LICENSE file.
  4. import unittest
  5. import subprocess
  6. bisect_builds = __import__('bisect-builds')
  7. class FakeProcess:
  8. called_num_times = 0
  9. def __init__(self, returncode):
  10. self.returncode = returncode
  11. FakeProcess.called_num_times += 1
  12. def communicate(self):
  13. return ('', '')
  14. class BisectTest(unittest.TestCase):
  15. patched = []
  16. max_rev = 10000
  17. fake_process_return_code = 0
  18. def monkey_patch(self, obj, name, new):
  19. self.patched.append((obj, name, getattr(obj, name)))
  20. setattr(obj, name, new)
  21. def clear_patching(self):
  22. for obj, name, old in self.patched:
  23. setattr(obj, name, old)
  24. self.patched = []
  25. def setUp(self):
  26. FakeProcess.called_num_times = 0
  27. self.fake_process_return_code = 0
  28. self.monkey_patch(bisect_builds.DownloadJob, 'Start', lambda *args: None)
  29. self.monkey_patch(bisect_builds.DownloadJob, 'Stop', lambda *args: None)
  30. self.monkey_patch(bisect_builds.DownloadJob, 'WaitFor', lambda *args: None)
  31. self.monkey_patch(bisect_builds, 'UnzipFilenameToDir', lambda *args: None)
  32. self.monkey_patch(
  33. subprocess, 'Popen',
  34. lambda *args, **kwargs: FakeProcess(self.fake_process_return_code))
  35. self.monkey_patch(bisect_builds.PathContext, 'ParseDirectoryIndex',
  36. lambda *args: range(self.max_rev))
  37. def tearDown(self):
  38. self.clear_patching()
  39. def bisect(self, good_rev, bad_rev, evaluate, num_runs=1):
  40. base_url = bisect_builds.CHROMIUM_BASE_URL
  41. archive = 'linux'
  42. asan = False
  43. use_local_cache = False
  44. context = bisect_builds.PathContext(base_url, archive, good_rev, bad_rev,
  45. asan, use_local_cache)
  46. (minrev, maxrev, _) = bisect_builds.Bisect(
  47. context=context,
  48. evaluate=evaluate,
  49. num_runs=num_runs,
  50. profile=None,
  51. try_args=[])
  52. return (minrev, maxrev)
  53. def testBisectConsistentAnswer(self):
  54. self.assertEqual(self.bisect(1000, 100, lambda *args: 'g'), (100, 101))
  55. self.assertEqual(self.bisect(100, 1000, lambda *args: 'b'), (100, 101))
  56. self.assertEqual(self.bisect(2000, 200, lambda *args: 'b'), (1999, 2000))
  57. self.assertEqual(self.bisect(200, 2000, lambda *args: 'g'), (1999, 2000))
  58. def testBisectMultipleRunsEarlyReturn(self):
  59. self.fake_process_return_code = 1
  60. self.assertEqual(self.bisect(1, 3, lambda *args: 'b', num_runs=10), (1, 2))
  61. self.assertEqual(FakeProcess.called_num_times, 1)
  62. def testBisectAllRunsWhenAllSucceed(self):
  63. self.assertEqual(self.bisect(1, 3, lambda *args: 'b', num_runs=10), (1, 2))
  64. self.assertEqual(FakeProcess.called_num_times, 10)
  65. if __name__ == '__main__':
  66. unittest.main()