|  | #!/bin/bash | 
|  | # | 
|  | # Copyright 2015 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. | 
|  | # | 
|  | # Testing environment for the Bazel integration tests | 
|  | # | 
|  | # TODO(bazel-team): This file is currently an append of the old testenv.sh and | 
|  | # test-setup.sh files. This must be cleaned up eventually. | 
|  |  | 
|  | # Windows | 
|  | PLATFORM="$(uname -s | tr 'A-Z' 'a-z')" | 
|  | function is_windows() { | 
|  | # On windows, the shell test is actually running on msys | 
|  | if [[ "${PLATFORM}" =~ msys_nt* ]]; then | 
|  | true | 
|  | else | 
|  | false | 
|  | fi | 
|  | } | 
|  |  | 
|  | # Set some environment variables needed on Windows. | 
|  | if is_windows; then | 
|  | # TODO(philwo) remove this once we have a Bazel release that includes the CL | 
|  | # moving the Windows-specific TEST_TMPDIR into TestStrategy. | 
|  | TEST_TMPDIR_BASENAME="$(basename "$TEST_TMPDIR")" | 
|  | export TEST_TMPDIR="c:/temp/${TEST_TMPDIR_BASENAME}" | 
|  |  | 
|  | # Bazel (TMPDIR) and Windows (TEMP, TMP) have three envvars that specify the | 
|  | # location of the temp directory... | 
|  | export TMPDIR="$TEST_TMPDIR" | 
|  | export TEMP="$TEST_TMPDIR" | 
|  | export TMP="$TEST_TMPDIR" | 
|  |  | 
|  | export JAVA_HOME="$(ls -d C:/Program\ Files/Java/jdk* | sort | tail -n 1)" | 
|  | export BAZEL_SH="c:/tools/msys64/usr/bin/bash.exe" | 
|  | export BAZEL_VC="c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC" | 
|  | if [ -x /c/Python27/python.exe ]; then | 
|  | export BAZEL_PYTHON="C:/Python27/python.exe" | 
|  | export PATH="/c/Python27:$PATH" | 
|  | elif [ -x /c/python_27_amd64/files/python.exe ]; then | 
|  | export BAZEL_PYTHON="C:/python_27_amd64/files/python.exe" | 
|  | export PATH="/c/python_27_amd64/files:$PATH" | 
|  | fi | 
|  | fi | 
|  |  | 
|  | # Make the command "bazel" available for tests. | 
|  | PATH_TO_BAZEL_BIN=$(rlocation io_bazel/src/bazel) | 
|  | PATH_TO_BAZEL_WRAPPER="$(dirname $(rlocation io_bazel/src/test/shell/bin/bazel))" | 
|  | # Convert PATH_TO_BAZEL_WRAPPER to Unix path style on Windows, because it will be | 
|  | # added into PATH. There's problem if PATH=C:/msys64/usr/bin:/usr/local, | 
|  | # because ':' is used as both path seperator and in C:/msys64/... | 
|  | if is_windows; then | 
|  | PATH_TO_BAZEL_WRAPPER="$(cygpath -u "$PATH_TO_BAZEL_WRAPPER")" | 
|  | fi | 
|  | if [ ! -f "${PATH_TO_BAZEL_WRAPPER}/bazel" ]; | 
|  | then | 
|  | echo "Unable to find the Bazel binary at $PATH_TO_BAZEL_WRAPPER/bazel" >&2 | 
|  | exit 1; | 
|  | fi | 
|  | export PATH="$PATH_TO_BAZEL_WRAPPER:$PATH" | 
|  |  | 
|  | ################### shell/bazel/testenv ################################## | 
|  | # Setting up the environment for Bazel integration tests. | 
|  | # | 
|  | [ -z "$TEST_SRCDIR" ] && { echo "TEST_SRCDIR not set!" >&2; exit 1; } | 
|  | BAZEL_RUNFILES="$TEST_SRCDIR/io_bazel" | 
|  |  | 
|  | if ! type rlocation &> /dev/null; then | 
|  | function rlocation() { | 
|  | if [[ "$1" = /* ]]; then | 
|  | echo $1 | 
|  | else | 
|  | echo "$TEST_SRCDIR/$1" | 
|  | fi | 
|  | } | 
|  | export -f rlocation | 
|  | fi | 
|  |  | 
|  | # WORKSPACE file | 
|  | workspace_file="${BAZEL_RUNFILES}/WORKSPACE" | 
|  |  | 
|  | # Bazel | 
|  | bazel_tree="$(rlocation io_bazel/src/test/shell/bazel/doc-srcs.zip)" | 
|  | bazel_data="${BAZEL_RUNFILES}" | 
|  |  | 
|  | # Java | 
|  | if is_windows; then | 
|  | jdk_dir="$(cygpath -m $(cd $(rlocation local_jdk/bin/java.exe)/../..; pwd))" | 
|  | else | 
|  | jdk_dir="${TEST_SRCDIR}/local_jdk" | 
|  | fi | 
|  | langtools="$(rlocation io_bazel/src/test/shell/bazel/langtools.jar)" | 
|  |  | 
|  | # Tools directory location | 
|  | tools_dir="$(dirname $(rlocation io_bazel/tools/BUILD))" | 
|  | langtools_dir="$(dirname $(rlocation io_bazel/third_party/java/jdk/langtools/BUILD))" | 
|  |  | 
|  | # Sandbox tools | 
|  | process_wrapper="${BAZEL_RUNFILES}/src/main/tools/process-wrapper" | 
|  | linux_sandbox="${BAZEL_RUNFILES}/src/main/tools/linux-sandbox" | 
|  |  | 
|  | # Test data | 
|  | testdata_path=${BAZEL_RUNFILES}/src/test/shell/bazel/testdata | 
|  | python_server="${BAZEL_RUNFILES}/src/test/shell/bazel/testing_server.py" | 
|  |  | 
|  | # Third-party | 
|  | MACHINE_TYPE="$(uname -m)" | 
|  | MACHINE_IS_64BIT='no' | 
|  | if [ "${MACHINE_TYPE}" = 'amd64' -o "${MACHINE_TYPE}" = 'x86_64' -o "${MACHINE_TYPE}" = 's390x' ]; then | 
|  | MACHINE_IS_64BIT='yes' | 
|  | fi | 
|  |  | 
|  | MACHINE_IS_Z='no' | 
|  | if [ "${MACHINE_TYPE}" = 's390x' ]; then | 
|  | MACHINE_IS_Z='yes' | 
|  | fi | 
|  |  | 
|  | case "${PLATFORM}" in | 
|  | darwin) | 
|  | if [ "${MACHINE_IS_64BIT}" = 'yes' ]; then | 
|  | protoc_compiler="${BAZEL_RUNFILES}/third_party/protobuf/protoc-osx-x86_64.exe" | 
|  | else | 
|  | protoc_compiler="${BAZEL_RUNFILES}/third_party/protobuf/protoc-osx-x86_32.exe" | 
|  | fi | 
|  | ;; | 
|  | *) | 
|  | if [ "${MACHINE_IS_64BIT}" = 'yes' ]; then | 
|  | if [ "${MACHINE_IS_Z}" = 'yes' ]; then | 
|  | protoc_compiler="${BAZEL_RUNFILES}//third_party/protobuf/protoc-linux-s390x_64.exe" | 
|  | else | 
|  | protoc_compiler="${BAZEL_RUNFILES}/third_party/protobuf/protoc-linux-x86_64.exe" | 
|  | fi | 
|  | else | 
|  | protoc_compiler="${BAZEL_RUNFILES}/third_party/protobuf/protoc-linux-x86_32.exe" | 
|  | fi | 
|  | ;; | 
|  | esac | 
|  |  | 
|  | if [ -z ${RUNFILES_MANIFEST_ONLY+x} ]; then | 
|  | junit_jar="${BAZEL_RUNFILES}/third_party/junit/junit-*.jar" | 
|  | hamcrest_jar="${BAZEL_RUNFILES}/third_party/hamcrest/hamcrest-*.jar" | 
|  | else | 
|  | junit_jar=$(rlocation io_bazel/third_party/junit/junit-.*.jar) | 
|  | hamcrest_jar=$(rlocation io_bazel/third_party/hamcrest/hamcrest-.*.jar) | 
|  | fi | 
|  |  | 
|  | # This function copies the tools directory from Bazel. | 
|  | function copy_tools_directory() { | 
|  | cp -RL ${tools_dir}/* tools | 
|  | # tools/jdk/BUILD file for JDK 7 is generated. | 
|  | if [ -f tools/jdk/BUILD.* ]; then | 
|  | cp tools/jdk/BUILD.* tools/jdk/BUILD | 
|  | chmod +w tools/jdk/BUILD | 
|  | fi | 
|  | # To support custom langtools | 
|  | cp ${langtools} tools/jdk/langtools.jar | 
|  | cat >>tools/jdk/BUILD <<'EOF' | 
|  | filegroup(name = "test-langtools", srcs = ["langtools.jar"]) | 
|  | EOF | 
|  |  | 
|  | mkdir -p third_party/java/jdk/langtools | 
|  | cp -R ${langtools_dir}/* third_party/java/jdk/langtools | 
|  |  | 
|  | chmod -R +w . | 
|  | mkdir -p tools/defaults | 
|  | touch tools/defaults/BUILD | 
|  |  | 
|  | mkdir -p third_party/py/gflags | 
|  | cat > third_party/py/gflags/BUILD <<EOF | 
|  | licenses(["notice"]) | 
|  | package(default_visibility = ["//visibility:public"]) | 
|  |  | 
|  | py_library( | 
|  | name = "gflags", | 
|  | ) | 
|  | EOF | 
|  | } | 
|  |  | 
|  | # Report whether a given directory name corresponds to a tools directory. | 
|  | function is_tools_directory() { | 
|  | case "$1" in | 
|  | third_party|tools|src) | 
|  | true | 
|  | ;; | 
|  | *) | 
|  | false | 
|  | ;; | 
|  | esac | 
|  | } | 
|  |  | 
|  | # Copy the examples of the base workspace | 
|  | function copy_examples() { | 
|  | EXAMPLE="$(cd $(dirname $(rlocation io_bazel/examples/cpp/BUILD))/..; pwd)" | 
|  | cp -RL ${EXAMPLE} . | 
|  | chmod -R +w . | 
|  | } | 
|  |  | 
|  | # | 
|  | # Find a random unused TCP port | 
|  | # | 
|  | pick_random_unused_tcp_port () { | 
|  | perl -MSocket -e ' | 
|  | sub CheckPort { | 
|  | my ($port) = @_; | 
|  | socket(TCP_SOCK, PF_INET, SOCK_STREAM, getprotobyname("tcp")) | 
|  | || die "socket(TCP): $!"; | 
|  | setsockopt(TCP_SOCK, SOL_SOCKET, SO_REUSEADDR, 1) | 
|  | || die "setsockopt(TCP): $!"; | 
|  | return 0 unless bind(TCP_SOCK, sockaddr_in($port, INADDR_ANY)); | 
|  | socket(UDP_SOCK, PF_INET, SOCK_DGRAM, getprotobyname("udp")) | 
|  | || die "socket(UDP): $!"; | 
|  | return 0 unless bind(UDP_SOCK, sockaddr_in($port, INADDR_ANY)); | 
|  | return 1; | 
|  | } | 
|  | for (1 .. 128) { | 
|  | my ($port) = int(rand() * 27000 + 32760); | 
|  | if (CheckPort($port)) { | 
|  | print "$port\n"; | 
|  | exit 0; | 
|  | } | 
|  | } | 
|  | print "NO_FREE_PORT_FOUND\n"; | 
|  | exit 1; | 
|  | ' | 
|  | } | 
|  |  | 
|  | # | 
|  | # A uniform SHA-256 commands that works accross platform | 
|  | # | 
|  | case "${PLATFORM}" in | 
|  | darwin) | 
|  | function sha256sum() { | 
|  | cat "$1" | shasum -a 256 | cut -f 1 -d " " | 
|  | } | 
|  | ;; | 
|  | *) | 
|  | # Under linux sha256sum should exists | 
|  | ;; | 
|  | esac | 
|  |  | 
|  | ################### shell/bazel/test-setup ############################### | 
|  | # Setup bazel for integration tests | 
|  | # | 
|  |  | 
|  | # OS X has a limit in the pipe length, so force the root to a shorter one | 
|  | bazel_root="${TEST_TMPDIR}/root" | 
|  | mkdir -p "${bazel_root}" | 
|  |  | 
|  | bazel_javabase="${jdk_dir}" | 
|  |  | 
|  | echo "bazel binary is at $PATH_TO_BAZEL_WRAPPER" | 
|  |  | 
|  | # Here we unset variable that were set by the invoking Blaze instance | 
|  | unset JAVA_RUNFILES | 
|  |  | 
|  | function setup_bazelrc() { | 
|  | cat >$TEST_TMPDIR/bazelrc <<EOF | 
|  | # Set the user root properly for this test invocation. | 
|  | startup --output_user_root=${bazel_root} | 
|  | # Set the correct javabase from the outer bazel invocation. | 
|  | startup --host_javabase=${bazel_javabase} | 
|  |  | 
|  | # Print all progress messages because we regularly grep the output in tests. | 
|  | common --show_progress_rate_limit=-1 | 
|  |  | 
|  | # Disable terminal-specific features. | 
|  | common --color=no --curses=no | 
|  |  | 
|  | build -j 8 | 
|  | ${EXTRA_BAZELRC:-} | 
|  | EOF | 
|  | } | 
|  |  | 
|  | function setup_android_sdk_support() { | 
|  | ANDROID_SDK=$PWD/android_sdk | 
|  | SDK_SRCDIR=$TEST_SRCDIR/androidsdk | 
|  | mkdir -p $ANDROID_SDK | 
|  | for i in $SDK_SRCDIR/*; do | 
|  | ln -s "$i" "$ANDROID_SDK/$(basename $i)" | 
|  | done | 
|  | ANDROID_SDK_API_LEVEL=$(ls $SDK_SRCDIR/platforms | cut -d '-' -f 2 | sort -n | tail -1) | 
|  | cat >> WORKSPACE <<EOF | 
|  | android_sdk_repository( | 
|  | name = "androidsdk", | 
|  | path = "$ANDROID_SDK", | 
|  | api_level = $ANDROID_SDK_API_LEVEL, | 
|  | ) | 
|  | EOF | 
|  | } | 
|  |  | 
|  | function setup_android_ndk_support() { | 
|  | ANDROID_NDK=$PWD/android_ndk | 
|  | NDK_SRCDIR=$TEST_SRCDIR/androidndk/ndk | 
|  | mkdir -p $ANDROID_NDK | 
|  | for i in $NDK_SRCDIR/*; do | 
|  | if [[ "$(basename $i)" != "BUILD" ]]; then | 
|  | ln -s "$i" "$ANDROID_NDK/$(basename $i)" | 
|  | fi | 
|  | done | 
|  | ANDROID_NDK_API_LEVEL=$(ls $NDK_SRCDIR/platforms | cut -d '-' -f 2 | sort -n | tail -1) | 
|  | cat >> WORKSPACE <<EOF | 
|  | android_ndk_repository( | 
|  | name = "androidndk", | 
|  | path = "$ANDROID_NDK", | 
|  | api_level = $ANDROID_NDK_API_LEVEL, | 
|  | ) | 
|  | EOF | 
|  | } | 
|  |  | 
|  | function setup_javatest_common() { | 
|  | # TODO(bazel-team): we should use remote repositories. | 
|  | mkdir -p third_party | 
|  | if [ ! -f third_party/BUILD ]; then | 
|  | cat <<EOF >third_party/BUILD | 
|  | package(default_visibility = ["//visibility:public"]) | 
|  | EOF | 
|  | fi | 
|  |  | 
|  | [ -e third_party/junit.jar ] || ln -s ${junit_jar} third_party/junit.jar | 
|  | [ -e third_party/hamcrest.jar ] \ | 
|  | || ln -s ${hamcrest_jar} third_party/hamcrest.jar | 
|  | } | 
|  |  | 
|  | function setup_javatest_support() { | 
|  | setup_javatest_common | 
|  | grep -q 'name = "junit4"' third_party/BUILD \ | 
|  | || cat <<EOF >>third_party/BUILD | 
|  | java_import( | 
|  | name = "junit4", | 
|  | jars = [ | 
|  | "junit.jar", | 
|  | "hamcrest.jar", | 
|  | ], | 
|  | ) | 
|  | EOF | 
|  | } | 
|  |  | 
|  | function setup_skylark_javatest_support() { | 
|  | setup_javatest_common | 
|  | grep -q "name = \"junit4-jars\"" third_party/BUILD \ | 
|  | || cat <<EOF >>third_party/BUILD | 
|  | filegroup( | 
|  | name = "junit4-jars", | 
|  | srcs = [ | 
|  | "junit.jar", | 
|  | "hamcrest.jar", | 
|  | ], | 
|  | ) | 
|  | EOF | 
|  | } | 
|  |  | 
|  | # Sets up Objective-C tools. Mac only. | 
|  | function setup_objc_test_support() { | 
|  | IOS_SDK_VERSION=$(xcrun --sdk iphoneos --show-sdk-version) | 
|  | } | 
|  |  | 
|  | workspaces=() | 
|  | # Set-up a new, clean workspace with only the tools installed. | 
|  | function create_new_workspace() { | 
|  | new_workspace_dir=${1:-$(mktemp -d ${TEST_TMPDIR}/workspace.XXXXXXXX)} | 
|  | rm -fr ${new_workspace_dir} | 
|  | mkdir -p ${new_workspace_dir} | 
|  | workspaces+=(${new_workspace_dir}) | 
|  | cd ${new_workspace_dir} | 
|  | mkdir tools | 
|  | mkdir -p third_party/java/jdk/langtools | 
|  |  | 
|  | copy_tools_directory | 
|  |  | 
|  | [ -e third_party/java/jdk/langtools/javac-9-dev-r3297-4.jar ] \ | 
|  | || ln -s "${langtools_path}"  third_party/java/jdk/langtools/javac-9-dev-r3297-4.jar | 
|  |  | 
|  | touch WORKSPACE | 
|  | } | 
|  |  | 
|  | # Set-up a clean default workspace. | 
|  | function setup_clean_workspace() { | 
|  | export WORKSPACE_DIR=${TEST_TMPDIR}/workspace | 
|  | echo "setting up client in ${WORKSPACE_DIR}" > $TEST_log | 
|  | rm -fr ${WORKSPACE_DIR} | 
|  | create_new_workspace ${WORKSPACE_DIR} | 
|  | [ "${new_workspace_dir}" = "${WORKSPACE_DIR}" ] || \ | 
|  | { echo "Failed to create workspace" >&2; exit 1; } | 
|  | export BAZEL_INSTALL_BASE=$(bazel info install_base) | 
|  | export BAZEL_GENFILES_DIR=$(bazel info bazel-genfiles) | 
|  | export BAZEL_BIN_DIR=$(bazel info bazel-bin) | 
|  | if is_windows; then | 
|  | export BAZEL_SH="$(cygpath --windows /bin/bash)" | 
|  | fi | 
|  | } | 
|  |  | 
|  | # Clean up all files that are not in tools directories, to restart | 
|  | # from a clean workspace | 
|  | function cleanup_workspace() { | 
|  | if [ -d "${WORKSPACE_DIR:-}" ]; then | 
|  | echo "Cleaning up workspace" > $TEST_log | 
|  | cd ${WORKSPACE_DIR} | 
|  | bazel clean >& $TEST_log # Clean up the output base | 
|  |  | 
|  | for i in $(ls); do | 
|  | if ! is_tools_directory "$i"; then | 
|  | rm -fr "$i" | 
|  | fi | 
|  | done | 
|  | touch WORKSPACE | 
|  | fi | 
|  | for i in ${workspaces}; do | 
|  | if [ "$i" != "${WORKSPACE_DIR:-}" ]; then | 
|  | rm -fr $i | 
|  | fi | 
|  | done | 
|  | workspaces=() | 
|  | } | 
|  |  | 
|  | # Clean-up the bazel install base | 
|  | function cleanup() { | 
|  | if [ -d "${BAZEL_INSTALL_BASE:-__does_not_exists__}" ]; then | 
|  | rm -fr "${BAZEL_INSTALL_BASE}" | 
|  | fi | 
|  | } | 
|  |  | 
|  | function tear_down() { | 
|  | cleanup_workspace | 
|  | } | 
|  |  | 
|  | # | 
|  | # Simples assert to make the tests more readable | 
|  | # | 
|  | function assert_build() { | 
|  | bazel build -s --verbose_failures $* || fail "Failed to build $*" | 
|  | } | 
|  |  | 
|  | function assert_build_output() { | 
|  | local OUTPUT=$1 | 
|  | shift | 
|  | assert_build "$*" | 
|  | test -f "$OUTPUT" || fail "Output $OUTPUT not found for target $*" | 
|  | } | 
|  |  | 
|  | function assert_build_fails() { | 
|  | bazel build -s $1 >& $TEST_log \ | 
|  | && fail "Test $1 succeed while expecting failure" \ | 
|  | || true | 
|  | if [ -n "${2:-}" ]; then | 
|  | expect_log "$2" | 
|  | fi | 
|  | } | 
|  |  | 
|  | function assert_test_ok() { | 
|  | bazel test --test_output=errors $* >& $TEST_log \ | 
|  | || fail "Test $1 failed while expecting success" | 
|  | } | 
|  |  | 
|  | function assert_test_fails() { | 
|  | bazel test --test_output=errors $* >& $TEST_log \ | 
|  | && fail "Test $* succeed while expecting failure" \ | 
|  | || true | 
|  | expect_log "$1.*FAILED" | 
|  | } | 
|  |  | 
|  | function assert_binary_run() { | 
|  | $1 >& $TEST_log || fail "Failed to run $1" | 
|  | [ -z "${2:-}" ] || expect_log "$2" | 
|  | } | 
|  |  | 
|  | function assert_bazel_run() { | 
|  | bazel run $1 >& $TEST_log || fail "Failed to run $1" | 
|  | [ -z "${2:-}" ] || expect_log "$2" | 
|  |  | 
|  | assert_binary_run "./bazel-bin/$(echo "$1" | sed 's|^//||' | sed 's|:|/|')" "${2:-}" | 
|  | } | 
|  |  | 
|  | setup_bazelrc | 
|  | setup_clean_workspace | 
|  |  | 
|  | ################### shell/integration/testenv ############################ | 
|  | # Setting up the environment for our legacy integration tests. | 
|  | # | 
|  | PRODUCT_NAME=bazel | 
|  | WORKSPACE_NAME=main | 
|  | bazelrc=$TEST_TMPDIR/bazelrc | 
|  |  | 
|  | function put_bazel_on_path() { | 
|  | # do nothing as test-setup already does that | 
|  | true | 
|  | } | 
|  |  | 
|  | function write_default_bazelrc() { | 
|  | setup_bazelrc | 
|  | } | 
|  |  | 
|  | function add_to_bazelrc() { | 
|  | echo "$@" >> $bazelrc | 
|  | } | 
|  |  | 
|  | function create_and_cd_client() { | 
|  | setup_clean_workspace | 
|  | echo "workspace(name = '$WORKSPACE_NAME')" >WORKSPACE | 
|  | touch .bazelrc | 
|  | } | 
|  |  | 
|  | ################### Extra ############################ | 
|  | # Functions that need to be called before each test. | 
|  | create_and_cd_client |