binary_search_tool_tester.py revision 61ace4c75764cbab29bc0bcddf40d6c2d71996a6
1#!/usr/bin/python2 2 3# Copyright 2012 Google Inc. All Rights Reserved. 4"""Tests for bisecting tool.""" 5 6from __future__ import print_function 7 8__author__ = 'shenhan@google.com (Han Shen)' 9 10import os 11import random 12import sys 13import unittest 14 15from utils import command_executer 16from binary_search_tool import binary_search_state 17 18import common 19import gen_obj 20 21 22class BisectingUtilsTest(unittest.TestCase): 23 """Tests for bisecting tool.""" 24 25 def setUp(self): 26 """Generate [100-1000] object files, and 1-5% of which are bad ones.""" 27 obj_num = random.randint(100, 1000) 28 bad_obj_num = random.randint(obj_num / 100, obj_num / 20) 29 if bad_obj_num == 0: 30 bad_obj_num = 1 31 gen_obj.Main(['--obj_num', str(obj_num), '--bad_obj_num', str(bad_obj_num)]) 32 33 with open('./installed', 'w'): 34 pass 35 36 try: 37 os.remove(binary_search_state.STATE_FILE) 38 except OSError: 39 pass 40 41 def tearDown(self): 42 """Cleanup temp files.""" 43 os.remove(common.OBJECTS_FILE) 44 os.remove(common.WORKING_SET_FILE) 45 print('Deleted "{0}" and "{1}"'.format(common.OBJECTS_FILE, 46 common.WORKING_SET_FILE)) 47 try: 48 os.remove('./installed') 49 os.remove(os.readlink(binary_search_state.STATE_FILE)) 50 os.remove(binary_search_state.STATE_FILE) 51 except OSError: 52 pass 53 54 def runTest(self): 55 ret = binary_search_state.Run(get_initial_items='./gen_init_list.py', 56 switch_to_good='./switch_to_good.py', 57 switch_to_bad='./switch_to_bad.py', 58 test_script='./is_good.py', 59 prune=True, 60 file_args=True) 61 self.assertEquals(ret, 0) 62 self.check_output() 63 64 def test_arg_parse(self): 65 args = ['--get_initial_items', './gen_init_list.py', '--switch_to_good', 66 './switch_to_good.py', '--switch_to_bad', './switch_to_bad.py', 67 '--test_script', './is_good.py', '--prune', '--file_args'] 68 ret = binary_search_state.Main(args) 69 self.assertEquals(ret, 0) 70 self.check_output() 71 72 def test_install_script(self): 73 os.remove('./installed') 74 with self.assertRaises(AssertionError): 75 ret = binary_search_state.Run(get_initial_items='./gen_init_list.py', 76 switch_to_good='./switch_to_good.py', 77 switch_to_bad='./switch_to_bad.py', 78 test_script='./is_good.py', 79 prune=True, 80 file_args=True) 81 82 ret = binary_search_state.Run(get_initial_items='./gen_init_list.py', 83 switch_to_good='./switch_to_good.py', 84 switch_to_bad='./switch_to_bad.py', 85 test_script='./is_good.py', 86 install_script='./install.py', 87 prune=True, 88 file_args=True) 89 self.assertEquals(ret, 0) 90 self.check_output() 91 92 def test_bad_install_script(self): 93 with self.assertRaises(AssertionError): 94 binary_search_state.Run(get_initial_items='./gen_init_list.py', 95 switch_to_good='./switch_to_good.py', 96 switch_to_bad='./switch_to_bad.py', 97 test_script='./is_good.py', 98 install_script='./install_bad.py', 99 prune=True, 100 file_args=True) 101 102 def test_bad_save_state(self): 103 state_file = binary_search_state.STATE_FILE 104 hidden_state_file = os.path.basename(binary_search_state.HIDDEN_STATE_FILE) 105 106 with open(state_file, 'w') as f: 107 f.write('test123') 108 109 bss = binary_search_state.MockBinarySearchState() 110 with self.assertRaises(binary_search_state.Error): 111 bss.SaveState() 112 113 with open(state_file, 'r') as f: 114 self.assertEquals(f.read(), 'test123') 115 116 os.remove(state_file) 117 118 # Cleanup generated save state that has no symlink 119 files = os.listdir(os.getcwd()) 120 save_states = [x for x in files if x.startswith(hidden_state_file)] 121 _ = [os.remove(x) for x in save_states] 122 123 def test_save_state(self): 124 state_file = binary_search_state.STATE_FILE 125 126 bss = binary_search_state.MockBinarySearchState() 127 bss.SaveState() 128 self.assertTrue(os.path.exists(state_file)) 129 first_state = os.readlink(state_file) 130 131 bss.SaveState() 132 second_state = os.readlink(state_file) 133 self.assertTrue(os.path.exists(state_file)) 134 self.assertTrue(second_state != first_state) 135 self.assertFalse(os.path.exists(first_state)) 136 137 bss.RemoveState() 138 self.assertFalse(os.path.islink(state_file)) 139 self.assertFalse(os.path.exists(second_state)) 140 141 def test_load_state(self): 142 test_items = [1, 2, 3, 4, 5] 143 144 bss = binary_search_state.MockBinarySearchState() 145 bss.all_items = test_items 146 bss.SaveState() 147 148 bss = None 149 150 bss2 = binary_search_state.MockBinarySearchState.LoadState() 151 self.assertEquals(bss2.all_items, test_items) 152 153 def test_tmp_cleanup(self): 154 bss = binary_search_state.MockBinarySearchState( 155 get_initial_items='echo "0\n1\n2\n3"', 156 switch_to_good='./switch_tmp.py', 157 file_args=True) 158 bss.SwitchToGood(['0', '1', '2', '3']) 159 160 tmp_file = None 161 with open('tmp_file', 'r') as f: 162 tmp_file = f.read() 163 os.remove('tmp_file') 164 165 self.assertFalse(os.path.exists(tmp_file)) 166 ws = common.ReadWorkingSet() 167 for i in range(3): 168 self.assertEquals(ws[i], 42) 169 170 def check_output(self): 171 _, out, _ = command_executer.GetCommandExecuter().RunCommandWOutput( 172 ('grep "Bad items are: " logs/binary_search_tool_tester.py.out | ' 173 'tail -n1')) 174 ls = out.splitlines() 175 self.assertEqual(len(ls), 1) 176 line = ls[0] 177 178 _, _, bad_ones = line.partition('Bad items are: ') 179 bad_ones = bad_ones.split() 180 expected_result = common.ReadObjectsFile() 181 182 # Reconstruct objects file from bad_ones and compare 183 actual_result = [0] * len(expected_result) 184 for bad_obj in bad_ones: 185 actual_result[int(bad_obj)] = 1 186 187 self.assertEqual(actual_result, expected_result) 188 189 190def Main(argv): 191 num_tests = 2 192 if len(argv) > 1: 193 num_tests = int(argv[1]) 194 195 suite = unittest.TestSuite() 196 for _ in range(0, num_tests): 197 suite.addTest(BisectingUtilsTest()) 198 suite.addTest(BisectingUtilsTest('test_arg_parse')) 199 suite.addTest(BisectingUtilsTest('test_install_script')) 200 suite.addTest(BisectingUtilsTest('test_bad_install_script')) 201 suite.addTest(BisectingUtilsTest('test_bad_save_state')) 202 suite.addTest(BisectingUtilsTest('test_save_state')) 203 suite.addTest(BisectingUtilsTest('test_load_state')) 204 suite.addTest(BisectingUtilsTest('test_tmp_cleanup')) 205 runner = unittest.TextTestRunner() 206 runner.run(suite) 207 208 209if __name__ == '__main__': 210 Main(sys.argv) 211