diff options
-rwxr-xr-x | binary_search_tool/binary_search_state.py | 6 | ||||
-rwxr-xr-x | binary_search_tool/test/binary_search_tool_tester.py | 56 | ||||
-rwxr-xr-x | binary_search_tool/test/gen_obj.py | 40 |
3 files changed, 89 insertions, 13 deletions
diff --git a/binary_search_tool/binary_search_state.py b/binary_search_tool/binary_search_state.py index 62acd759..ef276fab 100755 --- a/binary_search_tool/binary_search_state.py +++ b/binary_search_tool/binary_search_state.py @@ -222,6 +222,12 @@ class BinarySearchState(object): # Prune is set. prune_index = self.binary_search.current + # If found item is last item, no new items can be found + if prune_index == len(self.all_items) - 1: + self.l.LogOutput('First bad item is the last item. Breaking.') + self.l.LogOutput('Bad items are: %s' % self.all_items[-1]) + break + # If already seen item we have no new bad items to find, finish up if self.all_items[prune_index] in self.found_items: self.l.LogOutput(('Found item already found before: %s. ' diff --git a/binary_search_tool/test/binary_search_tool_tester.py b/binary_search_tool/test/binary_search_tool_tester.py index 8488e9e0..4ec920b8 100755 --- a/binary_search_tool/test/binary_search_tool_tester.py +++ b/binary_search_tool/test/binary_search_tool_tester.py @@ -336,6 +336,60 @@ class BisectingUtilsTest(unittest.TestCase): self.assertEqual(actual_result, expected_result) +class BisectStressTest(unittest.TestCase): + """Stress tests for bisecting tool.""" + + def test_every_obj_bad(self): + amt = 25 + gen_obj.Main(['--obj_num', str(amt), '--bad_obj_num', str(amt)]) + ret = binary_search_state.Run(get_initial_items='./gen_init_list.py', + switch_to_good='./switch_to_good.py', + switch_to_bad='./switch_to_bad.py', + test_script='./is_good.py', + prune=True, + file_args=True, + verify_level=0) + self.assertEquals(ret, 0) + self.check_output() + + def test_every_index_is_bad(self): + amt = 25 + for i in range(amt): + obj_list = ['0'] * amt + obj_list[i] = '1' + obj_list = ','.join(obj_list) + gen_obj.Main(['--obj_list', obj_list]) + ret = binary_search_state.Run(get_initial_items='./gen_init_list.py', + switch_to_good='./switch_to_good.py', + switch_to_bad='./switch_to_bad.py', + install_script='./install.py', + test_script='./is_good.py', + prune=True, + file_args=True) + self.assertEquals(ret, 0) + self.check_output() + + + def check_output(self): + _, out, _ = command_executer.GetCommandExecuter().RunCommandWOutput( + ('grep "Bad items are: " logs/binary_search_tool_tester.py.out | ' + 'tail -n1')) + ls = out.splitlines() + self.assertEqual(len(ls), 1) + line = ls[0] + + _, _, bad_ones = line.partition('Bad items are: ') + bad_ones = bad_ones.split() + expected_result = common.ReadObjectsFile() + + # Reconstruct objects file from bad_ones and compare + actual_result = [0] * len(expected_result) + for bad_obj in bad_ones: + actual_result[int(bad_obj)] = 1 + + self.assertEqual(actual_result, expected_result) + + def Main(argv): num_tests = 2 if len(argv) > 1: @@ -357,6 +411,8 @@ def Main(argv): suite.addTest(BisectingUtilsTest('test_set_file')) suite.addTest(BisectingUtilsTest('test_noincremental_prune')) suite.addTest(BisectTest('test_full_bisector')) + suite.addTest(BisectStressTest('test_every_obj_bad')) + suite.addTest(BisectStressTest('test_every_index_is_bad')) runner = unittest.TextTestRunner() runner.run(suite) diff --git a/binary_search_tool/test/gen_obj.py b/binary_search_tool/test/gen_obj.py index 6fb9a908..1c060e01 100755 --- a/binary_search_tool/test/gen_obj.py +++ b/binary_search_tool/test/gen_obj.py @@ -40,23 +40,34 @@ def Main(argv): help=('Number of bad objects. Must be great than or ' 'equal to zero and less than total object ' 'number.')) + parser.add_argument('-o', + '--obj_list', + dest='obj_list', + default='', + help=('List of comma seperated objects to generate. ' + 'A 0 means the object is good, a 1 means the ' + 'object is bad.')) options = parser.parse_args(argv) obj_num = int(options.obj_num) bad_obj_num = int(options.bad_obj_num) bad_to_gen = int(options.bad_obj_num) - obj_list = [] - for i in range(obj_num): - if bad_to_gen > 0 and random.randint(1, obj_num) <= bad_obj_num: - obj_list.append(1) - bad_to_gen -= 1 - else: - obj_list.append(0) - while bad_to_gen > 0: - t = random.randint(0, obj_num - 1) - if obj_list[t] == 0: - obj_list[t] = 1 - bad_to_gen -= 1 + obj_list = options.obj_list + if not obj_list: + obj_list = [] + for i in range(obj_num): + if bad_to_gen > 0 and random.randint(1, obj_num) <= bad_obj_num: + obj_list.append(1) + bad_to_gen -= 1 + else: + obj_list.append(0) + while bad_to_gen > 0: + t = random.randint(0, obj_num - 1) + if obj_list[t] == 0: + obj_list[t] = 1 + bad_to_gen -= 1 + else: + obj_list = obj_list.split(',') if os.path.isfile(common.OBJECTS_FILE): os.remove(common.OBJECTS_FILE) @@ -70,8 +81,11 @@ def Main(argv): w.write('{0}\n'.format(i)) f.close() + obj_num = len(obj_list) + bad_obj_num = obj_list.count('1') print('Generated {0} object files, with {1} bad ones.'.format( - options.obj_num, options.bad_obj_num)) + obj_num, bad_obj_num)) + return 0 |