Home | History | Annotate | Download | only in binary_search_tool
      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