blob: 6f081a023cd22b93241b570733f666c684de8e49 [file]
#!/bin/bash
#
# Copyright 2015 Google Inc. 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 //external mechanisms
#
# Load test environment
source $(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/test-setup.sh \
|| { echo "test-setup.sh not found!" >&2; exit 1; }
function set_up() {
mkdir -p zoo
cat > zoo/BUILD <<EOF
java_binary(
name = "ball-pit",
srcs = ["BallPit.java"],
main_class = "BallPit",
deps = ["//external:mongoose"],
)
EOF
cat > zoo/BallPit.java <<EOF
import carnivore.Mongoose;
public class BallPit {
public static void main(String args[]) {
Mongoose.frolic();
}
}
EOF
}
case "${PLATFORM}" in
darwin)
function nc_l() {
nc -l $1
}
;;
*)
function nc_l() {
nc -l -p $1 -q 1
}
;;
esac
# Serves $1 as a file on localhost:$nc_port. Sets the following variables:
# * nc_port - the port nc is listening on.
# * nc_log - the path to nc's log.
# * nc_pid - the PID of nc.
# * http_response - the full response nc will provide to a request.
# This also creates the file $TEST_TMPDIR/http_response.
function serve_file() {
http_response=$TEST_TMPDIR/http_response
cat > $http_response <<EOF
HTTP/1.0 200 OK
EOF
cat $1 >> $http_response
nc_port=$(pick_random_unused_tcp_port) || exit 1
nc_log=$TEST_TMPDIR/nc.log
nc_l $nc_port < $http_response >& $nc_log &
nc_pid=$!
}
# Creates a jar carnivore.Mongoose and serves it using serve_file.
function serve_jar() {
pkg_dir=$TEST_TMPDIR/carnivore
if [ -e "$pkg_dir" ]; then
rm -fr $pkg_dir
fi
mkdir $pkg_dir
cat > $pkg_dir/Mongoose.java <<EOF
package carnivore;
public class Mongoose {
public static void frolic() {
System.out.println("Tra-la!");
}
}
EOF
${bazel_javabase}/bin/javac $pkg_dir/Mongoose.java
test_jar=$TEST_TMPDIR/libcarnivore.jar
cd ${TEST_TMPDIR}
${bazel_javabase}/bin/jar cf $test_jar carnivore/Mongoose.class
sha256=$(sha256sum $test_jar | cut -f 1 -d ' ')
serve_file $test_jar
cd ${WORKSPACE_DIR}
}
function kill_nc() {
# Try to kill nc, otherwise the test will time out if Bazel has a bug and
# didn't make a request to it.
kill $nc_pid || true # kill can fails if the process already finished
[ -z "${nc_log:-}" ] || cat $nc_log
}
# Test downloading a file from a repository.
# This creates a simple repository containing:
#
# repo/
# WORKSPACE
# zoo/
# BUILD
# female.sh
#
# And a .zip file, which contains:
#
# WORKSPACE
# fox/
# BUILD
# male
function test_http_archive() {
# Create a zipped-up repository HTTP response.
repo2=$TEST_TMPDIR/repo2
rm -rf $repo2
mkdir -p $repo2/fox
cd $repo2
touch WORKSPACE
cat > fox/BUILD <<EOF
filegroup(
name = "fox",
srcs = ["male"],
visibility = ["//visibility:public"],
)
EOF
what_does_the_fox_say="Fraka-kaka-kaka-kaka-kow"
echo $what_does_the_fox_say > fox/male
repo2_zip=$TEST_TMPDIR/fox.zip
zip -r $repo2_zip WORKSPACE fox
sha256=$(sha256sum $repo2_zip | cut -f 1 -d ' ')
serve_file $repo2_zip
cd ${WORKSPACE_DIR}
cat > WORKSPACE <<EOF
http_archive(name = 'endangered', url = 'http://localhost:$nc_port/repo.zip',
sha256 = '$sha256')
bind(name = 'stud', actual = '@endangered//fox')
EOF
cat > zoo/BUILD <<EOF
sh_binary(
name = "breeding-program",
srcs = ["female.sh"],
data = ["//external:stud"],
)
EOF
cat > zoo/female.sh <<EOF
#!/bin/bash
cat external/endangered/fox/male
EOF
chmod +x zoo/female.sh
bazel run //zoo:breeding-program >& $TEST_log \
|| echo "Expected build/run to succeed"
kill_nc
expect_log $what_does_the_fox_say
}
function test_http_archive_no_server() {
nc_port=$(pick_random_unused_tcp_port) || exit 1
cat > WORKSPACE <<EOF
http_archive(name = 'endangered', url = 'http://localhost:$nc_port/repo.zip',
sha256 = 'dummy')
bind(name = 'stud', actual = '@endangered//fox')
EOF
cat > zoo/BUILD <<EOF
sh_binary(
name = "breeding-program",
srcs = ["female.sh"],
data = ["//external:stud"],
)
EOF
cat > zoo/female.sh <<EOF
#!/bin/bash
cat fox/male
EOF
chmod +x zoo/female.sh
bazel run //zoo:breeding-program >& $TEST_log && echo "Expected build to fail"
cat $TEST_log
expect_log "Connection refused"
}
function test_http_archive_mismatched_sha256() {
# Create a zipped-up repository HTTP response.
repo2=$TEST_TMPDIR/repo2
rm -rf $repo2
mkdir -p $repo2
cd $repo2
touch WORKSPACE
repo2_zip=$TEST_TMPDIR/fox.zip
zip -r $repo2_zip WORKSPACE
serve_file $repo2_zip
wrong_sha256=0000000000000000000000000000000000000000
cd ${WORKSPACE_DIR}
cat > WORKSPACE <<EOF
http_archive(name = 'endangered', url = 'http://localhost:$nc_port/repo.zip',
sha256 = '$wrong_sha256')
bind(name = 'stud', actual = '@endangered//fox')
EOF
cat > zoo/BUILD <<EOF
sh_binary(
name = "breeding-program",
srcs = ["female.sh"],
data = ["//external:stud"],
)
EOF
cat > zoo/female.sh <<EOF
#!/bin/bash
cat fox/male
EOF
chmod +x zoo/female.sh
bazel run //zoo:breeding-program >& $TEST_log && echo "Expected build to fail"
kill_nc
expect_log "does not match expected SHA-256"
}
# Bazel should not re-download the .zip unless the user requests it or the
# WORKSPACE file changes, so doing a BUILD where the "wrong" .zip is available
# on the server should work if the correct .zip is already available.
function test_sha256_caching() {
# Download with correct sha256.
test_http_archive
# Create another HTTP response.
http_response=$TEST_TMPDIR/http_response
cat > $http_response <<EOF
HTTP/1.0 200 OK
EOF
nc_log=$TEST_TMPDIR/nc.log
nc_port=$(pick_random_unused_tcp_port) || exit 1
# "Webserver" for http_archive rule.
nc_l $nc_port < $http_response >& $nc_log &
pid=$!
bazel run //zoo:breeding-program >& $TEST_log \
|| echo "Expected run to succeed"
kill_nc
expect_log $what_does_the_fox_say
}
# Tests downloading a jar and using it as a Java dependency.
function test_jar_download() {
serve_jar
cat > WORKSPACE <<EOF
http_jar(name = 'endangered', url = 'http://localhost:$nc_port/lib.jar',
sha256 = '$sha256')
bind(name = 'mongoose', actual = '@endangered//jar')
EOF
mkdir -p zoo
cat > zoo/BUILD <<EOF
java_binary(
name = "ball-pit",
srcs = ["BallPit.java"],
main_class = "BallPit",
deps = ["//external:mongoose"],
)
EOF
cat > zoo/BallPit.java <<EOF
import carnivore.Mongoose;
public class BallPit {
public static void main(String args[]) {
Mongoose.frolic();
}
}
EOF
bazel run //zoo:ball-pit >& $TEST_log || echo "Expected run to succeed"
kill_nc
expect_log "Tra-la!"
}
function test_invalid_rule() {
# http_jar with missing URL field.
cat > WORKSPACE <<EOF
http_jar(name = 'endangered', sha256 = 'dummy')
EOF
bazel run //external:endangered >& $TEST_log && echo "Expected run to fail"
expect_log "missing value for mandatory attribute 'url' in 'http_jar' rule"
}
function test_maven_jar() {
serve_jar
cat > WORKSPACE <<EOF
maven_jar(
name = 'endangered',
group_id = "com.example.carnivore",
artifact_id = "carnivore",
version = "1.23",
repositories = ['http://localhost:$nc_port/']
)
bind(name = 'mongoose', actual = '@endangered//jar')
EOF
bazel run //zoo:ball-pit >& $TEST_log || echo "Expected run to succeed"
kill_nc
assert_contains "GET /com/example/carnivore/carnivore/1.23/carnivore-1.23.jar" $nc_log
expect_log "Tra-la!"
}
function test_maven_jar_404() {
http_response=$TEST_TMPDIR/http_response
cat > $http_response <<EOF
HTTP/1.0 404 Not Found
EOF
nc_port=$(pick_random_unused_tcp_port) || exit 1
nc_l $nc_port < $http_response &
nc_pid=$!
cat > WORKSPACE <<EOF
maven_jar(
name = 'endangered',
group_id = "carnivore",
artifact_id = "carnivore",
version = "1.23",
repositories = ['http://localhost:$nc_port/']
)
bind(name = 'mongoose', actual = '@endangered//jar')
EOF
bazel run //zoo:ball-pit >& $TEST_log && echo "Expected run to fail"
kill_nc
expect_log "Failed to fetch Maven dependency: Could not find artifact"
}
function test_new_remote_repo() {
# Create a zipped-up repository HTTP response.
local repo2=$TEST_TMPDIR/repo2
rm -rf $repo2
mkdir -p $repo2/fox
cd $repo2
local what_does_the_fox_say="Fraka-kaka-kaka-kaka-kow"
echo $what_does_the_fox_say > fox/male
local repo2_zip=$TEST_TMPDIR/fox.zip
rm $repo2_zip
zip -r $repo2_zip fox
local sha256=$(sha256sum $repo2_zip | cut -f 1 -d ' ')
serve_file $repo2_zip
cd ${WORKSPACE_DIR}
cat > fox.BUILD <<EOF
filegroup(
name = "fox",
srcs = ["fox/male"],
visibility = ["//visibility:public"],
)
EOF
cat > WORKSPACE <<EOF
new_http_archive(
name = 'endangered',
url = 'http://localhost:$nc_port/repo.zip',
sha256 = '$sha256',
build_file = 'fox.BUILD'
)
bind(name = 'stud', actual = '@endangered//:fox')
EOF
mkdir -p zoo
cat > zoo/BUILD <<EOF
sh_binary(
name = "breeding-program",
srcs = ["female.sh"],
data = ["//external:stud"],
)
EOF
cat > zoo/female.sh <<EOF
#!/bin/bash
cat external/endangered/fox/male
EOF
chmod +x zoo/female.sh
bazel run //zoo:breeding-program >& $TEST_log \
|| echo "Expected build/run to succeed"
kill_nc
expect_log $what_does_the_fox_say
}
run_suite "external tests"