1#!/usr/bin/env python2 2"""Run full bisection test.""" 3 4from __future__ import print_function 5 6import argparse 7import os 8import sys 9 10from cros_utils import command_executer 11 12TEST_DIR = 'full_bisect_test' 13DEFAULT_BISECT_DIR = '/tmp/sysroot_bisect' 14 15 16def 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 45def 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 74def 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 80def 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 89This test uses the command 'gcc' to compile the good/bad versions of the 90source program. BEFORE you can run this script you must make sure that 91your compiler wrapper is in the right place, with the right name, so that 92a call to 'gcc' will go through your compiler wrapper and "do the right 93thing". 94 95Is 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 105def 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 170if __name__ == '__main__': 171 retval = Main(sys.argv[1:]) 172 sys.exit(retval) 173