1 #!/usr/bin/env python2 2 """Run full bisection test.""" 3 4 from __future__ import print_function 5 6 import argparse 7 import os 8 import sys 9 10 from cros_utils import command_executer 11 12 TEST_DIR = 'full_bisect_test' 13 DEFAULT_BISECT_DIR = '/tmp/sysroot_bisect' 14 15 16 def populate_good_files(top_dir, ce, bisect_dir=DEFAULT_BISECT_DIR): 17 # 'make clean' 18 work_dir = os.path.join(top_dir, TEST_DIR, 'work') 19 cmd = 'rm -f %s/*.o' % work_dir 20 status = ce.RunCommand(cmd) 21 if status != 0: 22 print('Error trying to clean out work directory: %s' % cmd) 23 return status 24 25 # set up the 'good' source files 26 script = os.path.join(top_dir, TEST_DIR, 'make_sources_good.sh') 27 status = ce.RunCommand(script) 28 if status != 0: 29 print('Error setting up "good" source files: %s' % script) 30 return status 31 32 export_bisect = 'export BISECT_DIR=%s; ' % bisect_dir 33 # build the good source files 34 script_path = os.path.join(top_dir, TEST_DIR) 35 if os.path.exists('/usr/bin/x86_64-cros-linux-gnu-gcc'): 36 build_script = 'chromeos_build.sh' 37 else: 38 build_script = 'build.sh' 39 cmd = ('%s export BISECT_STAGE=POPULATE_GOOD; pushd %s; ./%s; popd' % 40 (export_bisect, script_path, build_script)) 41 status = ce.RunCommand(cmd) 42 return status 43 44 45 def populate_bad_files(top_dir, ce, bisect_dir=DEFAULT_BISECT_DIR): 46 # 'make clean' 47 work_dir = os.path.join(top_dir, TEST_DIR, 'work') 48 cmd = 'rm -f %s/*.o' % work_dir 49 status = ce.RunCommand(cmd) 50 if status != 0: 51 print('Error trying to clean out work directory: %s' % cmd) 52 return status 53 54 # set up the 'bad' source files 55 script = os.path.join(top_dir, TEST_DIR, 'make_sources_bad.sh') 56 status = ce.RunCommand(script) 57 if status != 0: 58 print('Error setting up "bad" source files: %s' % script) 59 return status 60 61 export_bisect = 'export BISECT_DIR=%s; ' % bisect_dir 62 # build the bad source files 63 script_path = os.path.join(top_dir, TEST_DIR) 64 if os.path.exists('/usr/bin/x86_64-cros-linux-gnu-gcc'): 65 build_script = 'chromeos_build.sh' 66 else: 67 build_script = 'build.sh' 68 cmd = ('%s export BISECT_STAGE=POPULATE_BAD; pushd %s; ./%s ; popd' % 69 (export_bisect, script_path, build_script)) 70 status = ce.RunCommand(cmd) 71 return status 72 73 74 def run_main_bisection_test(top_dir, ce): 75 test_script = os.path.join(top_dir, TEST_DIR, 'main-bisect-test.sh') 76 status = ce.RunCommand(test_script) 77 return status 78 79 80 def verify_compiler_and_wrapper(): 81 # We don't need to do any special setup if running inside a ChromeOS 82 # chroot. 83 if os.path.exists('/usr/bin/x86_64-cros-linux-gnu-gcc'): 84 return 85 86 message = """ 87 *** IMPORTANT --- READ THIS CAREFULLY!! *** 88 89 This test uses the command 'gcc' to compile the good/bad versions of the 90 source program. BEFORE you can run this script you must make sure that 91 your compiler wrapper is in the right place, with the right name, so that 92 a call to 'gcc' will go through your compiler wrapper and "do the right 93 thing". 94 95 Is your compiler wrapper properly set up? [Y/n] 96 """ 97 98 print(message) 99 inp = sys.stdin.readline() 100 inp = inp.strip() 101 inp = inp.lower() 102 return not inp or inp == 'y' or inp == 'yes' 103 104 105 def Main(argv): 106 parser = argparse.ArgumentParser() 107 parser.add_argument( 108 '--dir', 109 dest='directory', 110 help='Bisection work tree, where good & bad object ' 111 'files go. Default is /tmp/sysroot_bisect') 112 113 options = parser.parse_args(argv) 114 115 # Make sure the compiler wrapper & soft links are properly set up. 116 wrapper_is_setup = verify_compiler_and_wrapper() 117 if not wrapper_is_setup: 118 print('Exiting now. Please re-run after you have set up the compiler ' 119 'wrapper.') 120 return 0 121 122 # Make sure we're in the correct directory for running this test. 123 cwd = os.getcwd() 124 if not os.path.exists(os.path.join(cwd, 'full_bisect_test')): 125 print('Error: Wrong directory. This script must be run from the top level' 126 ' of the binary_search_tool tree (under toolchain_utils).') 127 return 1 128 129 ce = command_executer.GetCommandExecuter() 130 bisect_dir = options.directory 131 if not bisect_dir: 132 bisect_dir = DEFAULT_BISECT_DIR 133 134 # Make sure BISECT_DIR is clean 135 if os.path.exists(bisect_dir): 136 cmd = 'rm -Rf %s/*' % bisect_dir 137 retv = ce.RunCommand(cmd) 138 if retv != 0: 139 return retv 140 141 retv = populate_good_files(cwd, ce, bisect_dir) 142 if retv != 0: 143 return retv 144 145 retv = populate_bad_files(cwd, ce, bisect_dir) 146 if retv != 0: 147 return retv 148 149 # Set up good/bad work soft links 150 cmd = ('rm -f %s/%s/good-objects; ln -s %s/good %s/%s/good-objects' % 151 (cwd, TEST_DIR, bisect_dir, cwd, TEST_DIR)) 152 153 status = ce.RunCommand(cmd) 154 if status != 0: 155 print('Error executing: %s; exiting now.' % cmd) 156 return status 157 158 cmd = ('rm -f %s/%s/bad-objects; ln -s %s/bad %s/%s/bad-objects' % 159 (cwd, TEST_DIR, bisect_dir, cwd, TEST_DIR)) 160 161 status = ce.RunCommand(cmd) 162 if status != 0: 163 print('Error executing: %s; exiting now.' % cmd) 164 return status 165 166 retv = run_main_bisection_test(cwd, ce) 167 return retv 168 169 170 if __name__ == '__main__': 171 retval = Main(sys.argv[1:]) 172 sys.exit(retval) 173