146 lines
3.4 KiB
Bash
146 lines
3.4 KiB
Bash
#! /bin/sh
|
|
# $NetBSD: test.subr,v 1.1 2019/03/21 21:45:30 rillig Exp $
|
|
set -eu
|
|
|
|
# This file defines utilities for testing Makefile fragments in a mocked
|
|
# environment. It is used primarily to test the pkgsrc infrastructure.
|
|
#
|
|
# It defines the following shell variables:
|
|
#
|
|
# cleanup
|
|
# If yes (the default), clean up the temporary directory
|
|
# after the test has run successfully.
|
|
#
|
|
# It defines the following shell functions:
|
|
#
|
|
# mock_cmd
|
|
# Returns the path to a newly created shell program whose
|
|
# behavior (output and exit status) is specified by pairs
|
|
# of --when-args/--then-output or --when-args/--then-exit.
|
|
# Example:
|
|
#
|
|
# hello=$(mock_cmd mock-hello \
|
|
# --when-args "" --then-output "Hello, world!" \
|
|
# --when-args "-t" --then-output "hello, world" \
|
|
# --when-args "-?" --then-exit 1
|
|
# )
|
|
#
|
|
# create_file $filename <<EOF ... EOF
|
|
# Creates a file in the temporary directory. The filename
|
|
# is relative to the temporary directory.
|
|
#
|
|
# create_pkgsrc_file $filename <<EOF ... EOF
|
|
# Creates a file in the temporary pkgsrc directory. This
|
|
# file will be included instead of the one in the real
|
|
# pkgsrc infrastructure. The filename is relative to the
|
|
# pkgsrc directory, such as mk/defaults/mk.conf.
|
|
#
|
|
# This is typically used for creating an empty file for
|
|
# mk/bsd.prefs.mk or similar files that are included by the
|
|
# file that is currently under test.
|
|
#
|
|
# test_file $filename $bmake_args...
|
|
# Runs bmake with the correct environment so that it picks
|
|
# up the mocked infrastructure files first and then the ones
|
|
# from the real pkgsrc installation. The filename is
|
|
# relative to the temporary directory.
|
|
#
|
|
# assert_that $actual --equals $expected
|
|
# Complains loudly if $actual is not equal to $expected.
|
|
|
|
: ${cleanup:=yes}
|
|
tmpdir="${TMP:-/tmp}/infra-unittests-$$"
|
|
mocked_pkgsrcdir="$tmpdir/pkgsrc"
|
|
rm -rf "$tmpdir"
|
|
mkdir -p "$mocked_pkgsrcdir"
|
|
|
|
real_pkgsrcdir=""
|
|
for rel in .. ../.. ../../..; do
|
|
[ -f "$rel/mk/bsd.pkg.mk" ] || continue
|
|
real_pkgsrcdir="$rel"
|
|
done
|
|
[ "$real_pkgsrcdir" ] || {
|
|
printf 'error: must be run from somewhere inside the pkgsrc directory\n' 1>&2
|
|
exit 1
|
|
}
|
|
|
|
maybe_cleanup() {
|
|
exit_status=$?
|
|
if [ $exit_status -ne 0 ]; then
|
|
printf 'info: the test files are in %s\n' "$tmpdir" 1>&2
|
|
exit $exit_status
|
|
fi
|
|
|
|
[ "$cleanup" = "yes" ] && rm -rf "$tmpdir"
|
|
}
|
|
trap "maybe_cleanup" EXIT
|
|
|
|
mock_cmd() {
|
|
cmdname="$1"
|
|
shift 1
|
|
|
|
{
|
|
printf '#! /bin/sh\n\n'
|
|
while [ $# -ge 4 ]; do
|
|
case $1,$3 in
|
|
(--when-args,--then-output)
|
|
cat <<EOF
|
|
[ "x\$*" = "x$2" ] && { printf '%s\n' "$4" && exit 0; }
|
|
|
|
EOF
|
|
shift 4
|
|
;;
|
|
(--when-args,--then-exit)
|
|
cat <<EOF
|
|
[ "x\$*" = "x$2" ] && exit $4
|
|
|
|
EOF
|
|
shift 4
|
|
;;
|
|
*) printf 'error: invalid arguments to mock_cmd: %s\n' "$*" 1>&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
cat <<EOF
|
|
printf 'error: %s: no mock behavior defined for arguments %s\n' "\$0" "\$*" 1>&2
|
|
exit 1
|
|
EOF
|
|
} > "$tmpdir/$cmdname"
|
|
chmod +x "$tmpdir/$cmdname"
|
|
|
|
printf '%s\n' "$tmpdir/$cmdname"
|
|
}
|
|
|
|
create_file() {
|
|
cat > "$tmpdir/$1"
|
|
}
|
|
|
|
create_pkgsrc_file() {
|
|
mkdir -p "$mocked_pkgsrcdir/$(dirname "$1")"
|
|
cat > "$mocked_pkgsrcdir/$1"
|
|
}
|
|
|
|
test_file() {
|
|
cat <<EOF > "$tmpdir/test.subr.main.mk"
|
|
PKGSRCDIR= $real_pkgsrcdir
|
|
.PATH: $mocked_pkgsrcdir
|
|
.PATH: $real_pkgsrcdir
|
|
.include "$1"
|
|
EOF
|
|
shift
|
|
|
|
bmake -f "$tmpdir/test.subr.main.mk" "$@"
|
|
}
|
|
|
|
assert_that() {
|
|
case "$2" in
|
|
(--equals)
|
|
[ "x$1" = "x$3" ] && return 0
|
|
printf 'assertion failed:\nexpected: <%s>\nbut was: <%s>\n' "$3" "$1" 1>&2
|
|
exit 1
|
|
(*)
|
|
printf 'usage: assert_that <expr> --equals <expr>\n' 1>&2
|
|
exit 1
|
|
esac
|
|
}
|