#!/bin/bash set -e export LANG=C # some defaults GIT_REF_DIR=$(pwd)/ref-snapshots/ ABE_PATH="" # if empty, then it gets a local checkout below BUILD_TARGET=auto CLEAN_SNAPSHOTS=false ONLY_PREV_ABE=false ABE_REVISION="" PREV_ABE_REVISION="HEAD~1" ALL_TARGET_LIST=(aarch64-elf aarch64-linux-gnu aarch64_be-elf aarch64_be-linux-gnu armv8l-linux-gnueabihf arm-eabi arm-linux-gnueabi arm-linux-gnueabihf armeb-eabi armeb-linux-gnueabi armeb-linux-gnueabihf) validate_path() { if ! readlink -e $1; then echo "Path $1 does not exist" >&2 exit 1 fi } TARGET_NUM=0 pick_target() { if [ x"${BUILD_TARGET}" = x"auto" ]; then echo "${ALL_TARGET_LIST[$TARGET_NUM]}" else echo "${BUILD_TARGET}" fi } # we can't advance TARGET_NUM in pick_target() because it # runs in a subshell. So next_target() is called in do_test # so that it is advanced once per test. next_target() { TARGET_NUM=$(( (TARGET_NUM + 1) % ${#ALL_TARGET_LIST[@]} )) } # parse command line options while [[ $# -gt 0 ]]; do OPT=$1 shift case "$OPT" in --abe-path) ABE_PATH="`validate_path $1`"; shift;; --ref-snapshots) GIT_REF_DIR="`validate_path $1`"; shift;; --abe-flags) ABE_FLAGS=$1; shift;; --target) BUILD_TARGET=$1; shift;; --clean-snapshots) CLEAN_SNAPSHOTS=true;; --abe-revision) ABE_REVISION=$1; shift;; --only-prev-abe-test) ONLY_PREV_ABE=true;; --prev-abe-revision) PREV_ABE_REVISION=$1; shift;; --debug) set -x;; *) echo "Unrecognised option: $OPT" >&2; exit 1;; esac done if [[ ( ! -z "$ABE_REVISION" ) && ( ! -z "$ABE_PATH" ) ]]; then echo "Error: --abe-path and --abe-revision cannot be used together" >&2 exit 1 fi # find the location of the abe-tests directory ABE_TESTS_PATH=`perl -e 'use File::Basename; use Cwd q(abs_path); print dirname(abs_path(shift))' "$0"` rm -Rf checkout-test mkdir -p checkout-test cd checkout-test TOP="`pwd`" if [[ -z "$ABE_PATH" ]]; then git clone git://git.linaro.org/toolchain/abe ABE_PATH=$PWD/abe if [[ ! -z "$ABE_REVISION" ]]; then git -C "$ABE_PATH" checkout "$ABE_REVISION" fi fi if [ -d "$GIT_REF_DIR" ]; then GIT_REF_OPT=--with-git-reference-dir=$GIT_REF_DIR echo "======= FOUND GIT REFERENCE DIR $GIT_REF_DIR" else echo "======= $GIT_REF_DIR not found" unset GIT_REF_OPT fi # we reset GIT_REF_OPT after the first successful test, to avoid further # network traffic GIT_REF_OPT_SET=false ## this hack was supposed to avoid any network traffic for the clones, by ## using snapshots-ref verbatim, but git does the wrong thing with remote ## branches. #export XDG_CONFIG_HOME="$TOP/xdg" #mkdir -p $XDG_CONFIG_HOME/git # #for i in $GIT_REF_DIR/*.git; do # REMOTE=`git -C $i remote -v | grep ^origin | head -n 1 | awk '{ print $2; }'` #cat <>$XDG_CONFIG_HOME/git/config # [url "file://$i"] # insteadOf = $REMOTE #EOF #done # make sure that some failure is reported if set -e kills the script. trap '{ if [ -z "$REACHED_THE_END" ]; then echo "FAIL: script died early" fi }' EXIT read_var() { local artifact_list=$1 local var=$2 grep "^${var}=" "${artifact_list}" | cut -d = -f 2- } relocate_manifest() { local ARTIFACTS="$1" local DEST="$2" mv "$(read_var ${ARTIFACTS} manifest)" "${DEST}" rm -f "${ARTIFACTS}" } validate_manifests() { "$ABE_TESTS_PATH"/validate-manifest.pl --verbose --no-online "$@" } # if the two manifests have different versions, only do generic validation # to allow the second manifest to have missing components validate_manifests_soft () { local RET=0 local version= local prev_version= local manifest_type_opt= for i in "$@"; do version=$(head -n 1 "${i}") if [ ! -z "${prev_version}" -a "${prev_version}" != "${version}" ]; then manifest_type_opt=--type=generic else manifest_type_opt= fi if ! "$ABE_TESTS_PATH"/validate-manifest.pl --verbose --no-online ${manifest_type_opt:+"$manifest_type_opt"} "$i"; then RET=1 fi prev_version=$version done return $RET } test_defaults() { set -ex TARGET=$(pick_target) $ABE_PATH/abe.sh --list-artifacts art.txt --checkout all --target "$TARGET" relocate_manifest art.txt mani1.txt $ABE_PATH/abe.sh --list-artifacts art.txt --checkout all --target "$TARGET" --enable update relocate_manifest art.txt mani2.txt validate_manifests mani1.txt mani2.txt } test_native() { set -ex $ABE_PATH/abe.sh --list-artifacts art.txt --checkout all relocate_manifest art.txt mani1.txt $ABE_PATH/abe.sh --list-artifacts art.txt --checkout all --enable update relocate_manifest art.txt mani2.txt # manifest validation fails for native builds because gdbserver # is not built, and we can't recognise a native build from the # manifest. #validate_manifests mani1.txt mani2.txt } test_extraconfigdir() { set -ex TARGET=$(pick_target) $ABE_PATH/abe.sh --list-artifacts art.txt --checkout all --target "$TARGET" --extraconfigdir "$ABE_PATH/config/$1" relocate_manifest art.txt mani1.txt $ABE_PATH/abe.sh --list-artifacts art.txt --checkout all --target "$TARGET" --extraconfigdir "$ABE_PATH/config/$1" --enable update relocate_manifest art.txt mani2.txt validate_manifests mani1.txt mani2.txt } test_gccver() { set -ex local gcc_ver_opt="$1" TARGET=$(pick_target) shift $ABE_PATH/abe.sh --list-artifacts art.txt --checkout all --target "$TARGET" "$gcc_ver_opt" relocate_manifest art.txt mani1.txt $ABE_PATH/abe.sh --list-artifacts art.txt --checkout all --target "$TARGET" "$gcc_ver_opt" --enable update relocate_manifest art.txt mani2.txt validate_manifests mani1.txt mani2.txt # we handle errors explicitly here, so switch off set -x, so that we get # nice output set +x local mani local val local result=PASS local id for mani in mani1.txt mani2.txt; do for val in "$@"; do if ! grep -q --line-regexp "$val" "$mani"; then result=FAIL id=$(echo "$val" | cut -d = -f 1) echo "FAIL: $mani: \"$(grep "^${id}=" "$mani")\" did not match expected \"$val\"" fi done done if [ x"$result" = x"FAIL" ]; then # messages handled by do_test exit 1 fi } test_unknown_branch() { set -ex TARGET=$(pick_target) ! $ABE_PATH/abe.sh --list-artifacts art.txt --checkout all --target "$TARGET" "$1" gcc=gcc.git~unknownbranch } helper_prev_abe() { local MANI="$1" shift mkdir part1 pushd part1 git new-workdir "$ABE_PATH" previous-abe "$(git -C "$ABE_PATH" rev-parse ${PREV_ABE_REVISION})" ./previous-abe/configure ${GIT_REF_OPT:+$GIT_REF_OPT} >& "configure.log" ./previous-abe/"$@" relocate_manifest art.txt ../$MANI popd } do_compare() { local SKIP_COMPARE=$1 shift local compare_ret=0 "$ABE_TESTS_PATH/compare-manifests.pl" "$@" || compare_ret=$? case "${compare_ret}-${SKIP_COMPARE}" in 0-false) echo "Manifests are equivalent"; result=0 ;; 0-true) echo "Manifests are equivalent, but configuration was tagged, so expecting mismatch."; result=1 ;; 1-false) echo "Manifests differ."; result=1 ;; 1-true) echo "Ignoring differing manifests due to tag in commit message."; result=0 ;; *) echo "error: Unknown state ${compare_ret}-${SKIP_COMPARE}!"; result=1 ;; esac return $result } test_previous_abe_manifest() { set -ex local SKIP_COMPARE=$1 shift TARGET=$(pick_target) helper_prev_abe mani1.txt abe.sh --list-artifacts art.txt --checkout all --target "$TARGET" --release foo "$@" "$ABE_PATH/abe.sh" --list-artifacts art.txt --checkout all --manifest mani1.txt "$@" relocate_manifest art.txt mani2.txt validate_manifests_soft mani1.txt mani2.txt do_compare "$SKIP_COMPARE" mani1.txt mani2.txt } test_previous_abe_cmd_line() { set -ex local SKIP_COMPARE=$1 shift TARGET=$(pick_target) helper_prev_abe mani1.txt abe.sh --list-artifacts art.txt --checkout all --target "$TARGET" --release foo "$@" "$ABE_PATH/abe.sh" --list-artifacts art.txt --checkout all --target $TARGET --release foo "$@" relocate_manifest art.txt mani2.txt validate_manifests mani1.txt mani2.txt # we ignore revisions here, because there could be a commit # in the upstream repos. do_compare "$SKIP_COMPARE" --ignore-revisions mani1.txt mani2.txt } manifest_after_1_4() { local mani_ver=$(grep ^manifest_format= "$1" | cut -d = -f 2) case "$mani_ver" in 1.[123]) return 1;; *) return 0;; esac } # check that mingw manifests match Linux manifests test_mingw() { set -ex TARGET=$(pick_target) $ABE_PATH/abe.sh --list-artifacts art.txt --checkout all --target "$TARGET" --release foo relocate_manifest art.txt mani1.txt $ABE_PATH/abe.sh --list-artifacts art.txt --checkout all --target "$TARGET" --host i686-w64-mingw32 --enable update --release foo relocate_manifest art.txt mani2.txt validate_manifests mani1.txt mani2.txt if manifest_after_1_4 mani1.txt; then "$ABE_TESTS_PATH/compare-manifests.pl" mani1.txt mani2.txt fi } do_test() { local LOGNAME="$1" shift NUM_TESTS=$((NUM_TESTS+1)) mkdir -p "workspace-$LOGNAME" pushd "workspace-$LOGNAME" >/dev/null # we use this trick because we need set -e to work inside the subshell # so we can't simply use || { RESULT=$? } RESULT=0 ( $ABE_PATH/configure ${GIT_REF_OPT:+$GIT_REF_OPT} >& "test_$LOGNAME.log" && "$@" &>> "test_$LOGNAME.log") & wait $! || RESULT=$? popd >/dev/null # advance TARGET_NUM after each test next_target if [ $RESULT -eq 0 ]; then NUM_PASS=$((NUM_PASS+1)) echo "PASS: $*" else NUM_FAIL=$((NUM_FAIL+1)) echo "FAIL: $* (See workspace-$LOGNAME/test_$LOGNAME.log, tail of log:)" tail workspace-$LOGNAME/test_$LOGNAME.log fi if [ $RESULT -eq 0 -a x"$GIT_REF_OPT_SET" = x"false" ]; then GIT_REF_OPT=--with-git-reference-dir=$TOP/workspace-$LOGNAME/snapshots GIT_REF_OPT_SET=true elif $CLEAN_SNAPSHOTS; then rm -Rf "workspace-$LOGNAME"/snapshots fi } scan_for_skip_tag() { local start=$1 local end=$2 local regexp=$3 local i for i in $(git -C "$ABE_PATH" rev-list "$start..$end"); do if git -C "$ABE_PATH" show --format=%B --no-patch "$i" | grep -q "$regexp"; then echo true return fi done echo false } NUM_FAIL=0 NUM_PASS=0 NUM_TESTS=0 if ! $ONLY_PREV_ABE; then do_test 'defaults' test_defaults do_test 'extraconfig49' test_extraconfigdir gcc4_9 do_test 'extraconfig5' test_extraconfigdir gcc5 do_test 'extraconfig6' test_extraconfigdir gcc6 do_test 'extraconfig7' test_extraconfigdir gcc7 do_test 'gccver_branch' test_gccver 'gcc=gcc.git~master' 'gcc_branch=master' do_test 'gccver_revision' test_gccver 'gcc=gcc.git@16b9ce8a3b10e8088a0bd6e62ca009aaf148e7ab' 'gcc_revision=16b9ce8a3b10e8088a0bd6e62ca009aaf148e7ab' do_test 'gccver_tag' test_gccver 'gcc=gcc.git~gcc-4_8_0-release' 'gcc_branch=gcc-4_8_0-release' 'gcc_revision=e9c762ec4671d77e301492e4f9e92e1d3d667188' do_test 'gccver_url' test_gccver 'gcc=http://snapshots.linaro.org/components/toolchain/gcc-linaro/6.2-2016.09/gcc-linaro-snapshot-6.2-2016.09.tar.xz' 'gcc_url=http://snapshots.linaro.org/components/toolchain/gcc-linaro/6.2-2016.09' 'gcc_filespec=gcc-linaro-snapshot-6.2-2016.09.tar.xz' do_test 'mingw' test_mingw do_test 'native' test_native do_test 'unknown_branch' test_unknown_branch fi PREV_TEST_SNAPSHOTS=$PWD/prev-test-snapshots mkdir -p "$PREV_TEST_SNAPSHOTS" # do tests for comparison of manifests with previous version. for configs in gcc4_9 gcc5 gcc6 gcc7; do CONFDIR=$ABE_PATH/config/$configs SKIP_PREV_MANI=$(scan_for_skip_tag "$PREV_ABE_REVISION" HEAD "\[ABE_PREV_MANIFEST_\(${configs^^}\|ALL\)\]") SKIP_PREV_CMD=$(scan_for_skip_tag "$PREV_ABE_REVISION" HEAD "\[ABE_PREV_CMD_\(${configs^^}\|ALL\)\]") do_test previous_abe_manifest_$configs test_previous_abe_manifest "$SKIP_PREV_MANI" --extraconfigdir "$CONFDIR" --snapshots "$PREV_TEST_SNAPSHOTS" do_test previous_abe_cmd_line_$configs test_previous_abe_cmd_line "$SKIP_PREV_CMD" --extraconfigdir "$CONFDIR" --snapshots "$PREV_TEST_SNAPSHOTS" done if $CLEAN_SNAPSHOTS; then rm -Rf "$PREV_TEST_SNAPSHOTS" fi echo Passed $NUM_PASS/$NUM_TESTS tests. REACHED_THE_END=1 if [ $NUM_FAIL -gt 0 ]; then exit 1 fi