Bisection: add better support for Chrome.

This adds custom path for Chrome, and calls deploy_chrome instead of
cros_deploy. Also adds --use_flags and --noreboot options.

BUG=b:188061539
TEST=Verified locally

Change-Id: Id7ca51199ac7877df57632258e87dab3612113c5
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/2894357
Reviewed-by: Manoj Gupta <manojgupta@chromium.org>
Tested-by: Jian Cai <jiancai@google.com>
diff --git a/binary_search_tool/README.bisect.md b/binary_search_tool/README.bisect.md
index bd9e0f1..32f4cba 100644
--- a/binary_search_tool/README.bisect.md
+++ b/binary_search_tool/README.bisect.md
@@ -75,7 +75,9 @@
 
 * board: The board to bisect on. For example: daisy, falco, etc.
 * remote: The IP address of the physical machine you're using to test with.
-* package: The package to bisect with. For example: chromeos-chrome
+* package: The package to bisect with. For example: chromeos-chrome.
+* use_flags: (Optional) Use flags for emerge. For example: "-thinlto -cfi".
+* noreboot: (Optional) Do not reboot after updating the package.
 * dir: (Optional) the directory for your good/bad build trees. Defaults to
        $BISECT_DIR or /tmp/sysroot_bisect. This value will set $BISECT_DIR
        for all bisecting scripts.
diff --git a/binary_search_tool/common/test_setup.sh b/binary_search_tool/common/test_setup.sh
index 6e64e5c..3ea7327 100755
--- a/binary_search_tool/common/test_setup.sh
+++ b/binary_search_tool/common/test_setup.sh
@@ -1,6 +1,8 @@
 #!/bin/bash
 #
-# Copyright 2016 Google Inc. All Rights Reserved.
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
 #
 # This is a generic ChromeOS package/image test setup script. It is meant to
 # be used for either the object file or package bisection tools. This script
@@ -98,8 +100,25 @@
   sudo rm -rf /build/${BISECT_BOARD}/var/cache/portage/*
   sudo rm -rf /build/${BISECT_BOARD}/tmp/portage/${BISECT_PACKAGE}*
   set +x
+  if [[ ${BISECT_PACKAGE} == *chromeos-chrome ]]; then
+    if [[ ${BISECT_USE_FLAGS} == *chrome_internal* && \
+      ${BISECT_USE_FLAGS} != *-chrome_internal* ]]; then
+      # for the pre-upload check of the length of lines
+      chrome_build_dir="/var/cache/chromeos-chrome/chrome-src-internal/src/"
+      chrome_build_dir+="out_${BISECT_BOARD}"
+    else
+      # for the pre-upload check of the length of lines
+      chrome_build_dir="/var/cache/chromeos-chrome/chrome-src/src/"
+      chrome_build_dir+="out_${BISECT_BOARD}"
+    fi
+    set -x
+    sudo rm -rf ${chrome_build_dir}
+    set +x
+  fi
+  set -x
   CLEAN_DELAY=0 emerge-${BISECT_BOARD} -C ${BISECT_PACKAGE}
-  emerge-${BISECT_BOARD} ${BISECT_PACKAGE}
+  USE="${BISECT_USE_FLAGS}" emerge-${BISECT_BOARD} ${BISECT_PACKAGE}
+  set +x
   emerge_status=$?
 
   if [[ ${emerge_status} -ne 0 ]] ; then
@@ -108,7 +127,7 @@
   fi
 
   echo
-  echo "DEPLOYING"
+  echo "DEPLOYING TO ${BISECT_REMOTE}"
 
   if [[ ${BISECT_PACKAGE} == *chromeos-kernel-* ]]; then
     cmd="/mnt/host/source/src/scripts/update_kernel.sh --board=${BISECT_BOARD} --remote=${BISECT_REMOTE}"
@@ -117,17 +136,34 @@
       PORT=$(echo $1 | cut -d ":" -f2)
       cmd="/mnt/host/source/src/scripts/update_kernel.sh --board=${BISECT_BOARD} --remote=${IP} --ssh_port=${PORT}"
     fi
+    if [[ ${BISECT_REBOOT_OPTION} == false ]]; then
+      cmd+=" --noreboot"
+    fi
     set -x
     # exec the command to make sure it always exit after
     exec $cmd
     set +x
   fi
 
-  echo "cros deploy ${BISECT_REMOTE} ${BISECT_PACKAGE}"
-  cros deploy ${BISECT_REMOTE} ${BISECT_PACKAGE} --log-level=info
-
+  if [[ ${BISECT_PACKAGE} == *chromeos-chrome ]]; then
+    # deploy_chrome needs to run inside chrome source tree
+    pushd ~/chrome_root
+    set -x
+    deploy_chrome --force --build-dir=${chrome_build_dir}/Release \
+      --device=${BISECT_REMOTE}
+    set +x
+    popd
+  else
+    set -x
+    cros deploy ${BISECT_REMOTE} ${BISECT_PACKAGE} --log-level=info
+    set +x
+  fi
   deploy_status=$?
 
+  if [[ ${BISECT_REBOOT_OPTION} == false ]]; then
+    exit 0
+  fi
+
   if [[ ${deploy_status} -eq 0 ]] ; then
     echo "Deploy successful. Rebooting device..."
     reboot
@@ -145,7 +181,8 @@
 
 echo "BUILDING IMAGE"
 pushd ~/trunk/src/scripts
-./build_image test --board=${BISECT_BOARD} --noenable_rootfs_verification --noeclean
+USE="${BISECT_USE_FLAGS}" ./build_image test --board=${BISECT_BOARD} \
+  --noenable_rootfs_verification --noeclean
 build_status=$?
 popd
 
diff --git a/binary_search_tool/run_bisect.py b/binary_search_tool/run_bisect.py
index ef1048b..249b9cf 100755
--- a/binary_search_tool/run_bisect.py
+++ b/binary_search_tool/run_bisect.py
@@ -12,6 +12,7 @@
 import argparse
 from argparse import RawTextHelpFormatter
 import os
+import shlex
 import sys
 
 from binary_search_tool import binary_search_state
@@ -141,8 +142,8 @@
         'prune': True,
         'file_args': True
     }
-    self.setup_cmd = ('%s %s %s' % (self.cros_pkg_setup, self.options.board,
-                                    self.options.remote))
+    self.setup_cmd = ' '.join(
+        (self.cros_pkg_setup, self.options.board, self.options.remote))
     self.ArgOverride(self.default_kwargs, self.overrides)
 
   def PreRun(self):
@@ -192,9 +193,10 @@
     if options.dir:
       os.environ['BISECT_DIR'] = options.dir
     self.options.dir = os.environ.get('BISECT_DIR', '/tmp/sysroot_bisect')
-    self.setup_cmd = (
-        '%s %s %s %s' % (self.sysroot_wrapper_setup, self.options.board,
-                         self.options.remote, self.options.package))
+    self.setup_cmd = ' '.join(
+        (self.sysroot_wrapper_setup, self.options.board, self.options.remote,
+         self.options.package, str(self.options.reboot).lower(),
+         shlex.quote(self.options.use_flags)))
 
     self.ArgOverride(self.default_kwargs, overrides)
 
@@ -253,8 +255,8 @@
     if self.options.device_id:
       device_id = "ANDROID_SERIAL='%s'" % self.options.device_id
 
-    self.setup_cmd = ('%s %s %s %s' % (num_jobs, device_id, self.android_setup,
-                                       self.options.android_src))
+    self.setup_cmd = ' '.join(
+        (num_jobs, device_id, self.android_setup, self.options.android_src))
 
     self.ArgOverride(self.default_kwargs, overrides)
 
@@ -344,6 +346,16 @@
   parser_object.add_argument('remote', help='Remote machine to test on')
   parser_object.add_argument('package', help='Package to emerge and test')
   parser_object.add_argument(
+      '--use_flags',
+      required=False,
+      default='',
+      help='Use flags passed to emerge')
+  parser_object.add_argument(
+      '--noreboot',
+      action='store_false',
+      dest='reboot',
+      help='Do not reboot after updating the package (default: False)')
+  parser_object.add_argument(
       '--dir',
       help=('Bisection directory to use, sets '
             '$BISECT_DIR if provided. Defaults to '
diff --git a/binary_search_tool/sysroot_wrapper/README.md b/binary_search_tool/sysroot_wrapper/README.md
index 89904a0..77ce4b8 100644
--- a/binary_search_tool/sysroot_wrapper/README.md
+++ b/binary_search_tool/sysroot_wrapper/README.md
@@ -8,7 +8,7 @@
 Before running the binary searcher tool you will need to run the setup script:
 
 ```
-./sysroot_wrapper/setup.sh ${board} ${remote_ip} ${package}
+./sysroot_wrapper/setup.sh ${board} ${remote_ip} ${package} ${reboot_option} ${use_flags}
 ```
 
 This setup script will ensure your `$BISECT_DIR` is properly populated and
diff --git a/binary_search_tool/sysroot_wrapper/setup.sh b/binary_search_tool/sysroot_wrapper/setup.sh
index f5907f5..6b9b48f 100755
--- a/binary_search_tool/sysroot_wrapper/setup.sh
+++ b/binary_search_tool/sysroot_wrapper/setup.sh
@@ -1,6 +1,8 @@
 #!/bin/bash -u
 #
-# Copyright 2016 Google Inc. All Rights Reserved.
+# Copyright 2021 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
 #
 # This script is part of the ChromeOS object binary search triage process.
 # It should be the first script called by the user, after the user has set up
@@ -23,6 +25,8 @@
 BOARD=$1
 REMOTE=$2
 PACKAGE=$3
+REBOOT_OPTION=$4
+USE_FLAGS=$5
 
 GOOD_BUILD=${bisect_dir}/good
 BAD_BUILD=${bisect_dir}/bad
@@ -60,6 +64,8 @@
 BISECT_BOARD=${BOARD}
 BISECT_REMOTE=${REMOTE}
 BISECT_PACKAGE=${PACKAGE}
+BISECT_REBOOT_OPTION=${REBOOT_OPTION}
+BISECT_USE_FLAGS="${USE_FLAGS}"
 BISECT_MODE="OBJECT_MODE"
 
 bisect_dir=${bisect_dir}