blob: 8efeb15ed096a52468d5a518d59e73d397a1e82e [file] [log] [blame]
#!/bin/bash
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Bash functions used by buildbot annotator scripts for the android
# build of chromium. Executing this script should not perform actions
# other than setting variables and defining of functions.
# Number of jobs on the compile line; e.g. make -j"${JOBS}"
JOBS="${JOBS:-4}"
# Parse named arguments passed into the annotator script
# and assign them global variable names.
function bb_parse_args {
while [[ $1 ]]; do
case "$1" in
--factory-properties=*)
FACTORY_PROPERTIES="$(echo "$1" | sed 's/^[^=]*=//')"
BUILDTYPE=$(bb_get_json_prop "$FACTORY_PROPERTIES" target)
;;
--build-properties=*)
BUILD_PROPERTIES="$(echo "$1" | sed 's/^[^=]*=//')"
;;
*)
echo "@@@STEP_WARNINGS@@@"
echo "Warning, unparsed input argument: '$1'"
;;
esac
shift
done
}
# Function to force-green a bot.
function bb_force_bot_green_and_exit {
echo "@@@BUILD_STEP Bot forced green.@@@"
exit 0
}
# Basic setup for all bots to run after a source tree checkout.
# Args:
# $1: source root.
# $2 and beyond: key value pairs which are parsed by bb_parse_args.
function bb_baseline_setup {
SRC_ROOT="$1"
# Remove SRC_ROOT param
shift
cd $SRC_ROOT
echo "@@@BUILD_STEP Environment setup@@@"
bb_parse_args "$@"
local BUILDTOOL=$(bb_get_json_prop "$FACTORY_PROPERTIES" buildtool)
if [[ $BUILDTOOL = ninja ]]; then
export GYP_GENERATORS=ninja
fi
export GOMA_DIR=/b/build/goma
. build/android/envsetup.sh
local extra_gyp_defines="$(bb_get_json_prop "$FACTORY_PROPERTIES" \
extra_gyp_defines)"
export GYP_DEFINES+=" fastbuild=1 $extra_gyp_defines"
if echo $extra_gyp_defines | grep -qE 'clang|asan'; then
unset CXX_target
fi
adb kill-server
adb start-server
local build_path="${SRC_ROOT}/out/${BUILDTYPE}"
local landmines_triggered_path="$build_path/.landmines_triggered"
python "$SRC_ROOT/build/landmines.py"
if [[ $BUILDBOT_CLOBBER || -f "$landmines_triggered_path" ]]; then
echo "@@@BUILD_STEP Clobber@@@"
if [[ -z $BUILDBOT_CLOBBER ]]; then
echo "Clobbering due to triggered landmines: "
cat "$landmines_triggered_path"
else
# Also remove all the files under out/ on an explicit clobber
find "${SRC_ROOT}/out" -maxdepth 1 -type f -exec rm -f {} +
fi
# Sdk key expires, delete android folder.
# crbug.com/145860
rm -rf ~/.android
rm -rf "$build_path"
if [[ -e $build_path ]] ; then
echo "Clobber appeared to fail? $build_path still exists."
echo "@@@STEP_WARNINGS@@@"
fi
fi
}
function bb_compile_setup {
bb_setup_goma_internal
# Should be called only after envsetup is done.
gclient runhooks
}
# Setup goma. Used internally to buildbot_functions.sh.
function bb_setup_goma_internal {
export GOMA_API_KEY_FILE=${GOMA_DIR}/goma.key
export GOMA_COMPILER_PROXY_DAEMON_MODE=true
export GOMA_COMPILER_PROXY_RPC_TIMEOUT_SECS=300
echo "Killing old goma processes"
${GOMA_DIR}/goma_ctl.sh stop || true
killall -9 compiler_proxy || true
echo "Starting goma"
${GOMA_DIR}/goma_ctl.sh start
trap bb_stop_goma_internal SIGHUP SIGINT SIGTERM
}
# Stop goma.
function bb_stop_goma_internal {
echo "Stopping goma"
${GOMA_DIR}/goma_ctl.sh stop
}
# $@: make args.
# Use goma if possible; degrades to non-Goma if needed.
function bb_goma_make {
if [ "${GOMA_DIR}" = "" ]; then
make -j${JOBS} "$@"
return
fi
HOST_CC=$GOMA_DIR/gcc
HOST_CXX=$GOMA_DIR/g++
TARGET_CC=$(/bin/ls $ANDROID_TOOLCHAIN/*-gcc | head -n1)
TARGET_CXX=$(/bin/ls $ANDROID_TOOLCHAIN/*-g++ | head -n1)
TARGET_CC="$GOMA_DIR/gomacc $TARGET_CC"
TARGET_CXX="$GOMA_DIR/gomacc $TARGET_CXX"
COMMON_JAVAC="$GOMA_DIR/gomacc /usr/bin/javac -J-Xmx512M \
-target 1.5 -Xmaxerrs 9999999"
command make \
-j100 \
-l20 \
HOST_CC="$HOST_CC" \
HOST_CXX="$HOST_CXX" \
TARGET_CC="$TARGET_CC" \
TARGET_CXX="$TARGET_CXX" \
CC.host="$HOST_CC" \
CXX.host="$HOST_CXX" \
CC.target="$TARGET_CC" \
CXX.target="$TARGET_CXX" \
LINK.target="$TARGET_CXX" \
COMMON_JAVAC="$COMMON_JAVAC" \
BUILDTYPE="$BUILDTYPE" \
"$@"
local make_exit_code=$?
return $make_exit_code
}
# Build using ninja.
function bb_goma_ninja {
echo "Using ninja to build."
local TARGET=$1
ninja -C out/$BUILDTYPE -j120 -l20 $TARGET
}
# Compile step
function bb_compile {
# This must be named 'compile', not 'Compile', for CQ interaction.
# Talk to maruel for details.
echo "@@@BUILD_STEP compile@@@"
bb_compile_setup
BUILDTOOL=$(bb_get_json_prop "$FACTORY_PROPERTIES" buildtool)
if [[ $BUILDTOOL = ninja ]]; then
bb_goma_ninja All
else
bb_goma_make
fi
bb_stop_goma_internal
}
# Experimental compile step; does not turn the tree red if it fails.
function bb_compile_experimental {
# Linking DumpRenderTree appears to hang forever?
EXPERIMENTAL_TARGETS="android_experimental"
for target in ${EXPERIMENTAL_TARGETS} ; do
echo "@@@BUILD_STEP Experimental Compile $target @@@"
set +e
if [[ $BUILDTOOL = ninja ]]; then
bb_goma_ninja "${target}"
else
bb_goma_make -k "${target}"
fi
if [ $? -ne 0 ] ; then
echo "@@@STEP_WARNINGS@@@"
fi
set -e
done
}
# Run tests on an emulator.
function bb_run_tests_emulator {
echo "@@@BUILD_STEP Run Tests on an Emulator@@@"
build/android/run_tests.py -e --xvfb --verbose
}
function bb_spawn_logcat_monitor_and_status {
python build/android/device_status_check.py
LOGCAT_DUMP_DIR="$CHROME_SRC/out/logcat"
rm -rf "$LOGCAT_DUMP_DIR"
python build/android/adb_logcat_monitor.py "$LOGCAT_DUMP_DIR" &
}
function bb_print_logcat {
echo "@@@BUILD_STEP Logcat dump@@@"
python build/android/adb_logcat_printer.py "$LOGCAT_DUMP_DIR"
}
# Run tests on an actual device. (Better have one plugged in!)
function bb_run_unit_tests {
build/android/run_tests.py --xvfb --verbose
}
# Run WebKit's test suites: webkit_unit_tests and TestWebKitAPI
function bb_run_webkit_unit_tests {
if [[ $BUILDTYPE = Release ]]; then
local BUILDFLAG="--release"
fi
bb_run_step build/android/run_tests.py --xvfb --verbose $BUILDFLAG \
-s webkit_unit_tests
bb_run_step build/android/run_tests.py --xvfb --verbose $BUILDFLAG \
-s TestWebKitAPI
}
# Lint WebKit's TestExpectation files.
function bb_lint_webkit_expectation_files {
echo "@@@BUILD_STEP webkit_lint@@@"
bb_run_step python webkit/tools/layout_tests/run_webkit_tests.py \
--lint-test-files \
--chromium
}
# Run layout tests on an actual device.
function bb_run_webkit_layout_tests {
echo "@@@BUILD_STEP webkit_tests@@@"
local BUILDERNAME="$(bb_get_json_prop "$BUILD_PROPERTIES" buildername)"
local BUILDNUMBER="$(bb_get_json_prop "$BUILD_PROPERTIES" buildnumber)"
local MASTERNAME="$(bb_get_json_prop "$BUILD_PROPERTIES" mastername)"
local RESULTSERVER=\
"$(bb_get_json_prop "$FACTORY_PROPERTIES" test_results_server)"
bb_run_step python webkit/tools/layout_tests/run_webkit_tests.py \
--no-show-results \
--no-new-test-results \
--full-results-html \
--clobber-old-results \
--exit-after-n-failures 5000 \
--exit-after-n-crashes-or-timeouts 100 \
--debug-rwt-logging \
--results-directory "../layout-test-results" \
--target "$BUILDTYPE" \
--builder-name "$BUILDERNAME" \
--build-number "$BUILDNUMBER" \
--master-name "$MASTERNAME" \
--build-name "$BUILDERNAME" \
--platform=chromium-android \
--test-results-server "$RESULTSERVER"
}
# Run experimental unittest bundles.
function bb_run_experimental_unit_tests {
build/android/run_tests.py --xvfb --verbose -s android_webview_unittests
}
# Run findbugs.
function bb_run_findbugs {
echo "@@@BUILD_STEP findbugs@@@"
if [[ $BUILDTYPE = Release ]]; then
local BUILDFLAG="--release-build"
fi
bb_run_step build/android/findbugs_diff.py $BUILDFLAG
bb_run_step tools/android/findbugs_plugin/test/run_findbugs_plugin_tests.py \
$BUILDFLAG
}
# Run a buildbot step and handle failure (failure will not halt build).
function bb_run_step {
(
set +e
"$@"
if [[ $? != 0 ]]; then
echo "@@@STEP_FAILURE@@@"
fi
)
}
# Install a specific APK.
# Args:
# $1: APK to be installed.
# $2: APK_PACKAGE for the APK to be installed.
function bb_install_apk {
local APK=${1}
local APK_PACKAGE=${2}
if [[ $BUILDTYPE = Release ]]; then
local BUILDFLAG="--release"
fi
echo "@@@BUILD_STEP Install ${APK}@@@"
python build/android/adb_install_apk.py --apk ${APK} \
--apk_package ${APK_PACKAGE} ${BUILDFLAG}
}
# Run instrumentation tests for a specific APK.
# Args:
# $1: APK to be installed.
# $2: APK_PACKAGE for the APK to be installed.
# $3: TEST_APK to run the tests against.
# $4: TEST_DATA in format destination:source
function bb_run_all_instrumentation_tests_for_apk {
local APK=${1}
local APK_PACKAGE=${2}
local TEST_APK=${3}
local TEST_DATA=${4}
# Install application APK.
bb_install_apk ${APK} ${APK_PACKAGE}
# Run instrumentation tests. Using -I to install the test apk.
echo "@@@BUILD_STEP Run instrumentation tests ${TEST_APK}@@@"
bb_run_step python build/android/run_instrumentation_tests.py \
-vvv --test-apk ${TEST_APK} -I --test_data ${TEST_DATA}
}
# Run instrumentation tests for all relevant APKs on device.
function bb_run_instrumentation_tests {
bb_run_all_instrumentation_tests_for_apk "ContentShell.apk" \
"org.chromium.content_shell" "ContentShellTest" \
"content:content/test/data/android/device_files"
bb_run_all_instrumentation_tests_for_apk "ChromiumTestShell.apk" \
"org.chromium.chrome.testshell" "ChromiumTestShellTest" \
"chrome:chrome/test/data/android/device_files"
bb_run_all_instrumentation_tests_for_apk "AndroidWebView.apk" \
"org.chromium.android_webview" "AndroidWebViewTest" \
"webview:android_webview/test/data/device_files"
}
# Run instrumentation tests for experimental APKs on device.
function bb_run_experimental_instrumentation_tests {
echo "" # Can't have empty functions in bash.
}
# Zip and archive a build.
function bb_zip_build {
echo "@@@BUILD_STEP Zip build@@@"
python ../../../../scripts/slave/zip_build.py \
--src-dir "$SRC_ROOT" \
--exclude-files "lib.target,gen,android_webview,jingle_unittests" \
--factory-properties "$FACTORY_PROPERTIES" \
--build-properties "$BUILD_PROPERTIES"
}
# Download and extract a build.
function bb_extract_build {
echo "@@@BUILD_STEP Download and extract build@@@"
if [[ -z $FACTORY_PROPERTIES || -z $BUILD_PROPERTIES ]]; then
return 1
fi
# When extract_build.py downloads an unversioned build it
# issues a warning by exiting with large numbered return code
# When it fails to download it build, it exits with return
# code 1. We disable halt on error mode and return normally
# unless the python tool returns 1.
(
set +e
python ../../../../scripts/slave/extract_build.py \
--build-dir "$SRC_ROOT/build" \
--build-output-dir "../out" \
--factory-properties "$FACTORY_PROPERTIES" \
--build-properties "$BUILD_PROPERTIES"
local extract_exit_code=$?
if (( $extract_exit_code > 1 )); then
echo "@@@STEP_WARNINGS@@@"
return
fi
return $extract_exit_code
)
}
# Reboot all phones and wait for them to start back up
# Does not break build if a phone fails to restart
function bb_reboot_phones {
echo "@@@BUILD_STEP Rebooting phones@@@"
(
set +e
cd $CHROME_SRC/build/android/pylib;
for DEVICE in $(adb_get_devices); do
python -c "import android_commands;\
android_commands.AndroidCommands(device='$DEVICE').Reboot(True)" &
done
wait
)
}
# Runs the license checker for the WebView build.
function bb_check_webview_licenses {
echo "@@@BUILD_STEP Check licenses for WebView@@@"
(
set +e
cd "${SRC_ROOT}"
python android_webview/tools/webview_licenses.py scan
if [[ $? -ne 0 ]]; then
echo "@@@STEP_WARNINGS@@@"
fi
return 0
)
}
# Retrieve a packed json property using python
function bb_get_json_prop {
local JSON="$1"
local PROP="$2"
python -c "import json; print json.loads('$JSON').get('$PROP', '')"
}