| #!/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. |
| # |
| # Test rules provided in Bazel not tested by examples |
| # |
| |
| function die() { |
| echo >&2 "ERROR[$(basename "$0") $(date +%H:%M:%S.%N)] $*" |
| exit 1 |
| } |
| |
| if ! type rlocation &> /dev/null; then |
| die "the rlocation() Bash function is undefined" |
| fi |
| |
| # Load the test setup defined in the parent directory |
| source $(rlocation io_bazel/src/test/shell/integration_test_setup.sh) \ |
| || die "integration_test_setup.sh not found!" |
| |
| |
| function test_sh_test() { |
| mkdir -p a |
| cat > a/BUILD <<EOF |
| package(default_visibility = ["//visibility:public"]) |
| sh_test( |
| name = 'success_test', |
| srcs = [ 'success_test.sh' ], |
| ) |
| |
| sh_test( |
| name = 'fail_test', |
| srcs = [ 'fail_test.sh' ], |
| ) |
| |
| EOF |
| |
| cat > a/success_test.sh <<EOF |
| #!/bin/sh |
| echo success-marker |
| exit 0 |
| EOF |
| |
| cat > a/fail_test.sh <<EOF |
| #!/bin/sh |
| echo failure-message |
| exit 1 |
| EOF |
| |
| chmod +x a/*.sh |
| |
| assert_test_ok //a:success_test |
| assert_test_fails //a:fail_test |
| expect_log 'failure-message' |
| } |
| |
| function test_extra_action() { |
| mkdir -p mypkg |
| # Make a program to run on each action that just prints the path to the extra |
| # action file. This file is a proto, but I don't want to bother implementing |
| # a program that parses the proto here. |
| cat > mypkg/echoer.sh <<EOF |
| #!/bin/sh |
| if [[ ! -e \$0.runfiles/__main__/mypkg/runfile ]]; then |
| echo "Runfile not found" >&2 |
| exit 1 |
| fi |
| echo EXTRA ACTION FILE: \$1 |
| EOF |
| chmod +x mypkg/echoer.sh |
| |
| cat > mypkg/Hello.java <<EOF |
| public class Hello { |
| public void sayHi() { |
| System.out.println("hi"); |
| } |
| } |
| EOF |
| |
| touch mypkg/runfile |
| |
| cat > mypkg/BUILD <<EOF |
| package(default_visibility = ["//visibility:public"]) |
| |
| extra_action( |
| name = "echo-filename", |
| cmd = "\$(location :echoer) \$(EXTRA_ACTION_FILE)", |
| tools = [":echoer"], |
| ) |
| |
| action_listener( |
| name = "al", |
| extra_actions = [":echo-filename"], |
| mnemonics = ["Javac"], |
| ) |
| |
| sh_binary( |
| name = "echoer", |
| srcs = ["echoer.sh"], |
| data = ["runfile"], |
| ) |
| |
| java_library( |
| name = "hello", |
| srcs = ["Hello.java"], |
| ) |
| EOF |
| |
| bazel build --experimental_action_listener=//mypkg:al //mypkg:hello >& $TEST_log \ |
| || fail "Building with action listener failed" |
| expect_log "EXTRA ACTION FILE" |
| } |
| |
| function test_with_arguments() { |
| mkdir -p mypkg |
| cat > mypkg/BUILD <<EOF |
| sh_test( |
| name = "expected_arg_test", |
| srcs = ["check_expected_argument.sh"], |
| args = ["expected_value"], |
| ) |
| |
| sh_test( |
| name = "unexpected_arg_test", |
| srcs = ["check_expected_argument.sh"], |
| args = ["unexpected_value"], |
| ) |
| EOF |
| cat > mypkg/check_expected_argument.sh <<EOF |
| #!/bin/sh |
| [ "expected_value" = "\$1" ] || exit 1 |
| EOF |
| |
| chmod +x mypkg/check_expected_argument.sh |
| |
| assert_test_ok //mypkg:expected_arg_test |
| assert_test_fails //mypkg:unexpected_arg_test |
| } |
| |
| function test_top_level_test() { |
| cat > BUILD <<EOF |
| sh_test( |
| name = "trivial_test", |
| srcs = ["true.sh"], |
| ) |
| EOF |
| cat > true.sh <<EOF |
| #!/bin/sh |
| exit 0 |
| EOF |
| |
| chmod +x true.sh |
| |
| assert_test_ok //:trivial_test |
| } |
| |
| # Regression test for https://github.com/bazelbuild/bazel/issues/67 |
| # C++ library depedending on C++ library fails to compile on Darwin |
| function test_cpp_libdeps() { |
| mkdir -p pkg |
| cat <<'EOF' >pkg/BUILD |
| cc_library( |
| name = "a", |
| srcs = ["a.cc"], |
| ) |
| |
| cc_library( |
| name = "b", |
| srcs = ["b.cc"], |
| deps = [":a"], |
| ) |
| |
| cc_binary( |
| name = "main", |
| srcs = ["main.cc"], |
| deps = [":b"], |
| ) |
| EOF |
| |
| cat <<'EOF' >pkg/a.cc |
| #include <string> |
| |
| std::string get_hello(std::string world) { |
| return "Hello, " + world + "!"; |
| } |
| EOF |
| |
| cat <<'EOF' >pkg/b.cc |
| #include <string> |
| #include <iostream> |
| |
| std::string get_hello(std::string); |
| |
| void print_hello(std::string world) { |
| std::cout << get_hello(world) << std::endl; |
| } |
| EOF |
| |
| cat <<'EOF' >pkg/main.cc |
| #include <string> |
| void print_hello(std::string); |
| |
| int main() { |
| print_hello(std::string("World")); |
| } |
| EOF |
| |
| bazel build //pkg:a >& $TEST_log \ |
| || fail "Failed to build //pkg:a" |
| bazel build //pkg:b >& $TEST_log \ |
| || fail "Failed to build //pkg:b" |
| bazel run //pkg:main >& $TEST_log \ |
| || fail "Failed to run //pkg:main" |
| expect_log "Hello, World!" |
| ./bazel-bin/pkg/main >& $TEST_log \ |
| || fail "Failed to run //pkg:main" |
| expect_log "Hello, World!" |
| } |
| |
| |
| function test_genrule_default_env() { |
| mkdir -p pkg |
| cat <<'EOF' >pkg/BUILD |
| genrule( |
| name = "test", |
| outs = ["test.out"], |
| cmd = "(echo \"PATH=$$PATH\"; echo \"TMPDIR=$$TMPDIR\") > $@", |
| ) |
| EOF |
| local old_path="${PATH}" |
| local old_tmpdir="${TMPDIR-}" |
| local new_tmpdir="$(mktemp -d "${TEST_TMPDIR}/newfancytmpdirXXXXXX")" |
| [ -d "${new_tmpdir}" ] || \ |
| fail "Could not create new temporary directory ${new_tmpdir}" |
| export PATH="$PATH_TO_BAZEL_WRAPPER:/bin:/usr/bin:/random/path" |
| export TMPDIR="${new_tmpdir}" |
| # batch mode to force reload of the environment |
| bazel --batch build //pkg:test --spawn_strategy=standalone \ |
| || fail "Failed to build //pkg:test" |
| assert_contains "PATH=$PATH_TO_BAZEL_WRAPPER:/bin:/usr/bin:/random/path" \ |
| bazel-genfiles/pkg/test.out |
| # Bazel respectes the client environment's TMPDIR. |
| assert_contains "TMPDIR=${new_tmpdir}$" bazel-genfiles/pkg/test.out |
| if [ -n "${old_tmpdir}" ] |
| then |
| export TMPDIR="${old_tmpdir}" |
| else |
| unset TMPDIR |
| fi |
| export PATH="${old_path}" |
| } |
| |
| function test_genrule_remote() { |
| cat > WORKSPACE <<EOF |
| local_repository( |
| name = "r", |
| path = __workspace_dir__, |
| ) |
| EOF |
| mkdir package |
| cat > package/BUILD <<EOF |
| genrule( |
| name = "abs_dep", |
| srcs = ["//package:in"], |
| outs = ["abs_dep.out"], |
| cmd = "echo '\$(locations //package:in)' > \$@", |
| ) |
| |
| sh_binary( |
| name = "in", |
| srcs = ["in.sh"], |
| ) |
| EOF |
| |
| cat > package/in.sh << EOF |
| #!/bin/sh |
| echo "Hi" |
| EOF |
| chmod +x package/in.sh |
| |
| bazel build @r//package:abs_dep >$TEST_log 2>&1 || fail "Should build" |
| } |
| |
| function test_genrule_remote_d() { |
| cat > WORKSPACE <<EOF |
| local_repository( |
| name = "r", |
| path = __workspace_dir__, |
| ) |
| EOF |
| mkdir package |
| cat > package/BUILD <<'EOF' |
| genrule( |
| name = "hi", |
| outs = [ |
| "a/b", |
| "c/d" |
| ], |
| cmd = "echo 'hi' | tee $(@D)/a/b $(@D)/c/d", |
| ) |
| EOF |
| |
| bazel build @r//package:hi >$TEST_log 2>&1 || fail "Should build" |
| expect_log "bazel-\(bin\|genfiles\)/external/r/package/a/b" |
| expect_log "bazel-\(bin\|genfiles\)/external/r/package/c/d" |
| } |
| |
| function test_genrule_toolchain_dependency { |
| mkdir -p t |
| cat > t/BUILD <<EOF |
| genrule( |
| name = "toolchain_check", |
| outs = ["version"], |
| toolchains = ['@bazel_tools//tools/jdk:current_java_runtime'], |
| cmd = "ls -al \$(JAVABASE) > \$@", |
| ) |
| EOF |
| bazel build //t:toolchain_check >$TEST_log 2>&1 || fail "Should build" |
| expect_log "bazel-\(bin\|genfiles\)/t/version" |
| expect_not_log "ls: cannot access" |
| } |
| |
| function test_python_with_workspace_name() { |
| |
| create_new_workspace |
| cd ${new_workspace_dir} |
| mkdir -p {module_a,module_b} |
| local remote_path="${new_workspace_dir}" |
| |
| cat > module_a/BUILD <<EOF |
| package(default_visibility = ["//visibility:public"]) |
| py_library(name = "foo", srcs=["foo.py"]) |
| EOF |
| |
| cat > module_b/BUILD <<EOF |
| package(default_visibility = ["//visibility:public"]) |
| py_library(name = "bar", deps = ["//module_a:foo"], srcs=["bar.py"],) |
| py_binary(name = "bar2", deps = ["//module_a:foo"], srcs=["bar2.py"],) |
| EOF |
| |
| cat > module_a/foo.py <<EOF |
| def GetNumber(): |
| return 42 |
| EOF |
| |
| cat > module_b/bar.py <<EOF |
| from module_a import foo |
| def PrintNumber(): |
| print "Print the number %d" % foo.GetNumber() |
| EOF |
| |
| cat > module_b/bar2.py <<EOF |
| from module_a import foo |
| print "The number is %d" % foo.GetNumber() |
| EOF |
| |
| cd ${WORKSPACE_DIR} |
| mkdir -p {module1,module2} |
| cat > WORKSPACE <<EOF |
| workspace(name = "foobar") |
| local_repository(name="remote", path="${remote_path}") |
| EOF |
| cat > module1/BUILD <<EOF |
| package(default_visibility = ["//visibility:public"]) |
| py_library(name = "fib", srcs=["fib.py"],) |
| EOF |
| cat > module2/BUILD <<EOF |
| py_binary(name = "bez", |
| deps = ["@remote//module_a:foo", "@remote//module_b:bar", "//module1:fib"], |
| srcs = ["bez.py"],) |
| EOF |
| |
| cat > module1/fib.py <<EOF |
| def Fib(n): |
| if n == 0 or n == 1: |
| return 1 |
| else: |
| return Fib(n-1) + Fib(n-2) |
| EOF |
| |
| cat > module2/bez.py <<EOF |
| from remote.module_a import foo |
| from remote.module_b import bar |
| from module1 import fib |
| |
| print "The number is %d" % foo.GetNumber() |
| bar.PrintNumber() |
| print "Fib(10) is %d" % fib.Fib(10) |
| EOF |
| bazel run //module2:bez >$TEST_log |
| expect_log "The number is 42" |
| expect_log "Print the number 42" |
| expect_log "Fib(10) is 89" |
| bazel run @remote//module_b:bar2 >$TEST_log |
| expect_log "The number is 42" |
| } |
| |
| function test_build_python_zip_with_middleman() { |
| mkdir py |
| touch py/data.txt |
| cat > py/BUILD <<EOF |
| py_binary(name = "bin", srcs = ["bin.py"], data = ["data.txt"]) |
| py_binary(name = "bin2", srcs = ["bin2.py"], data = [":bin"]) |
| EOF |
| cat > py/bin.py <<EOF |
| print("hello") |
| EOF |
| cat > py/bin2.py <<EOF |
| print("world") |
| EOF |
| bazel build --build_python_zip //py:bin2 || fail "build failed" |
| unzip -l ./bazel-bin/py/bin2 | grep "data.txt" || fail "failed to zip data file" |
| } |
| |
| function test_build_with_aliased_input_file() { |
| mkdir -p a |
| cat > a/BUILD <<EOF |
| exports_files(['f']) |
| alias(name='a', actual=':f') |
| EOF |
| |
| touch a/f |
| bazel build //a:a || fail "build failed" |
| } |
| |
| function test_visibility() { |
| mkdir visibility |
| cat > visibility/BUILD <<EOF |
| cc_library( |
| name = "foo", |
| visibility = [ |
| "//foo/bar:__pkg__", |
| "//visibility:public", |
| ], |
| ) |
| EOF |
| |
| bazel build //visibility:foo &> $TEST_log && fail "Expected failure" || true |
| expect_log "Public or private visibility labels (e.g. //visibility:public or //visibility:private) cannot be used in combination with other labels" |
| } |
| |
| run_suite "rules test" |