diff options
author | rillig <rillig@pkgsrc.org> | 2019-03-21 21:45:30 +0000 |
---|---|---|
committer | rillig <rillig@pkgsrc.org> | 2019-03-21 21:45:30 +0000 |
commit | 17d73acfb8a64e76f249122c1e1dc5b0ccaa910e (patch) | |
tree | 44ca9a182bac0c2da91b58a999c6614518a9a54d /regress | |
parent | e2da7305f7327e1cc2cfae50c6c0b288126332e1 (diff) | |
download | pkgsrc-17d73acfb8a64e76f249122c1e1dc5b0ccaa910e.tar.gz |
regress/infra-unittests: add small framework for testing mk/ with mocks
Diffstat (limited to 'regress')
-rw-r--r-- | regress/Makefile | 3 | ||||
-rw-r--r-- | regress/infra-unittests/mocked-include.sh | 20 | ||||
-rw-r--r-- | regress/infra-unittests/spec | 12 | ||||
-rw-r--r-- | regress/infra-unittests/test.subr | 146 | ||||
-rw-r--r-- | regress/infra-unittests/tools-bison.sh | 59 |
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" |