2019-08-20 16:13:20 +08:00
|
|
|
#!/usr/bin/env bash
|
2017-03-07 07:11:40 +08:00
|
|
|
|
|
|
|
BUILDAH_BINARY=${BUILDAH_BINARY:-$(dirname ${BASH_SOURCE})/../buildah}
|
2017-06-29 02:34:41 +08:00
|
|
|
IMGTYPE_BINARY=${IMGTYPE_BINARY:-$(dirname ${BASH_SOURCE})/../imgtype}
|
2017-03-07 07:11:40 +08:00
|
|
|
TESTSDIR=${TESTSDIR:-$(dirname ${BASH_SOURCE})}
|
2017-06-17 02:21:43 +08:00
|
|
|
STORAGE_DRIVER=${STORAGE_DRIVER:-vfs}
|
2017-07-21 01:41:51 +08:00
|
|
|
PATH=$(dirname ${BASH_SOURCE})/..:${PATH}
|
2017-03-07 07:11:40 +08:00
|
|
|
|
2019-04-02 05:56:29 +08:00
|
|
|
# Default timeout for a buildah command.
|
2019-04-03 21:38:25 +08:00
|
|
|
BUILDAH_TIMEOUT=${BUILDAH_TIMEOUT:-300}
|
2019-04-02 05:56:29 +08:00
|
|
|
|
2020-01-30 00:05:20 +08:00
|
|
|
# We don't invoke gnupg directly in many places, but this avoids ENOTTY errors
|
|
|
|
# when we invoke it directly in batch mode, and CI runs us without a terminal
|
|
|
|
# attached.
|
|
|
|
export GPG_TTY=/dev/null
|
|
|
|
|
2017-03-07 07:11:40 +08:00
|
|
|
function setup() {
|
2018-05-18 05:50:13 +08:00
|
|
|
suffix=$(dd if=/dev/urandom bs=12 count=1 status=none | od -An -tx1 | sed -e 's, ,,g')
|
|
|
|
TESTDIR=${BATS_TMPDIR}/tmp${suffix}
|
2017-03-08 04:54:51 +08:00
|
|
|
rm -fr ${TESTDIR}
|
|
|
|
mkdir -p ${TESTDIR}/{root,runroot}
|
2017-03-07 07:11:40 +08:00
|
|
|
}
|
|
|
|
|
2017-03-28 15:01:59 +08:00
|
|
|
function starthttpd() {
|
2017-03-30 03:50:32 +08:00
|
|
|
pushd ${2:-${TESTDIR}} > /dev/null
|
2018-04-19 16:52:24 +08:00
|
|
|
go build -o serve ${TESTSDIR}/serve/serve.go
|
2017-03-28 15:01:59 +08:00
|
|
|
HTTP_SERVER_PORT=$((RANDOM+32768))
|
|
|
|
./serve ${HTTP_SERVER_PORT} ${1:-${BATS_TMPDIR}} &
|
|
|
|
HTTP_SERVER_PID=$!
|
|
|
|
popd > /dev/null
|
|
|
|
}
|
|
|
|
|
|
|
|
function stophttpd() {
|
|
|
|
if test -n "$HTTP_SERVER_PID" ; then
|
|
|
|
kill -HUP ${HTTP_SERVER_PID}
|
|
|
|
unset HTTP_SERVER_PID
|
|
|
|
unset HTTP_SERVER_PORT
|
|
|
|
fi
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2017-03-07 07:11:40 +08:00
|
|
|
function teardown() {
|
2017-03-28 15:01:59 +08:00
|
|
|
stophttpd
|
2017-03-08 04:54:51 +08:00
|
|
|
rm -fr ${TESTDIR}
|
2017-03-07 07:11:40 +08:00
|
|
|
}
|
|
|
|
|
2019-12-09 21:45:52 +08:00
|
|
|
function _prefetch() {
|
|
|
|
if [ -z "${_BUILDAH_IMAGE_CACHEDIR}" ]; then
|
|
|
|
_pgid=$(sed -ne 's/^NSpgid:\s*//p' /proc/$$/status)
|
|
|
|
export _BUILDAH_IMAGE_CACHEDIR=${BATS_TMPDIR}/buildah-image-cache.$_pgid
|
|
|
|
mkdir -p ${_BUILDAH_IMAGE_CACHEDIR}
|
|
|
|
fi
|
|
|
|
|
|
|
|
local _podman_opts="--root ${TESTDIR}/root --storage-driver ${STORAGE_DRIVER}"
|
|
|
|
|
|
|
|
for img in "$@"; do
|
|
|
|
echo "# [checking for: $img]" >&2
|
|
|
|
fname=$(tr -c a-zA-Z0-9.- - <<< "$img")
|
|
|
|
if [ -e $_BUILDAH_IMAGE_CACHEDIR/$fname.tar ]; then
|
|
|
|
echo "# [restoring from cache: $_BUILDAH_IMAGE_CACHEDIR / $img]" >&2
|
|
|
|
podman $_podman_opts load -i $_BUILDAH_IMAGE_CACHEDIR/$fname.tar
|
|
|
|
else
|
|
|
|
echo "# [podman pull $img]" >&2
|
|
|
|
podman $_podman_opts pull $img || (
|
|
|
|
echo "Retrying:"
|
|
|
|
podman $_podman_opts pull $img || (
|
|
|
|
echo "Re-retrying:"
|
|
|
|
podman $_podman_opts pull $img
|
|
|
|
)
|
|
|
|
)
|
|
|
|
rm -f $_BUILDAH_IMAGE_CACHEDIR/$fname.tar
|
2020-02-07 01:04:17 +08:00
|
|
|
echo "# [podman save --format oci-archive $img >$_BUILDAH_IMAGE_CACHEDIR/$fname.tar ]" >&2
|
|
|
|
podman $_podman_opts save --format oci-archive --output=${_BUILDAH_IMAGE_CACHEDIR}/$fname.tar $img
|
2019-12-09 21:45:52 +08:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2017-03-07 07:11:40 +08:00
|
|
|
function createrandom() {
|
|
|
|
dd if=/dev/urandom bs=1 count=${2:-256} of=${1:-${BATS_TMPDIR}/randomfile} status=none
|
|
|
|
}
|
|
|
|
|
|
|
|
function buildah() {
|
2019-10-19 00:10:48 +08:00
|
|
|
${BUILDAH_BINARY} --registries-conf ${TESTSDIR}/registries.conf --root ${TESTDIR}/root --runroot ${TESTDIR}/runroot --storage-driver ${STORAGE_DRIVER} "$@"
|
2017-03-07 07:11:40 +08:00
|
|
|
}
|
2017-05-23 00:08:20 +08:00
|
|
|
|
|
|
|
function imgtype() {
|
2019-10-29 06:03:31 +08:00
|
|
|
${IMGTYPE_BINARY} -root ${TESTDIR}/root -runroot ${TESTDIR}/runroot -storage-driver ${STORAGE_DRIVER} "$@"
|
2017-05-23 00:08:20 +08:00
|
|
|
}
|
2018-09-03 19:20:52 +08:00
|
|
|
|
2019-04-02 05:56:29 +08:00
|
|
|
#################
|
|
|
|
# run_buildah # Invoke buildah, with timeout, using BATS 'run'
|
|
|
|
#################
|
|
|
|
#
|
|
|
|
# This is the preferred mechanism for invoking buildah:
|
|
|
|
#
|
|
|
|
# * we use 'timeout' to abort (with a diagnostic) if something
|
|
|
|
# takes too long; this is preferable to a CI hang.
|
|
|
|
# * we log the command run and its output. This doesn't normally
|
|
|
|
# appear in BATS output, but it will if there's an error.
|
|
|
|
# * we check exit status. Since the normal desired code is 0,
|
|
|
|
# that's the default; but the first argument can override:
|
|
|
|
#
|
|
|
|
# run_buildah 125 nonexistent-subcommand
|
|
|
|
# run_buildah '?' some-other-command # let our caller check status
|
|
|
|
#
|
|
|
|
# Since we use the BATS 'run' mechanism, $output and $status will be
|
|
|
|
# defined for our caller.
|
|
|
|
#
|
|
|
|
function run_buildah() {
|
|
|
|
# Number as first argument = expected exit code; default 0
|
|
|
|
expected_rc=0
|
|
|
|
case "$1" in
|
|
|
|
[0-9]) expected_rc=$1; shift;;
|
|
|
|
[1-9][0-9]) expected_rc=$1; shift;;
|
|
|
|
[12][0-9][0-9]) expected_rc=$1; shift;;
|
|
|
|
'?') expected_rc= ; shift;; # ignore exit code
|
|
|
|
esac
|
|
|
|
|
2019-04-05 21:56:11 +08:00
|
|
|
# Remember command args, for possible use in later diagnostic messages
|
|
|
|
MOST_RECENT_BUILDAH_COMMAND="buildah $*"
|
|
|
|
|
2019-04-02 05:56:29 +08:00
|
|
|
# stdout is only emitted upon error; this echo is to help a debugger
|
|
|
|
echo "\$ $BUILDAH_BINARY $*"
|
2019-10-19 00:10:48 +08:00
|
|
|
run timeout --foreground --kill=10 $BUILDAH_TIMEOUT ${BUILDAH_BINARY} --registries-conf ${TESTSDIR}/registries.conf --root ${TESTDIR}/root --runroot ${TESTDIR}/runroot --storage-driver ${STORAGE_DRIVER} "$@"
|
2019-04-02 05:56:29 +08:00
|
|
|
# without "quotes", multiple lines are glommed together into one
|
|
|
|
if [ -n "$output" ]; then
|
|
|
|
echo "$output"
|
|
|
|
fi
|
|
|
|
if [ "$status" -ne 0 ]; then
|
|
|
|
echo -n "[ rc=$status ";
|
|
|
|
if [ -n "$expected_rc" ]; then
|
|
|
|
if [ "$status" -eq "$expected_rc" ]; then
|
|
|
|
echo -n "(expected) ";
|
|
|
|
else
|
|
|
|
echo -n "(** EXPECTED $expected_rc **) ";
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
echo "]"
|
|
|
|
fi
|
|
|
|
|
2019-04-03 21:38:25 +08:00
|
|
|
if [ "$status" -eq 124 -o "$status" -eq 137 ]; then
|
|
|
|
# FIXME: 'timeout -v' requires coreutils-8.29; travis seems to have
|
|
|
|
# an older version. If/when travis updates, please add -v
|
|
|
|
# to the 'timeout' command above, and un-comment this out:
|
|
|
|
# if expr "$output" : ".*timeout: sending" >/dev/null; then
|
|
|
|
echo "*** TIMED OUT ***"
|
|
|
|
false
|
2019-04-02 05:56:29 +08:00
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -n "$expected_rc" ]; then
|
|
|
|
if [ "$status" -ne "$expected_rc" ]; then
|
|
|
|
die "exit code is $status; expected $expected_rc"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
#########
|
|
|
|
# die # Abort with helpful message
|
|
|
|
#########
|
|
|
|
function die() {
|
|
|
|
echo "#/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv" >&2
|
|
|
|
echo "#| FAIL: $*" >&2
|
|
|
|
echo "#\\^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" >&2
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
2019-04-05 23:59:54 +08:00
|
|
|
###################
|
|
|
|
# expect_output # Compare actual vs expected string; fail if mismatch
|
|
|
|
###################
|
2019-04-02 05:56:29 +08:00
|
|
|
#
|
2019-04-05 23:59:54 +08:00
|
|
|
# Compares $output against the given string argument. Optional second
|
|
|
|
# argument is descriptive text to show as the error message (default:
|
|
|
|
# the command most recently run by 'run_buildah'). This text can be
|
|
|
|
# useful to isolate a failure when there are multiple identical
|
|
|
|
# run_buildah invocations, and the difference is solely in the
|
|
|
|
# config or setup; see, e.g., run.bats:run-cmd().
|
|
|
|
#
|
|
|
|
# By default we run an exact string comparison; use --substring to
|
|
|
|
# look for the given string anywhere in $output.
|
|
|
|
#
|
|
|
|
# By default we look in "$output", which is set in run_buildah().
|
|
|
|
# To override, use --from="some-other-string" (e.g. "${lines[0]}")
|
2019-04-02 05:56:29 +08:00
|
|
|
#
|
|
|
|
# Examples:
|
|
|
|
#
|
2019-04-05 23:59:54 +08:00
|
|
|
# expect_output "this is exactly what we expect"
|
|
|
|
# expect_output "foo=bar" "description of this particular test"
|
|
|
|
# expect_output --from="${lines[0]}" "expected first line"
|
2019-04-02 05:56:29 +08:00
|
|
|
#
|
2019-04-05 23:59:54 +08:00
|
|
|
function expect_output() {
|
|
|
|
# By default we examine $output, the result of run_buildah
|
|
|
|
local actual="$output"
|
|
|
|
local check_substring=
|
|
|
|
|
|
|
|
# option processing: recognize --from="...", --substring
|
|
|
|
local opt
|
|
|
|
for opt; do
|
|
|
|
local value=$(expr "$opt" : '[^=]*=\(.*\)')
|
|
|
|
case "$opt" in
|
|
|
|
--from=*) actual="$value"; shift;;
|
|
|
|
--substring) check_substring=1; shift;;
|
|
|
|
--) shift; break;;
|
|
|
|
-*) die "Invalid option '$opt'" ;;
|
|
|
|
*) break;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
local expect="$1"
|
|
|
|
local testname="${2:-${MOST_RECENT_BUILDAH_COMMAND:-[no test name given]}}"
|
2019-04-02 05:56:29 +08:00
|
|
|
|
|
|
|
if [ -z "$expect" ]; then
|
|
|
|
if [ -z "$actual" ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
expect='[no output]'
|
|
|
|
elif [ "$actual" = "$expect" ]; then
|
|
|
|
return
|
2019-04-05 23:59:54 +08:00
|
|
|
elif [ -n "$check_substring" ]; then
|
|
|
|
if [[ "$actual" =~ $expect ]]; then
|
|
|
|
return
|
|
|
|
fi
|
2019-04-02 05:56:29 +08:00
|
|
|
fi
|
|
|
|
|
|
|
|
# This is a multi-line message, which may in turn contain multi-line
|
|
|
|
# output, so let's format it ourself, readably
|
|
|
|
local -a actual_split
|
|
|
|
readarray -t actual_split <<<"$actual"
|
|
|
|
printf "#/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n" >&2
|
2019-10-19 00:10:48 +08:00
|
|
|
printf "#| FAIL: %s\n" "$testname" >&2
|
2019-04-02 05:56:29 +08:00
|
|
|
printf "#| expected: '%s'\n" "$expect" >&2
|
|
|
|
printf "#| actual: '%s'\n" "${actual_split[0]}" >&2
|
|
|
|
local line
|
|
|
|
for line in "${actual_split[@]:1}"; do
|
|
|
|
printf "#| > '%s'\n" "$line" >&2
|
|
|
|
done
|
|
|
|
printf "#\\^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" >&2
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
2019-04-05 21:56:11 +08:00
|
|
|
#######################
|
|
|
|
# expect_line_count # Check the expected number of output lines
|
|
|
|
#######################
|
|
|
|
#
|
|
|
|
# ...from the most recent run_buildah command
|
|
|
|
#
|
|
|
|
function expect_line_count() {
|
|
|
|
local expect="$1"
|
|
|
|
local testname="${2:-${MOST_RECENT_BUILDAH_COMMAND:-[no test name given]}}"
|
|
|
|
|
|
|
|
local actual="${#lines[@]}"
|
|
|
|
if [ "$actual" -eq "$expect" ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
printf "#/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n" >&2
|
|
|
|
printf "#| FAIL: $testname\n" >&2
|
|
|
|
printf "#| Expected %d lines of output, got %d\n" $expect $actual >&2
|
|
|
|
printf "#| Output was:\n" >&2
|
|
|
|
local line
|
|
|
|
for line in "${lines[@]}"; do
|
|
|
|
printf "#| >%s\n" "$line" >&2
|
|
|
|
done
|
|
|
|
printf "#\\^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" >&2
|
|
|
|
false
|
|
|
|
}
|
2019-04-02 05:56:29 +08:00
|
|
|
|
2018-09-03 19:20:52 +08:00
|
|
|
function check_options_flag_err() {
|
|
|
|
flag="$1"
|
|
|
|
[ "$status" -eq 1 ]
|
|
|
|
[[ $output = *"No options ($flag) can be specified after"* ]]
|
|
|
|
}
|
2019-11-06 02:22:07 +08:00
|
|
|
|
|
|
|
####################
|
|
|
|
# skip_if_chroot #
|
|
|
|
####################
|
|
|
|
function skip_if_chroot() {
|
|
|
|
if test "$BUILDAH_ISOLATION" = "chroot"; then
|
|
|
|
skip "${1:-test does not work when \$BUILDAH_ISOLATION = chroot}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
######################
|
|
|
|
# skip_if_rootless #
|
|
|
|
######################
|
|
|
|
function skip_if_rootless() {
|
|
|
|
if test "$BUILDAH_ISOLATION" = "rootless"; then
|
|
|
|
skip "${1:-test does not work when \$BUILDAH_ISOLATION = rootless}"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
########################
|
|
|
|
# skip_if_no_runtime # 'buildah run' can't work without a runtime
|
|
|
|
########################
|
|
|
|
function skip_if_no_runtime() {
|
|
|
|
# FIXME: if #1964 gets fixed, use 'buildah info' to determine runtime
|
|
|
|
# FIXME: right now we just rely on runc
|
|
|
|
runtime=runc
|
|
|
|
if type -p $runtime &> /dev/null; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
skip "runtime '$runtime' not found"
|
|
|
|
}
|
2019-11-06 01:06:42 +08:00
|
|
|
|
|
|
|
##################
|
|
|
|
# is_cgroupsv2 # Returns true if host system has cgroupsv2 enabled
|
|
|
|
##################
|
|
|
|
function is_cgroupsv2() {
|
|
|
|
local cgroupfs_t=$(stat -f -c %T /sys/fs/cgroup)
|
|
|
|
test "$cgroupfs_t" = "cgroup2fs"
|
|
|
|
}
|
|
|
|
|
|
|
|
#######################
|
|
|
|
# skip_if_cgroupsv2 # Some tests don't work with cgroupsv2
|
|
|
|
#######################
|
|
|
|
function skip_if_cgroupsv2() {
|
|
|
|
if is_cgroupsv2; then
|
|
|
|
skip "${1:-test does not work with cgroups v2}"
|
|
|
|
fi
|
|
|
|
}
|