summaryrefslogtreecommitdiff
path: root/regress
diff options
context:
space:
mode:
authorrillig <rillig@pkgsrc.org>2019-03-21 21:45:30 +0000
committerrillig <rillig@pkgsrc.org>2019-03-21 21:45:30 +0000
commit17d73acfb8a64e76f249122c1e1dc5b0ccaa910e (patch)
tree44ca9a182bac0c2da91b58a999c6614518a9a54d /regress
parente2da7305f7327e1cc2cfae50c6c0b288126332e1 (diff)
downloadpkgsrc-17d73acfb8a64e76f249122c1e1dc5b0ccaa910e.tar.gz
regress/infra-unittests: add small framework for testing mk/ with mocks
Diffstat (limited to 'regress')
-rw-r--r--regress/Makefile3
-rw-r--r--regress/infra-unittests/mocked-include.sh20
-rw-r--r--regress/infra-unittests/spec12
-rw-r--r--regress/infra-unittests/test.subr146
-rw-r--r--regress/infra-unittests/tools-bison.sh59
5 files changed, 239 insertions, 1 deletions
diff --git a/regress/Makefile b/regress/Makefile
index 9f97c2bde9f..4e2e1c708b5 100644
--- a/regress/Makefile
+++ b/regress/Makefile
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.21 2018/11/10 10:40:55 rillig Exp $
+# $NetBSD: Makefile,v 1.22 2019/03/21 21:45:30 rillig Exp $
#
# See https://www.netbsd.org/docs/pkgsrc/regression.html for more
# information about these tests.
@@ -15,6 +15,7 @@ SUBDIR+= check-portability
SUBDIR+= compiler
SUBDIR+= env-vars
SUBDIR+= ignore-tools
+SUBDIR+= infra-unittests
SUBDIR+= make-env-phases
SUBDIR+= make-quoting
SUBDIR+= pkg-options
diff --git a/regress/infra-unittests/mocked-include.sh b/regress/infra-unittests/mocked-include.sh
new file mode 100644
index 00000000000..cec97a319b1
--- /dev/null
+++ b/regress/infra-unittests/mocked-include.sh
@@ -0,0 +1,20 @@
+#! /bin/sh
+set -eu
+
+# Ensures that files that are overridden in the "mocked pkgsrc" directory
+# are picked up before those from the "real pkgsrc" directory.
+
+. "./test.subr"
+
+create_file "including.mk" <<EOF
+.include "mk/bsd.prefs.mk"
+EOF
+
+create_pkgsrc_file "mk/bsd.prefs.mk" <<EOF
+all:
+ @echo 'the mocked definition wins'
+EOF
+
+out=$(test_file "including.mk")
+
+assert_that "$out" --equals "the mocked definition wins"
diff --git a/regress/infra-unittests/spec b/regress/infra-unittests/spec
new file mode 100644
index 00000000000..b7bde4b3717
--- /dev/null
+++ b/regress/infra-unittests/spec
@@ -0,0 +1,12 @@
+# $NetBSD: spec,v 1.1 2019/03/21 21:45:30 rillig Exp $
+#
+# Unit tests for the pkgsrc infrastructure.
+
+do_test() {
+ sh ./mocked-include.sh || TEST_EXITSTATUS=$?
+ sh ./tools-bison.sh || TEST_EXITSTATUS=$?
+}
+
+check_result() {
+ exit_status 0
+}
diff --git a/regress/infra-unittests/test.subr b/regress/infra-unittests/test.subr
new file mode 100644
index 00000000000..edf3fc43019
--- /dev/null
+++ b/regress/infra-unittests/test.subr
@@ -0,0 +1,146 @@
+#! /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
+}
diff --git a/regress/infra-unittests/tools-bison.sh b/regress/infra-unittests/tools-bison.sh
new file mode 100644
index 00000000000..160328d64a0
--- /dev/null
+++ b/regress/infra-unittests/tools-bison.sh
@@ -0,0 +1,59 @@
+#! /bin/sh
+set -eu
+
+# Tests for mk/tools/bison.mk
+
+. "./test.subr"
+
+bison=$(mock_cmd mock-bison \
+ --when-args "--version" --then-output "bison 1.5"
+)
+
+pkg_admin=$(mock_cmd mock-pkg_admin \
+ --when-args "pmatch bison>=1.0 bison-1.5" --then-exit 0 \
+ --when-args "pmatch bison>=1.1 bison-1.5" --then-exit 0 \
+ --when-args "pmatch bison>=2.0 bison-1.5" --then-exit 1
+)
+
+# A package may add more than one entry to the BISON_REQD list. The
+# platform-provided bison may only be used if all of the BISON_REQD
+# entries are below the platform-provided version.
+#
+create_file "multiple-reqd-entries.mk" <<EOF
+BISON_REQD= 1.0 2.0
+USE_TOOLS= bison
+TOOLS_PLATFORM.bison= $tmpdir/mock-bison
+ECHO= echo
+SED= sed
+PKG_ADMIN= $tmpdir/mock-pkg_admin
+
+all:
+ @echo \${_TOOLS_USE_PKGSRC.bison}
+
+.include "mk/tools/bison.mk"
+EOF
+
+out=$(test_file "multiple-reqd-entries.mk")
+
+assert_that "$out" --equals "yes"
+
+# Both required versions are lower than the version of the mocked bison,
+# which is 1.5. Therefore the platform-provided bison can be used.
+#
+create_file "multiple-reqd-entries.mk" <<EOF
+BISON_REQD= 1.0 1.1
+USE_TOOLS= bison
+TOOLS_PLATFORM.bison= $tmpdir/mock-bison
+ECHO= echo
+SED= sed
+PKG_ADMIN= $tmpdir/mock-pkg_admin
+
+all:
+ @echo \${_TOOLS_USE_PKGSRC.bison}
+
+.include "mk/tools/bison.mk"
+EOF
+
+out=$(test_file "multiple-reqd-entries.mk")
+
+assert_that "$out" --equals "no"