You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
5.5 KiB
199 lines
5.5 KiB
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
# Copyright 2020 The ChromiumOS Authors
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
"""Run full bisection test."""
|
|
|
|
|
|
import argparse
|
|
import os
|
|
import sys
|
|
|
|
from cros_utils import command_executer
|
|
|
|
|
|
TEST_DIR = "full_bisect_test"
|
|
DEFAULT_BISECT_DIR = "/tmp/sysroot_bisect"
|
|
|
|
|
|
def populate_good_files(top_dir, ce, bisect_dir=DEFAULT_BISECT_DIR):
|
|
# 'make clean'
|
|
work_dir = os.path.join(top_dir, TEST_DIR, "work")
|
|
cmd = "rm -f %s/*.o" % work_dir
|
|
status = ce.RunCommand(cmd)
|
|
if status != 0:
|
|
print("Error trying to clean out work directory: %s" % cmd)
|
|
return status
|
|
|
|
# set up the 'good' source files
|
|
script = os.path.join(top_dir, TEST_DIR, "make_sources_good.sh")
|
|
status = ce.RunCommand(script)
|
|
if status != 0:
|
|
print('Error setting up "good" source files: %s' % script)
|
|
return status
|
|
|
|
export_bisect = "export BISECT_DIR=%s; " % bisect_dir
|
|
# build the good source files
|
|
script_path = os.path.join(top_dir, TEST_DIR)
|
|
if os.path.exists("/usr/bin/x86_64-cros-linux-gnu-gcc"):
|
|
build_script = "chromeos_build.sh"
|
|
else:
|
|
build_script = "build.sh"
|
|
cmd = "%s export BISECT_STAGE=POPULATE_GOOD; pushd %s; ./%s; popd" % (
|
|
export_bisect,
|
|
script_path,
|
|
build_script,
|
|
)
|
|
status = ce.RunCommand(cmd)
|
|
return status
|
|
|
|
|
|
def populate_bad_files(top_dir, ce, bisect_dir=DEFAULT_BISECT_DIR):
|
|
# 'make clean'
|
|
work_dir = os.path.join(top_dir, TEST_DIR, "work")
|
|
cmd = "rm -f %s/*.o" % work_dir
|
|
status = ce.RunCommand(cmd)
|
|
if status != 0:
|
|
print("Error trying to clean out work directory: %s" % cmd)
|
|
return status
|
|
|
|
# set up the 'bad' source files
|
|
script = os.path.join(top_dir, TEST_DIR, "make_sources_bad.sh")
|
|
status = ce.RunCommand(script)
|
|
if status != 0:
|
|
print('Error setting up "bad" source files: %s' % script)
|
|
return status
|
|
|
|
export_bisect = "export BISECT_DIR=%s; " % bisect_dir
|
|
# build the bad source files
|
|
script_path = os.path.join(top_dir, TEST_DIR)
|
|
if os.path.exists("/usr/bin/x86_64-cros-linux-gnu-gcc"):
|
|
build_script = "chromeos_build.sh"
|
|
else:
|
|
build_script = "build.sh"
|
|
cmd = "%s export BISECT_STAGE=POPULATE_BAD; pushd %s; ./%s ; popd" % (
|
|
export_bisect,
|
|
script_path,
|
|
build_script,
|
|
)
|
|
status = ce.RunCommand(cmd)
|
|
return status
|
|
|
|
|
|
def run_main_bisection_test(top_dir, ce):
|
|
test_script = os.path.join(top_dir, TEST_DIR, "main-bisect-test.sh")
|
|
status = ce.RunCommand(test_script)
|
|
return status
|
|
|
|
|
|
def verify_compiler_and_wrapper():
|
|
# We don't need to do any special setup if running inside a ChromeOS
|
|
# chroot.
|
|
if os.path.exists("/usr/bin/x86_64-cros-linux-gnu-gcc"):
|
|
return True
|
|
|
|
message = """
|
|
*** IMPORTANT --- READ THIS CAREFULLY!! ***
|
|
|
|
This test uses the command 'gcc' to compile the good/bad versions of the
|
|
source program. BEFORE you can run this script you must make sure that
|
|
your compiler wrapper is in the right place, with the right name, so that
|
|
a call to 'gcc' will go through your compiler wrapper and "do the right
|
|
thing".
|
|
|
|
Is your compiler wrapper properly set up? [Y/n]
|
|
"""
|
|
|
|
print(message)
|
|
inp = sys.stdin.readline()
|
|
inp = inp.strip()
|
|
inp = inp.lower()
|
|
return not inp or inp == "y" or inp == "yes"
|
|
|
|
|
|
def Main(argv):
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"--dir",
|
|
dest="directory",
|
|
help="Bisection work tree, where good & bad object "
|
|
"files go. Default is /tmp/sysroot_bisect",
|
|
)
|
|
|
|
options = parser.parse_args(argv)
|
|
|
|
# Make sure the compiler wrapper & soft links are properly set up.
|
|
wrapper_is_setup = verify_compiler_and_wrapper()
|
|
if not wrapper_is_setup:
|
|
print(
|
|
"Exiting now. Please re-run after you have set up the compiler "
|
|
"wrapper."
|
|
)
|
|
return 0
|
|
|
|
# Make sure we're in the correct directory for running this test.
|
|
cwd = os.getcwd()
|
|
if not os.path.exists(os.path.join(cwd, "full_bisect_test")):
|
|
print(
|
|
"Error: Wrong directory. This script must be run from the top level"
|
|
" of the binary_search_tool tree (under toolchain_utils)."
|
|
)
|
|
return 1
|
|
|
|
ce = command_executer.GetCommandExecuter()
|
|
bisect_dir = options.directory
|
|
if not bisect_dir:
|
|
bisect_dir = DEFAULT_BISECT_DIR
|
|
|
|
# Make sure BISECT_DIR is clean
|
|
if os.path.exists(bisect_dir):
|
|
cmd = "rm -Rf %s/*" % bisect_dir
|
|
retv = ce.RunCommand(cmd)
|
|
if retv != 0:
|
|
return retv
|
|
|
|
retv = populate_good_files(cwd, ce, bisect_dir)
|
|
if retv != 0:
|
|
return retv
|
|
|
|
retv = populate_bad_files(cwd, ce, bisect_dir)
|
|
if retv != 0:
|
|
return retv
|
|
|
|
# Set up good/bad work soft links
|
|
cmd = "rm -f %s/%s/good-objects; ln -s %s/good %s/%s/good-objects" % (
|
|
cwd,
|
|
TEST_DIR,
|
|
bisect_dir,
|
|
cwd,
|
|
TEST_DIR,
|
|
)
|
|
|
|
status = ce.RunCommand(cmd)
|
|
if status != 0:
|
|
print("Error executing: %s; exiting now." % cmd)
|
|
return status
|
|
|
|
cmd = "rm -f %s/%s/bad-objects; ln -s %s/bad %s/%s/bad-objects" % (
|
|
cwd,
|
|
TEST_DIR,
|
|
bisect_dir,
|
|
cwd,
|
|
TEST_DIR,
|
|
)
|
|
|
|
status = ce.RunCommand(cmd)
|
|
if status != 0:
|
|
print("Error executing: %s; exiting now." % cmd)
|
|
return status
|
|
|
|
retv = run_main_bisection_test(cwd, ce)
|
|
return retv
|
|
|
|
|
|
if __name__ == "__main__":
|
|
retval = Main(sys.argv[1:])
|
|
sys.exit(retval)
|