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
diff --git a/compile.sh b/compile.sh
index b5a325e..e481690 100755
--- a/compile.sh
+++ b/compile.sh
@@ -53,12 +53,11 @@
 
 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 @@
   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 "${@}"
@@ -132,31 +126,6 @@
 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
 #
 if [ $DO_SRCS_TEST ]; then
diff --git a/scripts/bootstrap/bootstrap.sh b/scripts/bootstrap/bootstrap.sh
index c50afc2..eeac8d1 100755
--- a/scripts/bootstrap/bootstrap.sh
+++ b/scripts/bootstrap/bootstrap.sh
@@ -79,54 +79,3 @@
 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 8203e3d..fdc493c 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -452,6 +452,18 @@
 )
 
 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",
     srcs = ["rule_test_test.sh"],
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 0000000..7de2205
--- /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 7791a91..1906811 100755
--- a/src/test/shell/testenv.sh
+++ b/src/test/shell/testenv.sh
@@ -269,7 +269,7 @@
 # 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 " "
     }