When TOP dir changes and we reuse the same output between the old and new checkouts, we need to rewrite all the symlinks used by Bazel and other tools in the out-directory to point to the new top directory. Otherwise, if the old source dir is deleted, the build will fail. I used the OUT_DIR/soong/soong.environment.available file to find out the previous PWD. Tested: 1. Create source dir 1, run build, create source dir 2, remote source dir 1, reuse out dir and rerun build => build succeeded with this change. 2. m libc after moving build TOP. Only the analysis phase was rerun, the actual build was not rerun. Bug: b/300498226 Change-Id: I196625baa1f4efe7a4734accfa1f0be7c98a7920
213 lines
5.5 KiB
Bash
213 lines
5.5 KiB
Bash
#!/bin/bash -eu
|
|
|
|
set -o pipefail
|
|
|
|
HARDWIRED_MOCK_TOP=
|
|
# Uncomment this to be able to view the source tree after a test is run
|
|
# HARDWIRED_MOCK_TOP=/tmp/td
|
|
|
|
REAL_TOP="$(readlink -f "$(dirname "$0")"/../../..)"
|
|
|
|
function make_mock_top {
|
|
mock=$(mktemp -t -d st.XXXXX)
|
|
echo "$mock"
|
|
}
|
|
|
|
if [[ -n "$HARDWIRED_MOCK_TOP" ]]; then
|
|
MOCK_TOP="$HARDWIRED_MOCK_TOP"
|
|
else
|
|
MOCK_TOP=$(mktemp -t -d st.XXXXX)
|
|
trap cleanup_mock_top EXIT
|
|
fi
|
|
|
|
WARMED_UP_MOCK_TOP=$(mktemp -t soong_integration_tests_warmup.XXXXXX.tar.gz)
|
|
trap 'rm -f "$WARMED_UP_MOCK_TOP"' EXIT
|
|
|
|
function warmup_mock_top {
|
|
info "Warming up mock top ..."
|
|
info "Mock top warmup archive: $WARMED_UP_MOCK_TOP"
|
|
cleanup_mock_top
|
|
mkdir -p "$MOCK_TOP"
|
|
cd "$MOCK_TOP"
|
|
|
|
create_mock_soong
|
|
run_soong
|
|
tar czf "$WARMED_UP_MOCK_TOP" *
|
|
}
|
|
|
|
function cleanup_mock_top {
|
|
cd /
|
|
rm -fr "$MOCK_TOP"
|
|
}
|
|
|
|
function info {
|
|
echo -e "\e[92;1m[TEST HARNESS INFO]\e[0m" "$*"
|
|
}
|
|
|
|
function fail {
|
|
echo -e "\e[91;1mFAILED:\e[0m" "$*"
|
|
exit 1
|
|
}
|
|
|
|
function copy_directory {
|
|
local dir="$1"
|
|
local -r parent="$(dirname "$dir")"
|
|
|
|
mkdir -p "$MOCK_TOP/$parent"
|
|
cp -R "$REAL_TOP/$dir" "$MOCK_TOP/$parent"
|
|
}
|
|
|
|
function delete_directory {
|
|
rm -rf "$MOCK_TOP/$1"
|
|
}
|
|
|
|
function symlink_file {
|
|
local file="$1"
|
|
|
|
mkdir -p "$MOCK_TOP/$(dirname "$file")"
|
|
ln -s "$REAL_TOP/$file" "$MOCK_TOP/$file"
|
|
}
|
|
|
|
function symlink_directory {
|
|
local dir="$1"
|
|
|
|
mkdir -p "$MOCK_TOP/$dir"
|
|
# We need to symlink the contents of the directory individually instead of
|
|
# using one symlink for the whole directory because finder.go doesn't follow
|
|
# symlinks when looking for Android.bp files
|
|
for i in "$REAL_TOP/$dir"/*; do
|
|
i=$(basename "$i")
|
|
local target="$MOCK_TOP/$dir/$i"
|
|
local source="$REAL_TOP/$dir/$i"
|
|
|
|
if [[ -e "$target" ]]; then
|
|
if [[ ! -d "$source" || ! -d "$target" ]]; then
|
|
fail "Trying to symlink $dir twice"
|
|
fi
|
|
else
|
|
ln -s "$REAL_TOP/$dir/$i" "$MOCK_TOP/$dir/$i";
|
|
fi
|
|
done
|
|
}
|
|
|
|
function create_mock_soong {
|
|
create_mock_bazel
|
|
copy_directory build/blueprint
|
|
copy_directory build/soong
|
|
copy_directory build/make
|
|
|
|
symlink_directory prebuilts/sdk
|
|
symlink_directory prebuilts/go
|
|
symlink_directory prebuilts/build-tools
|
|
symlink_directory prebuilts/clang/host
|
|
symlink_directory external/compiler-rt
|
|
symlink_directory external/go-cmp
|
|
symlink_directory external/golang-protobuf
|
|
symlink_directory external/licenseclassifier
|
|
symlink_directory external/starlark-go
|
|
symlink_directory external/python
|
|
symlink_directory external/sqlite
|
|
symlink_directory external/spdx-tools
|
|
symlink_directory libcore
|
|
|
|
# TODO: b/286872909 - Remove these when the blocking bug is completed
|
|
symlink_directory external/libavc
|
|
symlink_directory external/libaom
|
|
symlink_directory external/libvpx
|
|
symlink_directory frameworks/base/libs/androidfw
|
|
symlink_directory external/libhevc
|
|
symlink_directory external/libexif
|
|
symlink_directory external/libopus
|
|
symlink_directory external/libmpeg2
|
|
symlink_directory external/expat
|
|
symlink_directory external/flac
|
|
symlink_directory system/extras/toolchain-extras
|
|
|
|
touch "$MOCK_TOP/Android.bp"
|
|
}
|
|
|
|
function setup {
|
|
cleanup_mock_top
|
|
mkdir -p "$MOCK_TOP"
|
|
|
|
echo
|
|
echo ----------------------------------------------------------------------------
|
|
info "Running test case \e[96;1m${FUNCNAME[1]}\e[0m"
|
|
cd "$MOCK_TOP"
|
|
|
|
tar xzf "$WARMED_UP_MOCK_TOP" --warning=no-timestamp
|
|
}
|
|
|
|
# shellcheck disable=SC2120
|
|
function run_soong {
|
|
USE_RBE=false build/soong/soong_ui.bash --make-mode --skip-ninja --skip-config --soong-only --skip-soong-tests "$@"
|
|
}
|
|
|
|
function create_mock_bazel {
|
|
copy_directory build/bazel
|
|
copy_directory build/bazel_common_rules
|
|
|
|
# This requires pulling more tools into the mock top to build partitions
|
|
delete_directory build/bazel/examples/partitions
|
|
|
|
symlink_directory packages/modules/common/build
|
|
symlink_directory prebuilts/bazel
|
|
symlink_directory prebuilts/clang
|
|
symlink_directory prebuilts/jdk
|
|
symlink_directory external/bazel-skylib
|
|
symlink_directory external/bazelbuild-rules_android
|
|
symlink_directory external/bazelbuild-rules_go
|
|
symlink_directory external/bazelbuild-rules_license
|
|
symlink_directory external/bazelbuild-kotlin-rules
|
|
symlink_directory external/bazelbuild-rules_cc
|
|
symlink_directory external/bazelbuild-rules_python
|
|
symlink_directory external/bazelbuild-rules_java
|
|
symlink_directory external/bazelbuild-rules_rust
|
|
symlink_directory external/rust/crates/tinyjson
|
|
|
|
symlink_file WORKSPACE
|
|
symlink_file BUILD
|
|
}
|
|
|
|
function run_bazel {
|
|
# Remove the ninja_build output marker file to communicate to buildbot that this is not a regular Ninja build, and its
|
|
# output should not be parsed as such.
|
|
rm -rf out/ninja_build
|
|
|
|
build/bazel/bin/bazel "$@"
|
|
}
|
|
|
|
function run_ninja {
|
|
build/soong/soong_ui.bash --make-mode --skip-config --soong-only --skip-soong-tests "$@"
|
|
}
|
|
|
|
info "Starting Soong integration test suite $(basename "$0")"
|
|
info "Mock top: $MOCK_TOP"
|
|
|
|
|
|
export ALLOW_MISSING_DEPENDENCIES=true
|
|
export ALLOW_BP_UNDER_SYMLINKS=true
|
|
warmup_mock_top
|
|
|
|
function scan_and_run_tests {
|
|
# find all test_ functions
|
|
# NB "declare -F" output is sorted, hence test order is deterministic
|
|
readarray -t test_fns < <(declare -F | sed -n -e 's/^declare -f \(test_.*\)$/\1/p')
|
|
info "Found ${#test_fns[*]} tests"
|
|
if [[ ${#test_fns[*]} -eq 0 ]]; then
|
|
fail "No tests found"
|
|
fi
|
|
for f in ${test_fns[*]}; do
|
|
$f
|
|
info "Completed test case \e[96;1m$f\e[0m"
|
|
done
|
|
}
|
|
|
|
function move_mock_top {
|
|
MOCK_TOP2=$(make_mock_top)
|
|
rm -rf $MOCK_TOP2
|
|
mv $MOCK_TOP $MOCK_TOP2
|
|
MOCK_TOP=$MOCK_TOP2
|
|
trap cleanup_mock_top EXIT
|
|
}
|