From 9d3084938d6f8e015e7b77812371dcbf2662b02c Mon Sep 17 00:00:00 2001 From: Yun Peng Date: Tue, 8 Aug 2023 00:49:00 -0700 Subject: [PATCH] Prepare for enabling Bzlmod for Bazel - Update MODULE.bazel for missing dependencies - Fix tests broken by repo mappings PiperOrigin-RevId: 554726284 Change-Id: I756041a126a9d0b4f1a26ebe264e23178c23f977 --- MODULE.bazel | 62 +++++++++++++------ extensions.bzl | 3 + rbe_extension.bzl | 27 ++++++++ scripts/BUILD | 1 + scripts/bash_completion_test.sh | 13 +++- scripts/testenv.sh | 13 +++- .../bazel/android/aar_integration_test.sh | 2 +- .../shell/bazel/embedded_tools_deps_test.sh | 2 +- src/test/shell/bazel/java_launcher_test.sh | 14 +++-- src/test/shell/integration/BUILD | 1 + .../integration/execution_phase_tests.sh | 31 +++------- .../integration/modify_execution_info_test.sh | 2 +- ...rget_compatible_with_test_external_repo.sh | 32 +++------- src/test/shell/testenv.sh.tmpl | 2 +- third_party/ijar/test/BUILD | 17 +++-- third_party/ijar/test/testenv.sh | 13 +++- 16 files changed, 152 insertions(+), 83 deletions(-) create mode 100644 rbe_extension.bzl diff --git a/MODULE.bazel b/MODULE.bazel index 340a3329e3fd4c..30f4628635c536 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,3 +1,5 @@ +"""Bazel build and test dependencies.""" + module( name = "bazel", version = "7.0.0-pre", @@ -11,7 +13,7 @@ bazel_dep(name = "grpc", version = "1.48.1.bcr.1", repo_name = "com_github_grpc_ bazel_dep(name = "platforms", version = "0.0.7") bazel_dep(name = "rules_pkg", version = "0.7.0") bazel_dep(name = "stardoc", version = "0.5.3", repo_name = "io_bazel_skydoc") -bazel_dep(name = "zstd-jni", version = "1.5.2-3") +bazel_dep(name = "zstd-jni", version = "1.5.2-3.bcr.1") bazel_dep(name = "blake3", version = "1.3.3") bazel_dep(name = "zlib", version = "1.2.13") bazel_dep(name = "rules_cc", version = "0.0.8") @@ -42,7 +44,7 @@ local_path_override( ) # ========================================= -# Bazel Java dependencies +# Java dependencies # ========================================= maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") @@ -57,6 +59,9 @@ maven.install( ) use_repo(maven, "maven") +java_toolchains = use_extension("@rules_java//java:extensions.bzl", "toolchains") +use_repo(java_toolchains, "local_jdk") + # ========================================= # Other Bazel internal dependencies # - embedded JDKs @@ -85,10 +90,44 @@ register_execution_platforms("//:default_host_platform") register_toolchains("@bazel_tools//tools/python:autodetecting_toolchain") +register_toolchains("@local_config_winsdk//:all") + register_toolchains("//src/main/res:empty_rc_toolchain") # ========================================= -# Android tools dependencies +# Python dependencies +# ========================================= + +python = use_extension("@rules_python//python/extensions:python.bzl", "python") +python.toolchain(python_version = "3.8") + +pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") +pip.parse( + hub_name = "bazel_pip_dev_deps", + python_version = "3.8", + requirements_lock = "//:requirements.txt", +) +use_repo(pip, "bazel_pip_dev_deps") + +# ========================================= +# Other dev dependencies +# ========================================= + +bazel_dep(name = "googletest", version = "1.12.1", repo_name = "com_google_googletest") + +bazel_dev_deps = use_extension("//:extensions.bzl", "bazel_dev_deps") +use_repo( + bazel_dev_deps, + "local_bazel_source_list", + "local_config_winsdk", + "bazelci_rules", +) + +bazel_rbe_deps = use_extension("//:rbe_extension.bzl", "bazel_rbe_deps") +use_repo(bazel_rbe_deps, "rbe_ubuntu1804_java11") + +# ========================================= +# Android tools Java dependencies # ========================================= maven_android = use_extension("@rules_jvm_external//:extensions.bzl", "maven") @@ -111,20 +150,3 @@ use_repo( "android_gmaven_r8", "desugar_jdk_libs", ) - -# ========================================= -# Bazel dev dependencies -# ========================================= - -bazel_dep(name = "googletest", version = "1.12.1", repo_name = "com_google_googletest") - -bazel_dev_deps = use_extension("//:extensions.bzl", "bazel_dev_deps") -use_repo(bazel_dev_deps, "local_bazel_source_list") - -pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") -pip.parse( - hub_name = "bazel_pip_dev_deps", - python_version = "3.8", - requirements_lock = "//:requirements.txt", -) -use_repo(pip, "bazel_pip_dev_deps") diff --git a/extensions.bzl b/extensions.bzl index 1e38f0a4bcae03..de87962a44abb2 100644 --- a/extensions.bzl +++ b/extensions.bzl @@ -20,6 +20,7 @@ load("//:repositories.bzl", "embedded_jdk_repositories") load("//:distdir.bzl", "dist_http_archive", "dist_http_jar") load("//tools/distributions/debian:deps.bzl", "debian_deps") load("//src/test/shell/bazel:list_source_repository.bzl", "list_source_repository") +load("//src/main/res:winsdk_configure.bzl", "winsdk_configure") ### Extra dependencies for building Bazel @@ -33,6 +34,8 @@ bazel_internal_deps = module_extension(implementation = _bazel_internal_deps) def _bazel_dev_deps(_ctx): list_source_repository(name = "local_bazel_source_list") + dist_http_archive(name = "bazelci_rules") + winsdk_configure(name = "local_config_winsdk") bazel_dev_deps = module_extension(implementation = _bazel_dev_deps) diff --git a/rbe_extension.bzl b/rbe_extension.bzl new file mode 100644 index 00000000000000..8c4ba715387140 --- /dev/null +++ b/rbe_extension.bzl @@ -0,0 +1,27 @@ +# Copyright 2023 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. + +"""Module extensions for loading RBE toolchains. + +""" + +load("@bazelci_rules//:rbe_repo.bzl", "rbe_preconfig") + +def _bazel_rbe_deps(_ctx): + rbe_preconfig( + name = "rbe_ubuntu1804_java11", + toolchain = "ubuntu1804-bazel-java11", + ) + +bazel_rbe_deps = module_extension(implementation = _bazel_rbe_deps) diff --git a/scripts/BUILD b/scripts/BUILD index c477439950b45c..badb397ca7d154 100644 --- a/scripts/BUILD +++ b/scripts/BUILD @@ -33,6 +33,7 @@ sh_test( "bazel-complete.bash", "testenv.sh", "//src/test/shell:bashunit", + "@bazel_tools//tools/bash/runfiles", ], ) diff --git a/scripts/bash_completion_test.sh b/scripts/bash_completion_test.sh index 6f6929e70ae5d8..50a808ecbde76e 100755 --- a/scripts/bash_completion_test.sh +++ b/scripts/bash_completion_test.sh @@ -16,7 +16,16 @@ # # bash_completion_test.sh: tests of bash command completion. -set -euo pipefail +# --- begin runfiles.bash initialization v3 --- +# Copy-pasted from the Bazel Bash runfiles library v3. +set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v3 --- : ${DIR:=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)} source ${DIR}/testenv.sh || { echo "testenv.sh not found!" >&2; exit 1; } @@ -25,7 +34,7 @@ source ${DIR}/testenv.sh || { echo "testenv.sh not found!" >&2; exit 1; } : ${COMMAND_ALIASES:=bazel} # Completion script -: ${COMPLETION:="$TEST_SRCDIR/io_bazel/scripts/bazel-complete.bash"} +: ${COMPLETION:="$(rlocation io_bazel/scripts/bazel-complete.bash)"} # Set this to test completion with package path (if enabled) : ${PACKAGE_PATH_PREFIX:=} diff --git a/scripts/testenv.sh b/scripts/testenv.sh index 25fa4ebfd757aa..589b97f52feb30 100755 --- a/scripts/testenv.sh +++ b/scripts/testenv.sh @@ -16,10 +16,19 @@ # # Setting up the environment for Bazel completion script test -[ -z "$TEST_SRCDIR" ] && { echo "TEST_SRCDIR not set!" >&2; exit 1; } +# --- begin runfiles.bash initialization v3 --- +# Copy-pasted from the Bazel Bash runfiles library v3. +set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v3 --- # Load the unit-testing framework -source "${TEST_SRCDIR}/io_bazel/src/test/shell/unittest.bash" \ +source "$(rlocation io_bazel/src/test/shell/unittest.bash)" \ || { echo "Failed to source unittest.bash" >&2; exit 1; } set_up() { diff --git a/src/test/shell/bazel/android/aar_integration_test.sh b/src/test/shell/bazel/android/aar_integration_test.sh index 3d838592732f0e..283e1311e58740 100755 --- a/src/test/shell/bazel/android/aar_integration_test.sh +++ b/src/test/shell/bazel/android/aar_integration_test.sh @@ -125,7 +125,7 @@ function test_android_binary_fat_apk_contains_all_shared_libraries() { add_to_bazelrc "build --noincompatible_enable_android_toolchain_resolution" # sample.aar contains native shared libraries for x86 and armeabi-v7a - cp "${TEST_SRCDIR}/io_bazel/src/test/shell/bazel/android/sample.aar" . + cp "$(rlocation io_bazel/src/test/shell/bazel/android/sample.aar)" . cat > AndroidManifest.xml < EOF diff --git a/src/test/shell/bazel/embedded_tools_deps_test.sh b/src/test/shell/bazel/embedded_tools_deps_test.sh index 6cd54206b35e10..d3064ab4c81d84 100755 --- a/src/test/shell/bazel/embedded_tools_deps_test.sh +++ b/src/test/shell/bazel/embedded_tools_deps_test.sh @@ -42,7 +42,7 @@ fi # Sort the targets for a deterministic diffing experience. current_deps="${TEST_TMPDIR}/current_deps" grep -v "^@bazel_tools//\|^@remote_java_tools\|^@debian_cc_deps" \ - "${TEST_SRCDIR}/io_bazel/src/test/shell/bazel/embedded_tools_deps" \ + "$(rlocation io_bazel/src/test/shell/bazel/embedded_tools_deps)" \ | sort >"${current_deps}" # TODO: This is a temporary hack to make this test works both before and after diff --git a/src/test/shell/bazel/java_launcher_test.sh b/src/test/shell/bazel/java_launcher_test.sh index bc0c6b00d515e0..2d86f00dcc08e6 100755 --- a/src/test/shell/bazel/java_launcher_test.sh +++ b/src/test/shell/bazel/java_launcher_test.sh @@ -14,10 +14,16 @@ # See the License for the specific language governing permissions and # limitations under the License. -if ! type rlocation &> /dev/null; then - # rlocation is a function defined in testenv.sh - exit 1 -fi +# --- begin runfiles.bash initialization v3 --- +# Copy-pasted from the Bazel Bash runfiles library v3. +set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v3 --- source "$(rlocation "io_bazel/src/test/shell/integration_test_setup.sh")" \ || { echo "integration_test_setup.sh not found!" >&2; exit 1; } diff --git a/src/test/shell/integration/BUILD b/src/test/shell/integration/BUILD index 05755b31570c25..cab3d59c49949b 100644 --- a/src/test/shell/integration/BUILD +++ b/src/test/shell/integration/BUILD @@ -368,6 +368,7 @@ sh_test( data = [ ":rules_proto_stanza.txt", ":test-deps", + "//third_party/zlib", "@bazel_tools//tools/bash/runfiles", ], ) diff --git a/src/test/shell/integration/execution_phase_tests.sh b/src/test/shell/integration/execution_phase_tests.sh index 214e5641673f06..61376e24a37e37 100755 --- a/src/test/shell/integration/execution_phase_tests.sh +++ b/src/test/shell/integration/execution_phase_tests.sh @@ -18,27 +18,16 @@ # behaviors that affect the execution phase. # -# --- begin runfiles.bash initialization --- -set -euo pipefail -if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then - if [[ -f "$TEST_SRCDIR/MANIFEST" ]]; then - export RUNFILES_MANIFEST_FILE="$TEST_SRCDIR/MANIFEST" - elif [[ -f "$0.runfiles/MANIFEST" ]]; then - export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST" - elif [[ -f "$TEST_SRCDIR/io_bazel/tools/bash/runfiles/runfiles.bash" ]]; then - export RUNFILES_DIR="$TEST_SRCDIR" - fi -fi -if [[ -f "${RUNFILES_DIR:-/dev/null}/io_bazel/tools/bash/runfiles/runfiles.bash" ]]; then - source "${RUNFILES_DIR}/io_bazel/tools/bash/runfiles/runfiles.bash" -elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then - source "$(grep -m1 "^io_bazel/tools/bash/runfiles/runfiles.bash " \ - "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)" -else - echo >&2 "ERROR: cannot find //third_party/bazel/tools/bash/runfiles:runfiles.bash" - exit 1 -fi -# --- end runfiles.bash initialization --- +# --- begin runfiles.bash initialization v3 --- +# Copy-pasted from the Bazel Bash runfiles library v3. +set -uo pipefail; set +e; f=io_bazel/tools/bash/runfiles/runfiles.bash +source "${TEST_SRCDIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${TEST_SRCDIR:-/dev/null}/MANIFEST" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v3 --- source "$(rlocation "io_bazel/src/test/shell/integration_test_setup.sh")" \ || { echo "integration_test_setup.sh not found!" >&2; exit 1; } diff --git a/src/test/shell/integration/modify_execution_info_test.sh b/src/test/shell/integration/modify_execution_info_test.sh index 36607b618d057f..9e98dc7fc21fbe 100755 --- a/src/test/shell/integration/modify_execution_info_test.sh +++ b/src/test/shell/integration/modify_execution_info_test.sh @@ -160,7 +160,7 @@ rules_proto_toolchains() # @com_google_protobuf//:protoc depends on @io_bazel//third_party/zlib. new_local_repository( name = "io_bazel", - path = "$(dirname $(rlocation io_bazel/third_party/zlib))/..", + path = "$(dirname $(dirname $(dirname $(rlocation io_bazel/third_party/zlib/BUILD))))", build_file_content = "# Intentionally left empty.", workspace_file_content = "workspace(name = 'io_bazel')", ) diff --git a/src/test/shell/integration/target_compatible_with_test_external_repo.sh b/src/test/shell/integration/target_compatible_with_test_external_repo.sh index 544e9418c1514d..17ddc277f73de6 100755 --- a/src/test/shell/integration/target_compatible_with_test_external_repo.sh +++ b/src/test/shell/integration/target_compatible_with_test_external_repo.sh @@ -16,28 +16,16 @@ # # target_compatible_with.sh variations for external repos. -# --- begin runfiles.bash initialization --- -set -euo pipefail - -if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then - if [[ -f "$TEST_SRCDIR/MANIFEST" ]]; then - export RUNFILES_MANIFEST_FILE="$TEST_SRCDIR/MANIFEST" - elif [[ -f "$0.runfiles/MANIFEST" ]]; then - export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST" - elif [[ -f "$TEST_SRCDIR/io_bazel/tools/bash/runfiles/runfiles.bash" ]]; then - export RUNFILES_DIR="$TEST_SRCDIR" - fi -fi -if [[ -f "${RUNFILES_DIR:-/dev/null}/io_bazel/tools/bash/runfiles/runfiles.bash" ]]; then - source "${RUNFILES_DIR}/io_bazel/tools/bash/runfiles/runfiles.bash" -elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then - source "$(grep -m1 "^io_bazel/tools/bash/runfiles/runfiles.bash " \ - "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)" -else - echo >&2 "ERROR: cannot find //third_party/bazel/tools/bash/runfiles:runfiles.bash" - exit 1 -fi -# --- end runfiles.bash initialization --- +# --- begin runfiles.bash initialization v3 --- +# Copy-pasted from the Bazel Bash runfiles library v3. +set -uo pipefail; set +e; f=io_bazel/tools/bash/runfiles/runfiles.bash +source "${TEST_SRCDIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${TEST_SRCDIR:-/dev/null}/MANIFEST" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v3 --- source "$(rlocation "io_bazel/src/test/shell/integration_test_setup.sh")" \ || { echo "integration_test_setup.sh not found!" >&2; exit 1; } diff --git a/src/test/shell/testenv.sh.tmpl b/src/test/shell/testenv.sh.tmpl index 8f1fdd95320d37..c7f40ddd27b1fd 100755 --- a/src/test/shell/testenv.sh.tmpl +++ b/src/test/shell/testenv.sh.tmpl @@ -92,7 +92,7 @@ distdir_bzl_file="${BAZEL_RUNFILES}/distdir.bzl" if [[ $PLATFORM =~ msys ]]; then jdk_dir="$(cygpath -m $(cd $(rlocation local_jdk/bin/java.exe)/../..; pwd))" else - jdk_dir="${TEST_SRCDIR}/local_jdk" + jdk_dir="$(dirname $(dirname $(rlocation local_jdk/bin/java)))" fi # Tools directory location diff --git a/third_party/ijar/test/BUILD b/third_party/ijar/test/BUILD index 053db09e80fb32..2e4cf9845c184e 100644 --- a/third_party/ijar/test/BUILD +++ b/third_party/ijar/test/BUILD @@ -20,8 +20,6 @@ sh_test( "$(location :zip_count)", ], data = [ - "testenv.sh", - "//src/test/shell:bashunit", "//third_party/ijar", "A.java", "B.java", @@ -54,6 +52,7 @@ sh_test( toolchains = [ "@bazel_tools//tools/jdk:current_java_runtime", ], + deps = [":testenv"], ) sh_test( @@ -66,12 +65,18 @@ sh_test( "unzip", "zip", ], - data = [ - "testenv.sh", + data = ["//third_party/ijar:zipper"], + tags = ["zip"], + deps = [":testenv"], +) + +sh_library( + name = "testenv", + srcs = ["testenv.sh"], + deps = [ "//src/test/shell:bashunit", - "//third_party/ijar:zipper", + "@bazel_tools//tools/bash/runfiles", ], - tags = ["zip"], ) java_library( diff --git a/third_party/ijar/test/testenv.sh b/third_party/ijar/test/testenv.sh index 235f2c5948982e..e7c131fbdf8ffb 100644 --- a/third_party/ijar/test/testenv.sh +++ b/third_party/ijar/test/testenv.sh @@ -17,10 +17,19 @@ # Setting up the environment for Bazel integration tests. # -[ -z "$TEST_SRCDIR" ] && { echo "TEST_SRCDIR not set!" >&2; exit 1; } +# --- begin runfiles.bash initialization v3 --- +# Copy-pasted from the Bazel Bash runfiles library v3. +set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ +source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ +source "$0.runfiles/$f" 2>/dev/null || \ +source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ +source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ +{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v3 --- # Load the unit-testing framework -source "${TEST_SRCDIR}/io_bazel/src/test/shell/unittest.bash" || \ +source "$(rlocation io_bazel/src/test/shell/unittest.bash)" || \ { echo "Failed to source unittest.bash" >&2; exit 1; } ## OSX/BSD stat and MD5