From da1d416f83942dc1b1b203cdd4d79c47fce7335f Mon Sep 17 00:00:00 2001 From: Damien Martin-Guillerez Date: Wed, 23 Aug 2017 12:19:25 +0200 Subject: Add a Bazel test testing determinism of `bazel build //src:bazel` - Test if hash(bazel1) == hash(bazel2) This ensure that the build of bazel is a fixed point. Change-Id: I422dfc7ec5b95aa054a2677e59427cbd8cd4ef01 PiperOrigin-RevId: 166180529 --- compile.sh | 35 +------------ scripts/bootstrap/bootstrap.sh | 51 ------------------ src/test/shell/bazel/BUILD | 12 +++++ src/test/shell/bazel/bazel_determinism_test.sh | 71 ++++++++++++++++++++++++++ src/test/shell/testenv.sh | 2 +- 5 files changed, 86 insertions(+), 85 deletions(-) create mode 100644 src/test/shell/bazel/bazel_determinism_test.sh diff --git a/compile.sh b/compile.sh index b5a325e937..e481690e27 100755 --- a/compile.sh +++ b/compile.sh @@ -53,12 +53,11 @@ source scripts/bootstrap/buildenv.sh function usage() { [ -n "${1:-compile}" ] && echo "Invalid command(s): $1" >&2 - echo "syntax: $0 [command[,command]* [BAZEL_BIN [BAZEL_SUM]]]" >&2 + echo "syntax: $0 [command[,command]* [BAZEL_BIN]]" >&2 echo " General purpose commands:" >&2 echo " compile = compile the bazel binary (default)" >&2 echo " Commands for developers:" >&2 - echo " all = compile,determinism,test" >&2 - echo " determinism = test for stability of Bazel builds" >&2 + echo " all = compile,srcs,test" >&2 echo " srcs = test that //:srcs contains all the sources" >&2 echo " test = run the full test suite of Bazel" >&2 exit 1 @@ -69,18 +68,13 @@ function parse_options() { COMMANDS="${1:-compile}" [[ "${COMMANDS}" =~ ^$keywords(,$keywords)*$ ]] || usage "$@" DO_COMPILE= - DO_CHECKSUM= - DO_FULL_CHECKSUM=1 DO_TESTS= DO_SRCS_TEST= [[ "${COMMANDS}" =~ (compile|all) ]] && DO_COMPILE=1 - [[ "${COMMANDS}" =~ (bootstrap|determinism|all) ]] && DO_CHECKSUM=1 - [[ "${COMMANDS}" =~ (bootstrap) ]] && DO_FULL_CHECKSUM= [[ "${COMMANDS}" =~ (srcs|all) ]] && DO_SRCS_TEST=1 [[ "${COMMANDS}" =~ (test|all) ]] && DO_TESTS=1 BAZEL_BIN=${2:-"bazel-bin/src/bazel"} - BAZEL_SUM=${3:-"x"} } parse_options "${@}" @@ -131,31 +125,6 @@ if [ $DO_COMPILE ]; then BAZEL="$(pwd)/output/bazel${EXE_EXT}" fi -# -# Output is deterministic between two bootstrapped bazel binary using the actual tools and the -# released binary. -# -if [ $DO_CHECKSUM ]; then - new_step "Determinism test" - if [ ! -f ${BAZEL_SUM:-x} ]; then - BAZEL_SUM=bazel-out/bazel_checksum - log "First build" - bootstrap_test ${BAZEL} ${BAZEL_SUM} - else - BOOTSTRAP=${BAZEL} - fi - if [ "${BAZEL_SUM}" != "${OUTPUT_DIR}/bazel_checksum" ]; then - cp ${BAZEL_SUM} ${OUTPUT_DIR}/bazel_checksum - fi - if [ $DO_FULL_CHECKSUM ]; then - log "Second build" - bootstrap_test ${BOOTSTRAP} bazel-out/bazel_checksum - log "Comparing output" - (diff -U 0 ${OUTPUT_DIR}/bazel_checksum bazel-out/bazel_checksum >&2) \ - || fail "Differences detected in outputs!" - fi -fi - # # Test that //:srcs contains all the sources # diff --git a/scripts/bootstrap/bootstrap.sh b/scripts/bootstrap/bootstrap.sh index c50afc249a..eeac8d1d20 100755 --- a/scripts/bootstrap/bootstrap.sh +++ b/scripts/bootstrap/bootstrap.sh @@ -79,54 +79,3 @@ function bazel_build() { function get_bazel_bin_path() { _run_bootstrapping_bazel info "bazel-bin" || echo "bazel-bin" } - -function md5_outputs() { - [ -n "${BAZEL_TEST_XTRACE:-}" ] && set +x # Avoid garbage in the output - # runfiles/MANIFEST & runfiles_manifest contain absolute path, ignore. - # ar on OS-X is non-deterministic, ignore .a files. - for i in $(find bazel-bin/ -type f -a \! -name MANIFEST -a \! -name '*.runfiles_manifest' -a \! -name '*.a'); do - md5_file $i - done - for i in $(find bazel-genfiles/ -type f); do - md5_file $i - done - [ -n "${BAZEL_TEST_XTRACE:-}" ] && set -x -} - -function get_outputs_sum() { - md5_outputs | sort -k 2 -} - -function bootstrap_test() { - local BAZEL_BIN=$1 - local BAZEL_SUM=$2 - local BAZEL_TARGET=${3:-src:bazel} - local STRATEGY="--strategy=Javac=worker --worker_quit_after_build" - if [ "${JAVA_VERSION}" = "1.7" ]; then - STRATEGY= - fi - [ -x "${BAZEL_BIN}" ] || fail "syntax: bootstrap bazel-binary" - run ${BAZEL_BIN} --nomaster_bazelrc --bazelrc=${BAZELRC} \ - ${BAZEL_DIR_STARTUP_OPTIONS} \ - clean \ - --expunge || return $? - run ${BAZEL_BIN} --nomaster_bazelrc --bazelrc=${BAZELRC} \ - ${BAZEL_DIR_STARTUP_OPTIONS} \ - build \ - ${EXTRA_BAZEL_ARGS-} ${STRATEGY} \ - --fetch --nostamp \ - --define "JAVA_VERSION=${JAVA_VERSION}" \ - --javacopt="-g -source ${JAVA_VERSION} -target ${JAVA_VERSION}" \ - ${BAZEL_TARGET} || return $? - if [ -n "${BAZEL_SUM}" ]; then - cat bazel-genfiles/src/java.version >${BAZEL_SUM} - get_outputs_sum >> ${BAZEL_SUM} || return $? - fi - if [ -z "${BOOTSTRAP:-}" ]; then - tempdir - BOOTSTRAP=${NEW_TMPDIR}/bazel - local FILE=bazel-bin/${BAZEL_TARGET##//} - cp -f ${FILE/:/\/} $BOOTSTRAP - chmod +x $BOOTSTRAP - fi -} diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD index 8203e3d36c..fdc493cfd5 100644 --- a/src/test/shell/bazel/BUILD +++ b/src/test/shell/bazel/BUILD @@ -451,6 +451,18 @@ sh_test( tags = ["jdk8"], ) +sh_test( + name = "bazel_determinism_test", + timeout = "eternal", + srcs = ["bazel_determinism_test.sh"], + args = ["$(location //:bazel-distfile)"], + data = [ + ":test-deps", + "//:bazel-distfile", + ], + tags = ["jdk8"], +) + sh_test( name = "rule_test_test", size = "medium", diff --git a/src/test/shell/bazel/bazel_determinism_test.sh b/src/test/shell/bazel/bazel_determinism_test.sh new file mode 100644 index 0000000000..7de2205112 --- /dev/null +++ b/src/test/shell/bazel/bazel_determinism_test.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# +# Copyright 2016 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Test that bootstrapping bazel is a fixed point +# + +set -u +DISTFILE=$(rlocation io_bazel/${1#./}) +shift 1 + +if [ "${JAVA_VERSION:-}" == "1.7" ] ; then + echo "Warning: bootstrapping not tested for java 1.7" + exit 0 +fi + +# Load the test setup defined in the parent directory +source $(rlocation io_bazel/src/test/shell/integration_test_setup.sh) \ + || { echo "integration_test_setup.sh not found!" >&2; exit 1; } + +function hash_outputs() { + [ -n "${BAZEL_TEST_XTRACE:-}" ] && set +x # Avoid garbage in the output + # runfiles/MANIFEST & runfiles_manifest contain absolute path, ignore. + # ar on OS-X is non-deterministic, ignore .a files. + for i in $(find bazel-bin/ -type f -a \! -name MANIFEST -a \! -name '*.runfiles_manifest' -a \! -name '*.a'); do + sha256sum $i + done + for i in $(find bazel-genfiles/ -type f); do + sha256sum $i + done + [ -n "${BAZEL_TEST_XTRACE:-}" ] && set -x +} + +function get_outputs_sum() { + hash_outputs | sort -k 2 +} + +function test_determinism() { + local olddir=$(pwd) + WRKDIR=$(mktemp -d ${TEST_TMPDIR}/bazelbootstrap.XXXXXXXX) + mkdir -p "${WRKDIR}" || fail "Could not create workdir" + trap "rm -rf \"$WRKDIR\"" EXIT + cd "${WRKDIR}" || fail "Could not change to work directory" + unzip -q ${DISTFILE} + # Compile bazel a first time + bazel build --nostamp src:bazel + cp bazel-bin/src/bazel bazel1 + get_outputs_sum >"${TEST_TMPDIR}/sum1" + ./bazel1 clean --expunge + ./bazel1 build --nostamp src:bazel + get_outputs_sum >"${TEST_TMPDIR}/sum2" + if ! (diff -q "${TEST_TMPDIR}/sum1" "${TEST_TMPDIR}/sum2"); then + diff -U0 "${TEST_TMPDIR}/sum1" "${TEST_TMPDIR}/sum2" >$TEST_log + fail "Non deterministic outputs found!" + fi +} + +run_suite "determinism test" diff --git a/src/test/shell/testenv.sh b/src/test/shell/testenv.sh index 7791a91c4e..1906811515 100755 --- a/src/test/shell/testenv.sh +++ b/src/test/shell/testenv.sh @@ -269,7 +269,7 @@ exit 1; # A uniform SHA-256 commands that works accross platform # case "${PLATFORM}" in - darwin) + darwin|freebsd) function sha256sum() { cat "$1" | shasum -a 256 | cut -f 1 -d " " } -- cgit v1.2.3