summaryrefslogtreecommitdiff
path: root/pkgtools/pkgtasks/files/t
diff options
context:
space:
mode:
Diffstat (limited to 'pkgtools/pkgtasks/files/t')
-rw-r--r--pkgtools/pkgtasks/files/t/Kyuafile84
-rw-r--r--pkgtools/pkgtasks/files/t/build_test.sh134
-rw-r--r--pkgtools/pkgtasks/files/t/run_tests.sh167
-rw-r--r--pkgtools/pkgtasks/files/t/t_compare.sh157
-rw-r--r--pkgtools/pkgtasks/files/t/t_createfile.sh91
-rw-r--r--pkgtools/pkgtasks/files/t/t_directories.sh386
-rw-r--r--pkgtools/pkgtasks/files/t/t_dirwalk.sh144
-rw-r--r--pkgtools/pkgtasks/files/t/t_echo.sh378
-rw-r--r--pkgtools/pkgtasks/files/t/t_files.sh781
-rw-r--r--pkgtools/pkgtasks/files/t/t_fonts.sh347
-rw-r--r--pkgtools/pkgtasks/files/t/t_groups.sh193
-rw-r--r--pkgtools/pkgtasks/files/t/t_info_files.sh411
-rw-r--r--pkgtools/pkgtasks/files/t/t_lock.sh120
-rw-r--r--pkgtools/pkgtasks/files/t/t_makedir.sh70
-rw-r--r--pkgtools/pkgtasks/files/t/t_maketemp.sh215
-rw-r--r--pkgtools/pkgtasks/files/t/t_match.sh175
-rw-r--r--pkgtools/pkgtasks/files/t/t_ocaml_findlib.sh346
-rw-r--r--pkgtools/pkgtasks/files/t/t_permissions.sh172
-rw-r--r--pkgtools/pkgtasks/files/t/t_platform.sh68
-rw-r--r--pkgtools/pkgtasks/files/t/t_postinstall.sh199
-rw-r--r--pkgtools/pkgtasks/files/t/t_postremove.sh217
-rw-r--r--pkgtools/pkgtasks/files/t/t_preinstall.sh117
-rw-r--r--pkgtools/pkgtasks/files/t/t_preremove.sh105
-rw-r--r--pkgtools/pkgtasks/files/t/t_quote.sh118
-rw-r--r--pkgtools/pkgtasks/files/t/t_random.sh61
-rw-r--r--pkgtools/pkgtasks/files/t/t_refcount.sh397
-rw-r--r--pkgtools/pkgtasks/files/t/t_shells.sh339
-rw-r--r--pkgtools/pkgtasks/files/t/t_shlibs.sh106
-rw-r--r--pkgtools/pkgtasks/files/t/t_sort.sh155
-rw-r--r--pkgtools/pkgtasks/files/t/t_taskfunc.sh173
-rw-r--r--pkgtools/pkgtasks/files/t/t_tee.sh133
-rw-r--r--pkgtools/pkgtasks/files/t/t_truthy.sh72
-rw-r--r--pkgtools/pkgtasks/files/t/t_usergroup.sh194
-rw-r--r--pkgtools/pkgtasks/files/t/t_usergroup_FreeBSD.sh53
-rw-r--r--pkgtools/pkgtasks/files/t/t_usergroup_Linux.sh102
-rw-r--r--pkgtools/pkgtasks/files/t/t_usergroup_MirBSD.sh378
-rw-r--r--pkgtools/pkgtasks/files/t/t_usergroup_NetBSD.sh51
-rw-r--r--pkgtools/pkgtasks/files/t/t_usergroup_exists.sh206
-rw-r--r--pkgtools/pkgtasks/files/t/t_usergroup_mock.sh334
-rw-r--r--pkgtools/pkgtasks/files/t/t_users.sh194
-rw-r--r--pkgtools/pkgtasks/files/t/t_valid_options.sh95
-rw-r--r--pkgtools/pkgtasks/files/t/t_version.sh322
-rw-r--r--pkgtools/pkgtasks/files/t/t_which.sh96
43 files changed, 8656 insertions, 0 deletions
diff --git a/pkgtools/pkgtasks/files/t/Kyuafile b/pkgtools/pkgtasks/files/t/Kyuafile
new file mode 100644
index 00000000000..090db59bc49
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/Kyuafile
@@ -0,0 +1,84 @@
+--[[-----------------------------------------------------------------------
+Copyright (c) 2017 The NetBSD Foundation, Inc.
+All rights reserved.
+
+This code is derived from software contributed to The NetBSD Foundation
+by Johnny C. Lam.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+--]]-----------------------------------------------------------------------
+--[[-----------------------------------------------------------------------
+
+ The following variables will be used if they are set.
+
+ TASK_MODULE_DIR
+ The location where the task modules are found.
+
+ TASK_TESTS_DIR
+ The location where this Kyuafile is found.
+
+--]]-----------------------------------------------------------------------
+
+syntax( 2 )
+
+test_suite( "pkgtasks" )
+
+tap_test_program { name = "t_compare" }
+tap_test_program { name = "t_createfile" }
+tap_test_program { name = "t_directories" }
+tap_test_program { name = "t_dirwalk" }
+tap_test_program { name = "t_echo" }
+tap_test_program { name = "t_files" }
+tap_test_program { name = "t_fonts" }
+tap_test_program { name = "t_groups" }
+tap_test_program { name = "t_info_files" }
+tap_test_program { name = "t_lock" }
+tap_test_program { name = "t_makedir" }
+tap_test_program { name = "t_maketemp" }
+tap_test_program { name = "t_match" }
+tap_test_program { name = "t_ocaml_findlib" }
+tap_test_program { name = "t_permissions" }
+tap_test_program { name = "t_platform" }
+tap_test_program { name = "t_postinstall" }
+tap_test_program { name = "t_postremove" }
+tap_test_program { name = "t_preinstall" }
+tap_test_program { name = "t_preremove" }
+tap_test_program { name = "t_quote" }
+tap_test_program { name = "t_random" }
+tap_test_program { name = "t_refcount" }
+tap_test_program { name = "t_shells" }
+tap_test_program { name = "t_shlibs" }
+tap_test_program { name = "t_sort" }
+tap_test_program { name = "t_taskfunc" }
+tap_test_program { name = "t_tee" }
+tap_test_program { name = "t_truthy" }
+tap_test_program { name = "t_usergroup" }
+tap_test_program { name = "t_usergroup_FreeBSD" }
+tap_test_program { name = "t_usergroup_Linux" }
+tap_test_program { name = "t_usergroup_MirBSD" }
+tap_test_program { name = "t_usergroup_NetBSD" }
+tap_test_program { name = "t_usergroup_exists" }
+tap_test_program { name = "t_usergroup_mock" }
+tap_test_program { name = "t_users" }
+tap_test_program { name = "t_valid_options" }
+tap_test_program { name = "t_version" }
+tap_test_program { name = "t_which" }
diff --git a/pkgtools/pkgtasks/files/t/build_test.sh b/pkgtools/pkgtasks/files/t/build_test.sh
new file mode 100644
index 00000000000..bd99af4a8bd
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/build_test.sh
@@ -0,0 +1,134 @@
+#! __POSIX_SHELL__
+#
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# NAME
+# build_test -- build standalone test scripts
+#
+# SYNOPSIS
+# build_test [-o <target>] <source>
+#
+# DESCRIPTION
+# build_test takes a script that uses pkgtask modules and generates an
+# executable script with the necessary boilerplate to run standalone.
+#
+# The <source> is the path to the file to build. The built script is
+# written to the standard output.
+#
+# The options are as follows:
+#
+# -o <output>
+# The path to the output file to write the built script.
+# If this option is given, then the built script is also made
+# executable.
+#
+# EXIT STATUS
+# The script exits with a value of 0 on success, and >0 if an error
+# occurs.
+#
+# ENVIRONMENT
+# The following variables are used if they are set:
+#
+# TASK_MODULE_DIR
+# The location of the pkgtask modules. The default value is
+# "__TASK_MODULE_DIR__".
+#
+# TASK_TESTS_DIR
+# The location of the pkgtask tests directory. The default
+# value is "__TASK_TESTS_DIR__".
+#
+# POSIX_SHELL
+# The path of the shell interpreter to add to the shebang
+# boilerplate of the built script. The default value is
+# "__POSIX_SHELL__".
+#
+
+: ${TASK_MODULE_DIR:=__TASK_MODULE_DIR__}
+: ${TASK_TESTS_DIR:=__TASK_TESTS_DIR__}
+: ${POSIX_SHELL:=__POSIX_SHELL__}
+
+. "${TASK_MODULE_DIR}/load.subr"
+
+task_load maketemp
+
+build_test()
+{
+ : ${CAT:=cat}
+ : ${CHMOD:=chmod}
+ : ${MV:=mv}
+
+ local output=
+ local arg
+ local OPTIND=1
+ while getopts ":o:" arg "$@"; do
+ case $arg in
+ o) output="${OPTARG}" ;;
+ *) return 127 ;;
+ esac
+ done
+ shift $(( ${OPTIND} - 1 ))
+
+ # Setting the output file to "-" means to write to standard output.
+ if [ "$output" = "-" ]; then
+ output=
+ fi
+
+ # Use standard input unless source files are given.
+ [ $# -gt 0 ] || set -- "-"
+
+ if [ -n "$output" ]; then
+ local output_tmp
+ output_tmp=$( task_maketemp $output.XXXXXXXXXX ) &&
+ ( _build_test_boilerplate && ${CAT} "$@" ) > $output_tmp &&
+ ${MV} -f "$output_tmp" "$output" &&
+ ${CHMOD} +x "$output"
+ else
+ # Write script to standard output.
+ _build_test_boilerplate && ${CAT} "$@"
+ fi
+}
+
+_build_test_boilerplate()
+{
+ : ${CAT:=cat}
+
+ ${CAT} << EOF
+#! ${POSIX_SHELL}
+
+: \${TASK_MODULE_DIR:=__TASK_MODULE_DIR__}
+: \${TASK_TESTS_DIR:=__TASK_TESTS_DIR__}
+
+[ -f "\${TASK_MODULE_DIR}/load.subr" ] ||
+ echo "\${0##*/}: missing file \`\`\${TASK_MODULE_DIR}/load.subr''"
+
+. "\${TASK_MODULE_DIR}/load.subr"
+
+EOF
+}
+
+build_test "$@"
diff --git a/pkgtools/pkgtasks/files/t/run_tests.sh b/pkgtools/pkgtasks/files/t/run_tests.sh
new file mode 100644
index 00000000000..7023ba02289
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/run_tests.sh
@@ -0,0 +1,167 @@
+#! __POSIX_SHELL__
+#
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# NAME
+# run_tests -- run all of the test scripts for pkgtasks
+#
+# SYNOPSIS
+# run_tests [-v] [<script> ...]
+#
+# DESCRIPTION
+# run_tests runs the test scripts in the ${TASK_TESTS_DIR} directory
+# and reports a summary of the test results. By default, all of the
+# test scripts are run, but a subset may be selected by passing their
+# names as optional parameters.
+#
+# The options are as follows:
+#
+# -v Verbose; run the tests so they produce output to the
+# standard output and error. By default, the tests are run
+# in quiet mode.
+#
+# If this script is run with a basename ending in ".sh", then the
+# tests are assumed to be named also ending in ".sh" and located in
+# the current directory. This is to allow the tests to be run from
+# their source directory.
+#
+# EXIT STATUS
+# The script exits with a value of the number of failed tests.
+#
+
+case ${0##*/} in
+*.sh) # Invoked from source directory.
+ : ${TASK_MODULE_DIR:=..}
+ : ${TASK_TESTS_DIR:=.}
+ ;;
+*) # Invoked from installed tests directory.
+ : ${TASK_MODULE_DIR:=__TASK_MODULE_DIR__}
+ : ${TASK_TESTS_DIR:=__TASK_TESTS_DIR__}
+ ;;
+esac
+
+. ${TASK_MODULE_DIR}/load.subr
+
+# Use the same TASK_MODULE_DIR for all test scripts.
+export TASK_MODULE_DIR="${TASK_MODULE_DIR}"
+
+# Use the same TASK_TEST_DIR for all test scripts.
+export TASK_TESTS_DIR="${TASK_TESTS_DIR}"
+
+task_load say
+
+run_tests()
+{
+ local quiet="-q"
+ local arg
+ local OPTIND=1
+ while getopts ":s:v" arg "$@"; do
+ case $arg in
+ v) quiet= ;;
+ *) return 127 ;;
+ esac
+ done
+ shift $(( ${OPTIND} - 1 ))
+
+ local suffix
+ case $0 in
+ *.sh) suffix=".sh" ;;
+ *) suffix= ;;
+ esac
+
+ # glob pattern to match test scripts
+ local test_pattern="${TASK_TESTS_DIR}/t_*$suffix"
+
+ [ $# -gt 0 ] || set -- $test_pattern
+
+ local count=0
+ local missing=
+ local failures=
+
+ local script
+ local script_args
+ while [ $# -gt 0 ]; do
+ script=$1; shift
+ if ! [ -f "$script" ]; then
+ missing="$missing $script"
+ continue
+ fi
+ case $script in
+ */*) name=${script##*/}
+ : "script unchanged" ;;
+ *) name=$script
+ script="./$script" ;;
+ esac
+
+ # Set up the script parameters. If the next parameter is
+ # "--", then all remaining arguments are used as parameters
+ # for the script.
+ #
+ script_args="$quiet"
+ if [ "$1" = "--" ]; then
+ shift
+ script_args="$@"
+ # shift away the remaining arguments so the loop will end
+ shift $#
+ fi
+
+ count=$(( $count + 1 ))
+ task_say info "*** $name ***"
+ #
+ # Run the test scripts by explicitly loading load.subr,
+ # setting up the parameters, and sourcing the script file,
+ # all within a subshell. This allows the test scripts to be
+ # run without being built.
+ #
+ ( . ${TASK_MODULE_DIR}/load.subr
+ set -- dummy $script_args; shift
+ . $script )
+ [ $? -eq 0 ] || failures="$failures $name"
+ done
+
+ set -o noglob; set -- $missing; set +o noglob
+ for script; do
+ task_say warn "# run_tests: missing: $script"
+ done
+
+ set -o noglob; set -- $failures; set +o noglob
+ for script; do
+ task_say error "# run_tests: failed: $script"
+ done
+
+ local msg="$count test script(s)"
+ if [ $# -gt 0 ]; then
+ task_say error "# run_tests: failed $# among $msg"
+ else
+ task_say pass "# run_tests: passed all $msg"
+ fi
+
+ return $#
+}
+
+run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_compare.sh b/pkgtools/pkgtasks/files/t/t_compare.sh
new file mode 100644
index 00000000000..45f7c7b7933
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_compare.sh
@@ -0,0 +1,157 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load compare
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${CP:=cp}
+}
+
+test1()
+{
+ describe="identical files"
+ ${CAT} > a << EOF
+line1
+line2
+line3
+EOF
+ ${CP} a b
+ if task_compare a b; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="truncated first file"
+ ${CAT} > a << EOF
+line1
+line2
+EOF
+ ${CAT} > b << EOF
+line1
+line2
+line3
+EOF
+ if task_compare a b; then
+ return 1
+ else
+ : "success"
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="truncated second file"
+ ${CAT} > a << EOF
+line1
+line2
+line3
+EOF
+ ${CAT} > b << EOF
+line1
+line2
+EOF
+ if task_compare a b; then
+ return 1
+ else
+ : "success"
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="leading whitespace differences"
+ ${CAT} > a << EOF
+line1
+line2
+line3
+EOF
+ ${CAT} > b << EOF
+line1
+ line2
+ line3
+EOF
+ if task_compare a b; then
+ return 1
+ else
+ : "success"
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="trailing whitespace differences"
+ ${CAT} > a << EOF
+line1
+line2
+line3
+EOF
+ ${CAT} > b << EOF
+line1
+line2
+line3
+EOF
+ if task_compare a b; then
+ return 1
+ else
+ : "success"
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="different content"
+ ${CAT} > a << EOF
+line1
+line2
+line3
+EOF
+ ${CAT} > b << EOF
+LINE1
+LINE2
+LINE3
+EOF
+ if task_compare a b; then
+ return 1
+ else
+ : "success"
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_createfile.sh b/pkgtools/pkgtasks/files/t/t_createfile.sh
new file mode 100644
index 00000000000..892508d378c
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_createfile.sh
@@ -0,0 +1,91 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load permissions
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+}
+
+test1()
+{
+ describe="make one file"
+ task_createfile a
+ if [ ! -f "a" ]; then
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="make two files"
+ task_createfile a b
+ if [ ! -f "a" -o ! -f "b" ]; then
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="make file with mode"
+ task_createfile -m 600 a
+ if [ ! -f "a" ]; then
+ return 1
+ fi
+ if task_check_permissions a 600; then
+ : "success"
+ else
+ describe="$describe: wrong mode!"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="overwrite existing file"
+ ${CAT} > a << 'EOF'
+content
+EOF
+ task_createfile a
+ if [ ! -f "a" ]; then
+ return 1
+ fi
+ local line
+ while read line; do
+ describe="$describe: non-empty file!"
+ return 1
+ done < a
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_directories.sh b/pkgtools/pkgtasks/files/t/t_directories.sh
new file mode 100644
index 00000000000..d9cb70cac85
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_directories.sh
@@ -0,0 +1,386 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load directories
+task_load unittest
+
+test_setup()
+{
+ : ${MKDIR:=mkdir}
+
+ PKGNAME=${0##*/}
+ PKG_PREFIX=${TEST_CURDIR}
+ PKG_DESTDIR=
+
+ PKG_DBDIR="${TEST_CURDIR}/var/db/pkg"
+ PKG_REFCOUNT_DBDIR="${PKG_DBDIR}.refcount"
+ ${MKDIR} -p "${PKG_DBDIR}"
+}
+
+test_destdir_setup()
+{
+ : ${MKDIR:=mkdir}
+ : ${MV:=mv}
+
+ PKG_DESTDIR="${TEST_CURDIR}/destdir"
+ ${MKDIR} -p "${PKG_DESTDIR}${PKG_PREFIX}"
+ ${MV} var "${PKG_DESTDIR}${PKG_PREFIX}"
+}
+
+test1()
+{
+ describe="make dir"
+ if echo "# DIR: etc/pkg1 m" | task_directories add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# DIR: etc/pkg1 m" | task_directories check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ ! -d "${PKG_PREFIX}/etc/pkg1" ]; then
+ describe="$describe: dir missing!"
+ return 1
+ fi
+ if task_refcount exists dirs "${PKG_PREFIX}/etc/pkg1"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="skip make dir"
+ if echo "# DIR: etc/pkg1 ." | task_directories add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# DIR: etc/pkg1 ." | task_directories check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/etc/pkg1" ]; then
+ describe="$describe: dir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="remove make dir"
+ echo "# DIR: etc/pkg1 m" | task_directories add
+ if echo "# DIR: etc/pkg1 m" | task_directories remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# DIR: etc/pkg1 m" | task_directories check-remove; then
+ : "success"
+ else
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/etc/pkg1" ]; then
+ describe="$describe: dir exists!"
+ return 1
+ fi
+ if task_refcount exists dirs "${PKG_PREFIX}/etc/pkg1"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="remove skipped make dir"
+ echo "# DIR: etc/pkg1 ." | task_directories add
+ if echo "# DIR: etc/pkg1 ." | task_directories remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# DIR: etc/pkg1 ." | task_directories check-remove; then
+ : "success"
+ else
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/etc/pkg1" ]; then
+ describe="$describe: dir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="remove skipped made dir"
+ echo "# DIR: etc/pkg1 ." | task_directories add
+ ${MKDIR} -p etc/pkg1
+ if echo "# DIR: etc/pkg1 ." | task_directories remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# DIR: etc/pkg1 ." | task_directories check-remove; then
+ : "success"
+ else
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/etc/pkg1" ]; then
+ describe="$describe: dir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="make dir for 2 packages"
+ ( PKGNAME="package1"
+ echo "# DIR: etc/common m" | task_directories add )
+ ( PKGNAME="package2"
+ echo "# DIR: etc/common m" | task_directories add )
+ if [ ! -d "${PKG_PREFIX}/etc/common" ]; then
+ describe="$describe: dir missing!"
+ return 1
+ fi
+ if task_refcount exists dirs "${PKG_PREFIX}/etc/common"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="remove after make dir for 2 packages"
+ ( PKGNAME="package1"
+ echo "# DIR: etc/common m" | task_directories add )
+ ( PKGNAME="package2"
+ echo "# DIR: etc/common m" | task_directories add )
+ ( PKGNAME="package1"
+ echo "# DIR: etc/common m" | task_directories remove )
+ if [ ! -d "${PKG_PREFIX}/etc/common" ]; then
+ describe="$describe: dir missing!"
+ return 1
+ fi
+ ( PKGNAME="package2"
+ echo "# DIR: etc/common m" | task_directories remove )
+ if [ -d "${PKG_PREFIX}/etc/common" ]; then
+ describe="$describe: dir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="remove owned directory"
+ echo "# DIR: etc/pkg1 mo" | task_directories add
+ echo "# DIR: etc/pkg1 mo" | task_directories remove
+ if [ -d "${PKG_PREFIX}/etc/pkg1" ]; then
+ describe="$describe: dir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="conflicting owner"
+ ( PKGNAME="package1"
+ echo "# DIR: etc/common mo" | task_directories add )
+ ( PKGNAME="package2"
+ echo "# DIR: etc/common mo" | task_directories add )
+ if [ $? -eq 0 ]; then
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="remove owned directory used by another package"
+ ( PKGNAME="package1"
+ echo "# DIR: etc/common mo" | task_directories add )
+ ( PKGNAME="package2"
+ echo "# DIR: etc/common m" | task_directories add )
+ ( PKGNAME="package1"
+ echo "# DIR: etc/common mo" | task_directories remove )
+ if [ $? -eq 0 ]; then
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="owned dir with permissions"
+ task_requires_root || return 0
+ if echo "# DIR: etc/pkg1 mo 0700 root wheel" |
+ task_directories add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# DIR: etc/pkg1 mo 0700 root wheel" |
+ task_directories check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if echo "# DIR: etc/pkg1 mo 0700 root wheel" |
+ task_directories check-perms; then
+ : "success"
+ else
+ describe="$describe: check-perms"
+ return 1
+ fi
+ if [ ! -d "${PKG_PREFIX}/etc/pkg1" ]; then
+ describe="$describe: dir missing!"
+ return 1
+ fi
+}
+
+test12()
+{
+ describe="make dir with PKG_DESTDIR"
+ test_destdir_setup
+ if echo "# DIR: etc/pkg1 m" | task_directories add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# DIR: etc/pkg1 m" | task_directories check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ ! -d "${PKG_DESTDIR}${PKG_PREFIX}/etc/pkg1" ]; then
+ describe="$describe: dir missing!"
+ return 1
+ fi
+ if task_refcount exists dirs "${PKG_PREFIX}/etc/pkg1"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ return 0
+}
+
+test13()
+{
+ describe="skip make dir with PKG_DESTDIR"
+ test_destdir_setup
+ if echo "# DIR: etc/pkg1 ." | task_directories add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# DIR: etc/pkg1 ." | task_directories check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ -d "${PKG_DESTDIR}${PKG_PREFIX}/etc/pkg1" ]; then
+ describe="$describe: dir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test14()
+{
+ describe="remove make dir with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# DIR: etc/pkg1 m" | task_directories add
+ if echo "# DIR: etc/pkg1 m" | task_directories remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# DIR: etc/pkg1 m" | task_directories check-remove; then
+ : "success"
+ else
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ -d "${PKG_DESTDIR}${PKG_PREFIX}/etc/pkg1" ]; then
+ describe="$describe: dir exists!"
+ return 1
+ fi
+ if task_refcount exists dirs "${PKG_PREFIX}/etc/pkg1"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ return 0
+}
+
+test15()
+{
+ describe="remove skipped made dir with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# DIR: etc/pkg1 ." | task_directories add
+ ${MKDIR} -p ${PKG_DESTDIR}${PKG_PREFIX}/etc/pkg1
+ if echo "# DIR: etc/pkg1 ." | task_directories remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# DIR: etc/pkg1 ." | task_directories check-remove; then
+ : "success"
+ else
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ -d "${PKG_DESTDIR}${PKG_PREFIX}/etc/pkg1" ]; then
+ describe="$describe: dir exists!"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_dirwalk.sh b/pkgtools/pkgtasks/files/t/t_dirwalk.sh
new file mode 100644
index 00000000000..7c7ec865a5c
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_dirwalk.sh
@@ -0,0 +1,144 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load dirwalk
+task_load unittest
+
+# Mock a broken utility.
+broken()
+{
+ return 1
+}
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${CMP:=cmp}
+ : ${MKDIR:=mkdir}
+
+ # Set FIND to a broken utility to force using the shell code path.
+ FIND=broken
+
+ output="output"
+
+ # ./
+ # `---root/
+ # |
+ # |---dir1/
+ # | |---fileA
+ # | |---dirB/
+ # | | |---filea
+ # | | `---fileb
+ # | `---fileC
+ # |---file2
+ # `---dir3/
+ # |---fileD
+ # `---fileE
+ #
+ ${MKDIR} root
+ ${MKDIR} root/dir1
+ task_createfile root/dir1/fileA
+ ${MKDIR} root/dir1/dirB
+ task_createfile root/dir1/dirB/filea
+ task_createfile root/dir1/dirB/fileb
+ task_createfile root/dir1/fileC
+ task_createfile root/file2
+ ${MKDIR} root/dir3
+ task_createfile root/dir3/fileD
+ task_createfile root/dir3/fileE
+
+ expected_all="expected_all"
+ ${CAT} > $expected_all << EOF
+root
+root/dir1
+root/dir1/dirB
+root/dir1/dirB/filea
+root/dir1/dirB/fileb
+root/dir1/fileA
+root/dir1/fileC
+root/dir3
+root/dir3/fileD
+root/dir3/fileE
+root/file2
+EOF
+ expected_dirs="expected_dirs"
+ ${CAT} > $expected_dirs << EOF
+root
+root/dir1
+root/dir1/dirB
+root/dir3
+EOF
+ expected_files="expected_files"
+ ${CAT} > $expected_files << EOF
+root/dir1/dirB/filea
+root/dir1/dirB/fileb
+root/dir1/fileA
+root/dir1/fileC
+root/dir3/fileD
+root/dir3/fileE
+root/file2
+EOF
+}
+
+test1()
+{
+ describe="dirwalk root"
+ task_dirwalk root > $output
+ if ${CMP} -s "$expected_all" "$output"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="dirwalk -d root"
+ task_dirwalk -d root > $output
+ if ${CMP} -s "$expected_dirs" "$output"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="dirwalk -f root"
+ task_dirwalk -f root > $output
+ if ${CMP} -s "$expected_files" "$output"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_echo.sh b/pkgtools/pkgtasks/files/t/t_echo.sh
new file mode 100644
index 00000000000..75943d6b4d6
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_echo.sh
@@ -0,0 +1,378 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load echo
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${CMP:=cmp}
+
+ # Explicitly set TASK_LOGFILE to empty string to prevent unintended
+ # duplicate output.
+ #
+ TASK_LOGFILE=
+}
+
+test1()
+{
+ describe="task_echo -b buffers text"
+ task_echo -bc "line 1"
+ task_echo -b "line 2"
+ task_echo "line 3" > value
+ ${CAT} > expected << 'EOF'
+line 1
+line 2
+line 3
+EOF
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ return 1
+ fi
+ task_echo "only line" > value
+ echo "only line" > expected
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ describe="$describe: next write has extra output!"
+ return 1
+ fi
+ for entry in *; do
+ case $entry in
+ expected|value)
+ : "can exist" ;;
+ *) describe="$describe: unknown file!"
+ return 1 ;;
+ esac
+ done
+ return 0
+}
+
+test2()
+{
+ describe="task_echo -c clears buffer"
+ task_echo -bc "line 1"
+ task_echo -b "line 2"
+ task_echo -cn
+ task_echo "only line" > value
+ echo "only line" > expected
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ return 1
+ fi
+ for entry in *; do
+ case $entry in
+ expected|value)
+ : "can exist" ;;
+ *) describe="$describe: unknown file!"
+ return 1 ;;
+ esac
+ done
+ return 0
+}
+
+test3()
+{
+ describe="task_echo -bc clears buffer"
+ task_echo -bc "line 1"
+ task_echo -b "line 2"
+ task_echo -bc "line 3"
+ task_echo "line 4" > value
+ ${CAT} > expected << 'EOF'
+line 3
+line 4
+EOF
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ for entry in *; do
+ case $entry in
+ expected|value)
+ : "can exist" ;;
+ *) describe="$describe: unknown file!"
+ return 1 ;;
+ esac
+ done
+ return 0
+}
+
+test4()
+{
+ describe="task_echo -n skips trailing newline"
+ task_echo -bcn "list: 1"
+ task_echo -bn ", 2"
+ task_echo -bn ", 3"
+ task_echo > value
+ echo "list: 1, 2, 3" > expected
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ for entry in *; do
+ case $entry in
+ expected|value)
+ : "can exist" ;;
+ *) describe="$describe: unknown file!"
+ return 1 ;;
+ esac
+ done
+ return 0
+}
+
+test5()
+{
+ describe="task_echo preserves leading whitespace"
+ task_echo " 1 2 3 4" > value
+ echo " 1 2 3 4" > expected
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ for entry in *; do
+ case $entry in
+ expected|value)
+ : "can exist" ;;
+ *) describe="$describe: unknown file!"
+ return 1 ;;
+ esac
+ done
+ return 0
+}
+
+test6()
+{
+ describe="task_echo preserves leading whitespace after buffer output"
+ task_echo -bc "header"
+ task_echo " 1 2 3 4" > value
+ ${CAT} > expected << 'EOF'
+header
+ 1 2 3 4
+EOF
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ for entry in *; do
+ case $entry in
+ expected|value)
+ : "can exist" ;;
+ *) describe="$describe: unknown file!"
+ return 1 ;;
+ esac
+ done
+ return 0
+}
+
+
+test7()
+{
+ describe="task_echo -b buffers text with log"
+ TASK_LOGFILE="${TEST_CURDIR}/log"
+ task_echo -bc "line 1"
+ if [ -f "${TASK_LOGFILE}" ]; then
+ describe="$describe: log exists after first buffered echo!"
+ return 1
+ fi
+ task_echo -b "line 2"
+ if [ -f "${TASK_LOGFILE}" ]; then
+ describe="$describe: log exists after second buffered echo!"
+ return 1
+ fi
+ task_echo "line 3" > value
+ if [ ! -f "${TASK_LOGFILE}" ]; then
+ describe="$describe: log missing!"
+ return 1
+ fi
+ ${CAT} > expected << 'EOF'
+line 1
+line 2
+line 3
+EOF
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ return 1
+ fi
+ if ${CMP} -s value log; then
+ : "success"
+ else
+ describe="$describe: log doesn't match standard output!"
+ ${CAT} log
+ return 1
+ fi
+ task_echo "only line" > value
+ echo "only line" >> expected
+ if ${CMP} -s expected log; then
+ : "success"
+ else
+ describe="$describe: log doesn't match all writes!"
+ ${CAT} log
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="task_echo -c clears buffer with log"
+ TASK_LOGFILE="${TEST_CURDIR}/log"
+ task_echo -bc "line 1"
+ task_echo -b "line 2"
+ task_echo -cn
+ task_echo "only line" > value
+ echo "only line" > expected
+ if ${CMP} -s expected log; then
+ : "success"
+ else
+ ${CAT} log
+ return 1
+ fi
+ if ${CMP} -s value log; then
+ : "success"
+ else
+ describe="$describe: log doesn't match output"
+ ${CAT} log
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="task_echo -bc clears buffer with log"
+ TASK_LOGFILE="${TEST_CURDIR}/log"
+ task_echo -bc "line 1"
+ task_echo -b "line 2"
+ task_echo -bc "line 3"
+ task_echo "line 4" > value
+ ${CAT} > expected << 'EOF'
+line 3
+line 4
+EOF
+ if ${CMP} -s expected log; then
+ : "success"
+ else
+ ${CAT} log
+ return 1
+ fi
+ if ${CMP} -s value log; then
+ : "success"
+ else
+ describe="$describe: log doesn't match output"
+ ${CAT} log
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="task_echo -n skips trailing newline with log"
+ TASK_LOGFILE="${TEST_CURDIR}/log"
+ task_echo -bcn "list: 1"
+ task_echo -bn ", 2"
+ task_echo -bn ", 3"
+ task_echo > value
+ echo "list: 1, 2, 3" > expected
+ if ${CMP} -s expected log; then
+ : "success"
+ else
+ ${CAT} log
+ return 1
+ fi
+ if ${CMP} -s value log; then
+ : "success"
+ else
+ describe="$describe: log doesn't match output"
+ ${CAT} log
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="task_echo preserves leading whitespace with log"
+ TASK_LOGFILE="${TEST_CURDIR}/log"
+ task_echo " 1 2 3 4" > value
+ echo " 1 2 3 4" > expected
+ if ${CMP} -s expected log; then
+ : "success"
+ else
+ ${CAT} log
+ return 1
+ fi
+ if ${CMP} -s value log; then
+ : "success"
+ else
+ describe="$describe: log doesn't match output"
+ ${CAT} log
+ return 1
+ fi
+ return 0
+}
+
+test12()
+{
+ describe="task_echo preserves leading whitespace after buffer output with log"
+ TASK_LOGFILE="${TEST_CURDIR}/log"
+ task_echo -bc "header"
+ task_echo " 1 2 3 4" > value
+ ${CAT} > expected << 'EOF'
+header
+ 1 2 3 4
+EOF
+ if ${CMP} -s expected log; then
+ : "success"
+ else
+ ${CAT} log
+ return 1
+ fi
+ if ${CMP} -s value log; then
+ : "success"
+ else
+ describe="$describe: log doesn't match output"
+ ${CAT} log
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_files.sh b/pkgtools/pkgtasks/files/t/t_files.sh
new file mode 100644
index 00000000000..d6d1ceef30e
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_files.sh
@@ -0,0 +1,781 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load files
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${CHMOD:=chmod}
+ : ${MKDIR:=mkdir}
+
+ PKGNAME=${0##*/}
+ PKG_PREFIX=${TEST_CURDIR}
+ PKG_DESTDIR=
+
+ PKG_DBDIR="${PKG_PREFIX}/var/db/pkg"
+ PKG_REFCOUNT_DBDIR="${PKG_DBDIR}.refcount"
+ ${MKDIR} -p "${PKG_DBDIR}"
+
+ ${MKDIR} -p etc
+ ${MKDIR} -p etc/rc.d
+ ${MKDIR} -p share/examples/pkg1
+ ${MKDIR} -p share/examples/pkg2
+ ${CAT} > share/examples/pkg2/conffile2 << EOF
+line 1
+line 2
+EOF
+ ${MKDIR} -p share/examples/rc.d
+
+ # Unwriteable directory.
+ ${MKDIR} -p unwriteable
+ ${CHMOD} 0400 unwriteable
+
+ # Don't copy rc.d scripts.
+ PKG_INIT_SCRIPTS="no"
+}
+
+test_destdir_setup()
+{
+ : ${MKDIR:=mkdir}
+ : ${MV:=mv}
+
+ PKG_DESTDIR="${TEST_CURDIR}/destdir"
+ ${MKDIR} -p "${PKG_DESTDIR}${PKG_PREFIX}"
+ ${MV} etc share var "${PKG_DESTDIR}${PKG_PREFIX}"
+
+ # Unwriteable directory.
+ ${MKDIR} -p "${PKG_DESTDIR}${PKG_PREFIX}/unwriteable"
+ ${CHMOD} 0400 "${PKG_DESTDIR}${PKG_PREFIX}/unwriteable"
+}
+
+test1()
+{
+ describe="missing example file"
+ if echo "# FILE: \
+ etc/conffile1 c \
+ share/examples/pkg1/conffile1" | task_files add; then
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile1 c \
+ share/examples/pkg1/conffile1" | task_files check-add; then
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/etc/conffile1" ]; then
+ describe="$describe: copied file exists!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile1"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="missing target directory"
+ if echo "# FILE: \
+ nonexistent/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files add; then
+ return 1
+ fi
+ if echo "# FILE: \
+ nonexistent/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-add; then
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/nonexistent/conffile2" ]; then
+ describe="$describe: copied file exists!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/nonexistent/conffile2"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="copy"
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ ! -f "${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file missing!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="skip copy"
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file exists!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="copy rc.d script"
+ if echo "# FILE: \
+ etc/rc.d/conffile2 cr \
+ share/examples/pkg2/conffile2" | task_files add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/rc.d/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-add; then
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/etc/rc.d/conffile2" ]; then
+ describe="$describe: file exists!"
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="remove after copy"
+ echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files add
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-remove; then
+ : "success"
+ else
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file exists!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ : ${CP:=cp}
+
+ describe="remove after skipped but copied"
+ echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files add
+ ${CP} share/examples/pkg2/conffile2 etc/conffile2
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files check-remove; then
+ : "success"
+ else
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file exists!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="remove after modification"
+ echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files add
+ echo "extra line" >> "${PKG_PREFIX}/etc/conffile2"
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-remove; then
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ ! -f "${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file missing!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ : ${CP:=cp}
+
+ describe="remove after skipped but copied and modification"
+ echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files add
+ ${CP} share/examples/pkg2/conffile2 etc/conffile2
+ echo "extra line" >> "${PKG_PREFIX}/etc/conffile2"
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files check-remove; then
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ ! -f "${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file missing!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="copy with preexisting"
+ task_createfile etc/conffile2
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ ! -f "${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file missing!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ if task_refcount prop_exists files "${PKG_PREFIX}/etc/conffile2" preexist; then
+ : "success"
+ else
+ describe="$describe: property missing!"
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="remove after copy with preexisting"
+ task_createfile etc/conffile2
+ echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files add
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-remove; then
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ ! -f "${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file missing!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ return 0
+}
+
+test12()
+{
+ describe="copy with permissions"
+ task_requires_root || return 0
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2 \
+ 0400 root wheel" | task_files add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2 \
+ 0400 root wheel" | task_files check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2 \
+ 0400 root wheel" | task_files check-perms; then
+ : "success"
+ else
+ describe="$describe: check-perms"
+ return 1
+ fi
+ if [ ! -f "${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file missing!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+}
+
+test13()
+{
+ describe="missing example file with PKG_DESTDIR"
+ test_destdir_setup
+ if echo "# FILE: \
+ etc/conffile1 c \
+ share/examples/pkg1/conffile1" | task_files add; then
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile1 c \
+ share/examples/pkg1/conffile1" | task_files check-add; then
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile1" ]; then
+ describe="$describe: copied file exists!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile1"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ return 0
+}
+
+test14()
+{
+ describe="missing target directory with PKG_DESTDIR"
+ test_destdir_setup
+ if echo "# FILE: \
+ nonexistent/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files add; then
+ return 1
+ fi
+ if echo "# FILE: \
+ nonexistent/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-add; then
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/nonexistent/conffile2" ]; then
+ describe="$describe: copied file exists!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/nonexistent/conffile2"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ return 0
+}
+
+test15()
+{
+ describe="copy with PKG_DESTDIR"
+ test_destdir_setup
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ ! -f "${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file missing!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ return 0
+}
+
+test16()
+{
+ describe="skip copy with PKG_DESTDIR"
+ test_destdir_setup
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file exists!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ return 0
+}
+
+test17()
+{
+ describe="copy rc.d script with PKG_DESTDIR"
+ test_destdir_setup
+ if echo "# FILE: \
+ etc/rc.d/conffile2 cr \
+ share/examples/pkg2/conffile2" | task_files add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/rc.d/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-add; then
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/etc/rc.d/conffile2" ]; then
+ describe="$describe: file exists!"
+ return 1
+ fi
+ return 0
+}
+
+test18()
+{
+ describe="remove after copy with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files add
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-remove; then
+ : "success"
+ else
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file exists!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ return 0
+}
+
+test19()
+{
+ : ${CP:=cp}
+
+ describe="remove after skipped but copied with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files add
+ ${CP} ${PKG_DESTDIR}${PKG_PREFIX}/share/examples/pkg2/conffile2 \
+ ${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files check-remove; then
+ : "success"
+ else
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file exists!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ return 0
+}
+
+test20()
+{
+ describe="remove after modification with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files add
+ echo "extra line" >> "${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2"
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-remove; then
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ ! -f "${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file missing!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ return 0
+}
+
+test21()
+{
+ : ${CP:=cp}
+
+ describe="remove after skipped but copied and modification with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files add
+ ${CP} ${PKG_DESTDIR}${PKG_PREFIX}/share/examples/pkg2/conffile2 \
+ ${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2
+ echo "extra line" >> "${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2"
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files remove; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 . \
+ share/examples/pkg2/conffile2" | task_files check-remove; then
+ describe="$describe: check-remove"
+ return 1
+ fi
+ if [ ! -f "${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file missing!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ return 0
+}
+
+test22()
+{
+ describe="copy with preexisting with PKG_DESTDIR"
+ test_destdir_setup
+ task_createfile "${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2"
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files add; then
+ : "success"
+ else
+ return 1
+ fi
+ if echo "# FILE: \
+ etc/conffile2 c \
+ share/examples/pkg2/conffile2" | task_files check-add; then
+ : "success"
+ else
+ describe="$describe: check-add"
+ return 1
+ fi
+ if [ ! -f "${PKG_DESTDIR}${PKG_PREFIX}/etc/conffile2" ]; then
+ describe="$describe: file missing!"
+ return 1
+ fi
+ if task_refcount exists files "${PKG_PREFIX}/etc/conffile2"; then
+ : "success"
+ else
+ describe="$describe: refcount missing!"
+ return 1
+ fi
+ if task_refcount prop_exists files "${PKG_PREFIX}/etc/conffile2" preexist; then
+ : "success"
+ else
+ describe="$describe: property missing!"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_fonts.sh b/pkgtools/pkgtasks/files/t/t_fonts.sh
new file mode 100644
index 00000000000..401ef397614
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_fonts.sh
@@ -0,0 +1,347 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load fonts
+task_load unittest
+
+test_setup()
+{
+ PKG_PREFIX="${TEST_CURDIR}"
+ PKG_DESTDIR=
+
+ fontdir_ttf="share/fonts/ttf"
+ fontdir_type1="share/fonts/type1"
+ fontdir_x11="share/fonts/x11"
+
+ # Prevent current directory from being auto-removed because it's empty.
+ task_createfile non-empty
+
+ MKFONTDIR="mock_mkfontdir"
+ MKFONTSCALE="mock_mkfontscale"
+ TTMKFDIR="mock_ttmkfdir"
+ TYPE1INST="mock_type1inst"
+}
+
+test_destdir_setup()
+{
+ : ${MKDIR:=mkdir}
+ : ${MV:=mv}
+
+ PKG_DESTDIR="${TEST_CURDIR}/destdir"
+ ${MKDIR} -p "${PKG_DESTDIR}${PKG_DESTDIR}"
+ ${MV} non-empty "${PKG_DESTDIR}${PKG_DESTDIR}"
+}
+
+# Mock font index generator utilities.
+mock_mkfontdir()
+{
+ task_createfile encodings.dir
+}
+
+mock_mkfontscale()
+{
+ task_createfile fonts.scale
+}
+
+mock_ttmkfdir()
+{
+ task_createfile fonts.dir
+ task_createfile fonts.scale
+}
+
+mock_type1inst()
+{
+ task_createfile type1inst.log
+ task_createfile Fontmap.1
+ task_createfile Fontmap.2
+ task_createfile Fontmap.3
+}
+
+test1()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="empty ttf fonts dir"
+ ${MKDIR} -p "$fontdir_ttf"
+ echo "# FONTS: $fontdir_ttf ttf" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$fontdir_ttf" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_ttf exists!"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="non-empty ttf fonts dir"
+ ${MKDIR} -p "$fontdir_ttf"
+ task_createfile "${PKG_PREFIX}/$fontdir_ttf/font1"
+ echo "# FONTS: $fontdir_ttf ttf" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -d "${PKG_PREFIX}/$fontdir_ttf" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_ttf missing!"
+ return 1
+ fi
+ if [ ! -f "${PKG_PREFIX}/$fontdir_ttf/encodings.dir" ]; then
+ describe="$describe: x11 encodings missing!"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="empty type1 fonts dir"
+ ${MKDIR} -p "$fontdir_type1"
+ echo "# FONTS: $fontdir_type1 type1" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$fontdir_type1" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_type1 exists!"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="non-empty type1 fonts dir"
+ ${MKDIR} -p "$fontdir_type1"
+ task_createfile "${PKG_PREFIX}/$fontdir_type1/font1"
+ echo "# FONTS: $fontdir_type1 type1" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -d "${PKG_PREFIX}/$fontdir_type1" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_type1 missing!"
+ return 1
+ fi
+ if [ ! -f "${PKG_PREFIX}/$fontdir_type1/encodings.dir" ]; then
+ describe="$describe: x11 encodings missing!"
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="empty x11 fonts dir"
+ ${MKDIR} -p "$fontdir_x11"
+ echo "# FONTS: $fontdir_x11 x11" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$fontdir_x11" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_x11 exists!"
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="non-empty x11 fonts dir"
+ ${MKDIR} -p "$fontdir_x11"
+ task_createfile "${PKG_PREFIX}/$fontdir_x11/font1"
+ echo "# FONTS: $fontdir_x11 x11" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -d "${PKG_PREFIX}/$fontdir_x11" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_x11 missing!"
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="empty ttf fonts dir with PKG_DESTDIR"
+ test_destdir_setup
+ local fontdir="${PKG_DESTDIR}${PKG_PREFIX}/$fontdir_ttf"
+ ${MKDIR} -p "$fontdir"
+ echo "# FONTS: $fontdir_ttf ttf" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -d "$fontdir" ]; then
+ describe="$describe: $fontdir exists!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$fontdir_ttf" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_ttf exists!"
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="non-empty ttf fonts dir with PKG_DESTDIR"
+ test_destdir_setup
+ local fontdir="${PKG_DESTDIR}${PKG_PREFIX}/$fontdir_ttf"
+ ${MKDIR} -p "$fontdir"
+ task_createfile "$fontdir/font1"
+ echo "# FONTS: $fontdir_ttf ttf" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -d "$fontdir" ]; then
+ describe="$describe: $fontdir missing!"
+ return 1
+ fi
+ if [ ! -f "$fontdir/encodings.dir" ]; then
+ describe="$describe: x11 encodings missing!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$fontdir_ttf" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_ttf exists!"
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="empty type1 fonts dir with PKG_DESTDIR"
+ test_destdir_setup
+ local fontdir="${PKG_DESTDIR}${PKG_PREFIX}/$fontdir_type1"
+ ${MKDIR} -p "$fontdir"
+ echo "# FONTS: $fontdir_type1 type1" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -d "$fontdir" ]; then
+ describe="$describe: $fontdir exists!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$fontdir_type1" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_type1 exists!"
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="non-empty type1 fonts dir with PKG_DESTDIR"
+ test_destdir_setup
+ local fontdir="${PKG_DESTDIR}${PKG_PREFIX}/$fontdir_type1"
+ ${MKDIR} -p "$fontdir"
+ task_createfile "$fontdir/font1"
+ echo "# FONTS: $fontdir_type1 type1" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -d "$fontdir" ]; then
+ describe="$describe: $fontdir missing!"
+ return 1
+ fi
+ if [ ! -f "$fontdir/encodings.dir" ]; then
+ describe="$describe: x11 encodings missing!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$fontdir_type1" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_type1 exists!"
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="empty x11 fonts dir with PKG_DESTDIR"
+ test_destdir_setup
+ local fontdir="${PKG_DESTDIR}${PKG_PREFIX}/$fontdir_x11"
+ ${MKDIR} -p "$fontdir"
+ echo "# FONTS: $fontdir_x11 x11" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -d "$fontdir" ]; then
+ describe="$describe: $fontdir exists!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$fontdir_x11" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_x11 exists!"
+ return 1
+ fi
+ return 0
+}
+
+test12()
+{
+ : ${MKDIR:=mkdir}
+
+ describe="non-empty x11 fonts dir with PKG_DESTDIR"
+ test_destdir_setup
+ local fontdir="${PKG_DESTDIR}${PKG_PREFIX}/$fontdir_x11"
+ ${MKDIR} -p "$fontdir"
+ task_createfile "$fontdir/font1"
+ echo "# FONTS: $fontdir_x11 x11" | task_fonts add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -d "$fontdir" ]; then
+ describe="$describe: $fontdir missing!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$fontdir_x11" ]; then
+ describe="$describe: ${PKG_PREFIX}/$fontdir_x11 exists!"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_groups.sh b/pkgtools/pkgtasks/files/t/t_groups.sh
new file mode 100644
index 00000000000..79020b030aa
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_groups.sh
@@ -0,0 +1,193 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load groups
+task_load unittest
+task_load usergroup_mock
+
+# Mock platform_groupadd() needed by usergroup.subr, and task_group_exists()
+# needed by groups.subr.
+#
+platform_groupadd()
+{
+ mock_groupadd "$@"
+}
+
+task_group_exists()
+{
+ mock_group_exists "$@"
+}
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${MKDIR:=mkdir}
+
+ PKG_DBDIR="${TEST_CURDIR}/var/db/pkg"
+ PKG_REFCOUNT_DBDIR="${PKG_DBDIR}.refcount"
+ ${MKDIR} -p "${PKG_DBDIR}"
+
+ ETC_GROUP="${TEST_CURDIR}/etc.group"
+ mock_usergroup_setup
+
+ datafile="datafile"
+ ${CAT} > $datafile << EOF
+# GROUP: groupG
+# GROUP: groupH:300
+# GROUP: groupI:305
+EOF
+}
+
+test1()
+{
+ describe="check-add missing groups"
+ if task_groups check-add < $datafile; then
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="add nonexistent groups"
+ if task_groups add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ local name
+ for name in groupG groupH groupI; do
+ if task_group_exists "$name"; then
+ : "success"
+ else
+ describe="$describe: missing $name!"
+ return 1
+ fi
+ done
+ return 0
+}
+
+test3()
+{
+ describe="add existent and nonexistent groups"
+ task_addgroup groupH 300
+ if task_groups add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ local name
+ for name in groupG groupH groupI; do
+ if task_group_exists "$name"; then
+ : "success"
+ else
+ describe="$describe: missing $name!"
+ return 1
+ fi
+ done
+ return 0
+}
+
+test4()
+{
+ describe="add conflicting group"
+ task_addgroup groupH 3000
+ if task_groups add < $datafile; then
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="check-add groups with all groups added"
+ task_groups add < $datafile
+ if task_groups check-add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="check-remove groups with no groups removed"
+ task_groups add < $datafile
+ if task_groups check-remove < $datafile; then
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="remove existent groups"
+ task_groups add < $datafile
+ # This always returns 0 because no groups are ever removed.
+ if task_groups remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ local name
+ for name in groupG groupH groupI; do
+ # No groups should have been removed.
+ if task_group_exists "$name"; then
+ : "success"
+ else
+ describe="$describe: $name remains!"
+ return 1
+ fi
+ done
+ return 0
+}
+
+test8()
+{
+ describe="remove nonexistent groups"
+ # This always returns 0 because no groups are ever removed.
+ if task_groups remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="check-remove groups with groups already removed"
+ if task_groups check-remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_info_files.sh b/pkgtools/pkgtasks/files/t/t_info_files.sh
new file mode 100644
index 00000000000..254a301c337
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_info_files.sh
@@ -0,0 +1,411 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load info_files
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${GREP:=grep}
+ : ${MKDIR:=mkdir}
+
+ PKG_PREFIX=${TEST_CURDIR}
+ PKG_DESTDIR=
+
+ infodir="info"
+ testinfo="$infodir/test.info"
+ dirfile="$infodir/dir"
+
+ ${MKDIR} "$infodir"
+ ${CAT} > "$testinfo" << 'EOF'
+INFO-DIR-SECTION Test section
+START-INFO-DIR-ENTRY
+* t_info-files: (test). Test info-files.sh.
+END-INFO-DIR-ENTRY
+EOF
+}
+
+test_destdir_setup()
+
+{
+ : ${MKDIR:=mkdir}
+ : ${MV:=mv}
+
+ PKG_DESTDIR="${TEST_CURDIR}/destdir"
+ ${MKDIR} -p "${PKG_DESTDIR}${PKG_PREFIX}"
+ ${MV} info "${PKG_DESTDIR}${PKG_PREFIX}"
+}
+
+test1()
+{
+ describe="missing dir file on remove"
+ echo "# INFO: $testinfo $infodir" | task_info_files remove
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="missing dir file on add"
+ echo "# INFO: $testinfo $infodir" | task_info_files add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -f "${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_PREFIX}/$dirfile missing!"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="empty dir file on remove"
+ task_createfile "$dirfile"
+ echo "# INFO: $testinfo $infodir" | task_info_files remove
+ if [ $? -eq 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="empty dir file on add"
+ task_createfile "$dirfile"
+ echo "# INFO: $testinfo $infodir" | task_info_files add
+ if [ $? -eq 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="invalid dir file on remove"
+ echo "asdf" > $dirfile
+ echo "# INFO: $testinfo $infodir" | task_info_files remove
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="invalid dir file on add"
+ echo "asdf" > $dirfile
+ echo "# INFO: $testinfo $infodir" | task_info_files add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="remove nonexistent info file from missing dir file"
+ echo "# INFO: /nonexistent.info $infodir" | task_info_files remove
+ if [ $? -eq 0 ]; then
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="add info file to missing dir file"
+ echo "# INFO: $testinfo $infodir" | task_info_files add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -f "${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: no dir!"
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="remove info file after successful add"
+ echo "# INFO: $testinfo $infodir" | task_info_files add
+ echo "# INFO: $testinfo $infodir" | task_info_files remove
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="add info file more than once"
+ task_info_files add << EOF
+# INFO: $testinfo $infodir
+# INFO: $testinfo $infodir
+# INFO: $testinfo $infodir
+# INFO: $testinfo $infodir
+EOF
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ local count
+ count=$( ${GREP} -c '^\* t_info-files:' "$dirfile" )
+ if [ $count -gt 1 ]; then
+ describe="$describe: $count"
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="missing dir file on remove with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# INFO: $testinfo $infodir" | task_info_files remove
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_DESTDIR}${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$infodir" ]; then
+ describe="$describe: ${PKG_PREFIX}/$infodir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test12()
+{
+ describe="missing dir file on add with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# INFO: $testinfo $infodir" | task_info_files add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -f "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_DESTDIR}${PKG_PREFIX}/$dirfile missing!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$infodir" ]; then
+ describe="$describe: ${PKG_PREFIX}/$infodir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test13()
+{
+ describe="empty dir file on remove with PKG_DESTDIR"
+ test_destdir_setup
+ task_createfile "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile"
+ echo "# INFO: $testinfo $infodir" | task_info_files remove
+ if [ $? -eq 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_DESTDIR}${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$infodir" ]; then
+ describe="$describe: ${PKG_PREFIX}/$infodir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test14()
+{
+ describe="empty dir file on add with PKG_DESTDIR"
+ test_destdir_setup
+ task_createfile "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile"
+ echo "# INFO: $testinfo $infodir" | task_info_files add
+ if [ $? -eq 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_DESTDIR}${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$infodir" ]; then
+ describe="$describe: ${PKG_PREFIX}/$infodir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test15()
+{
+ describe="invalid dir file on remove with PKG_DESTDIR"
+ test_destdir_setup
+ echo "asdf" > "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile"
+ echo "# INFO: $testinfo $infodir" | task_info_files remove
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_DESTDIR}${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$infodir" ]; then
+ describe="$describe: ${PKG_PREFIX}/$infodir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test16()
+{
+ describe="invalid dir file on add with PKG_DESTDIR"
+ test_destdir_setup
+ echo "asdf" > "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile"
+ echo "# INFO: $testinfo $infodir" | task_info_files add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_DESTDIR}${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$infodir" ]; then
+ describe="$describe: ${PKG_PREFIX}/$infodir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test17()
+{
+ describe="remove nonexistent info file from missing dir file with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# INFO: /nonexistent.info $infodir" | task_info_files remove
+ if [ $? -eq 0 ]; then
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$infodir" ]; then
+ describe="$describe: ${PKG_PREFIX}/$infodir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test18()
+{
+ describe="add info file to missing dir file with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# INFO: $testinfo $infodir" | task_info_files add
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -f "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: no dir!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$infodir" ]; then
+ describe="$describe: ${PKG_PREFIX}/$infodir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test19()
+{
+ describe="remove info file after successful add with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# INFO: $testinfo $infodir" | task_info_files add
+ echo "# INFO: $testinfo $infodir" | task_info_files remove
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile" ]; then
+ describe="$describe: ${PKG_DESTDIR}${PKG_PREFIX}/$dirfile exists!"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$infodir" ]; then
+ describe="$describe: ${PKG_PREFIX}/$infodir exists!"
+ return 1
+ fi
+ return 0
+}
+
+test20()
+{
+ describe="add info file more than once with PKG_DESTDIR"
+ test_destdir_setup
+ task_info_files add << EOF
+# INFO: $testinfo $infodir
+# INFO: $testinfo $infodir
+# INFO: $testinfo $infodir
+# INFO: $testinfo $infodir
+EOF
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ local count
+ count=$( ${GREP} -c '^\* t_info-files:' "${PKG_DESTDIR}${PKG_PREFIX}/$dirfile" )
+ if [ $count -gt 1 ]; then
+ describe="$describe: $count"
+ return 1
+ fi
+ if [ -d "${PKG_PREFIX}/$infodir" ]; then
+ describe="$describe: ${PKG_PREFIX}/$infodir exists!"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_lock.sh b/pkgtools/pkgtasks/files/t/t_lock.sh
new file mode 100644
index 00000000000..a1cc9d2bb2c
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_lock.sh
@@ -0,0 +1,120 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load lock
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${CMP:=cmp}
+ : ${SLEEP:=sleep}
+
+ lockfile="lock"
+}
+
+test1()
+{
+ describe="create lock"
+ if task_lock "$lockfile"; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ ! -f "$lockfile" ]; then
+ describe="$describe: $lockfile missing!"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="create nonblocking lock, pre-existing lock file"
+ task_createfile "$lockfile"
+ if task_lock -n "$lockfile"; then
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="release lock"
+ task_lock "$lockfile"
+ if task_lock -r "$lockfile"; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "$lockfile" ]; then
+ describe="$describe: $lockfile exists!"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="create lock, competing processes"
+ local timeout=3
+ # Create a child process that writes to "value".
+ ( if task_lock "$lockfile"; then
+ echo "child" >> value
+ ${SLEEP} $timeout
+ task_lock -r "$lockfile"
+ fi ) &
+ #
+ # Wait for up to $timeout seconds for the child to write to the
+ # datefile.
+ #
+ while [ $timeout -gt 0 ]; do
+ [ ! -f value ] || break
+ ${SLEEP} 1
+ timeout=$(( $timeout - 1 ))
+ done
+ # Block waiting for background process to unlock.
+ if task_lock "$lockfile"; then
+ echo "parent" >> value
+ task_lock -r "$lockfile"
+ fi
+ # Check that the writes were serialized: child, then parent.
+ ${CAT} > expected << 'EOF'
+child
+parent
+EOF
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ describe="$describe: child after parent!"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_makedir.sh b/pkgtools/pkgtasks/files/t/t_makedir.sh
new file mode 100644
index 00000000000..3a02eecd19c
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_makedir.sh
@@ -0,0 +1,70 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load makedir
+task_load permissions
+task_load unittest
+
+test1()
+{
+ describe="makedir a/b/c"
+ task_makedir a/b/c
+ if [ ! -d "a/b/c" ]; then
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="makedir -i a/b/c"
+ task_makedir -in a/b/c
+ task_makedir -i a/b/c
+ if [ ! -d "a/b/c" ]; then
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="makedir -i -m 700 a/b/c"
+ task_makedir -in -m 700 a/b/c
+ task_makedir -i -m 700 a/b/c
+ if [ ! -d "a/b/c" ]; then
+ return 1
+ fi
+ if task_check_permissions a/b/c 700; then
+ : "success"
+ else
+ describe="$describe: wrong mode!"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_maketemp.sh b/pkgtools/pkgtasks/files/t/t_maketemp.sh
new file mode 100644
index 00000000000..c7b622569de
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_maketemp.sh
@@ -0,0 +1,215 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load maketemp
+task_load unittest
+
+# Mock a broken utility.
+broken()
+{
+ return 1
+}
+
+test_setup()
+{
+ : ${MKDIR:=mkdir}
+
+ # Set MKTEMP to a broken utility to force following the shell code path.
+ MKTEMP=broken
+
+ etcdir="${TEST_CURDIR}/etc"
+ TMPDIR="${TEST_CURDIR}/tmp"
+
+ ${MKDIR} -p "$etcdir"
+ ${MKDIR} -p "${TMPDIR}"
+}
+
+test1()
+{
+ describe="maketemp"
+ local temp
+ temp=$( task_maketemp )
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -f "$temp" ]; then
+ describe="$describe: $temp missing!"
+ return 1
+ fi
+ local temp_dirname="${temp%/*}"
+ if [ "$temp_dirname" != "${TMPDIR}" ]; then
+ describe="$describe: $temp_dirname is wrong parent!"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="maketemp -p $etcdir"
+ local temp
+ temp=$( task_maketemp -p "$etcdir" )
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -f "$temp" ]; then
+ describe="$describe: $temp missing!"
+ return 1
+ fi
+ local temp_dirname="${temp%/*}"
+ if [ "$temp_dirname" != "$etcdir" ]; then
+ describe="$describe: $temp_dirname is wrong parent!"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="maketemp -t foobar"
+ local temp
+ temp=$( task_maketemp -t foobar )
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -f "$temp" ]; then
+ describe="$describe: $temp missing!"
+ return 1
+ fi
+ case $temp in
+ ${TMPDIR}/foobar.*)
+ : "success" ;;
+ *) describe="$describe: $temp doesn't match template!"
+ return 1 ;;
+ esac
+ return 0
+}
+
+test4()
+{
+ describe="maketemp $etcdir/group.XXX"
+ local temp
+ temp=$( task_maketemp "$etcdir/group.XXX" )
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -f "$temp" ]; then
+ describe="$describe: $temp missing!"
+ return 1
+ fi
+ case $temp in
+ $etcdir/group.???)
+ : "success" ;;
+ *) describe="$describe: $temp doesn't match template!"
+ return 1 ;;
+ esac
+ return 0
+}
+
+test5()
+{
+ describe="maketemp -d"
+ local temp
+ temp=$( task_maketemp -d )
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -d "$temp" ]; then
+ describe="$describe: $temp missing!"
+ return 1
+ fi
+ local temp_dirname="${temp%/*}"
+ if [ "$temp_dirname" != "${TMPDIR}" ]; then
+ describe="$describe: $temp_dirname is the wrong parent!"
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="maketemp -d -p $etcdir"
+ local temp
+ temp=$( task_maketemp -d -p "$etcdir" )
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -d "$temp" ]; then
+ describe="$describe: $temp missing!"
+ return 1
+ fi
+ local temp_dirname="${temp%/*}"
+ if [ "$temp_dirname" != "$etcdir" ]; then
+ describe="$describe: $temp_dirname is the wrong prefix!"
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="maketemp -d -t foobar"
+ local temp
+ temp=$( task_maketemp -d -t foobar )
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -d "$temp" ]; then
+ describe="$describe: $temp missing!"
+ return 1
+ fi
+ case $temp in
+ ${TMPDIR}/foobar.*)
+ : "success" ;;
+ *) describe="$describe: $temp doesn't match template!"
+ return 1 ;;
+ esac
+ return 0
+}
+
+test8()
+{
+ describe="maketemp -d $etcdir/group.XXX"
+ local temp
+ temp=$( task_maketemp -d "$etcdir/group.XXX" )
+ if [ $? -gt 0 ]; then
+ return 1
+ fi
+ if [ ! -d "$temp" ]; then
+ describe="$describe: $temp missing!"
+ return 1
+ fi
+ case $temp in
+ $etcdir/group.???)
+ : "success" ;;
+ *) describe="$describe: $temp doesn't match template!"
+ return 1 ;;
+ esac
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_match.sh b/pkgtools/pkgtasks/files/t/t_match.sh
new file mode 100644
index 00000000000..ee9400d3f59
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_match.sh
@@ -0,0 +1,175 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load match
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+
+ data="data"
+ newline="
+"
+
+ ${CAT} > $data << EOF
+aaa
+bbb ccc
+bbbccc
+
+ddd aaa
+
+aaa eee
+* Menu:
+EOF
+}
+
+test1()
+{
+ describe="exact plain match one line"
+ local expected value
+ expected="bbb ccc"
+ value=$( task_match "bbb ccc" < $data )
+ if [ "$value" != "$expected" ]; then
+ task_match "bbb ccc" < $data
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="word plain match one line"
+ local expected value
+ expected="bbb ccc"
+ value=$( task_match -w bbb < $data )
+ if [ "$value" != "$expected" ]; then
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="word plain match multiple lines"
+ local expected value
+ value=$( task_match -w aaa < $data )
+ expected="aaa${newline}aaa eee"
+ if [ "$value" != "$expected" ]; then
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="word reverse match one line"
+ local expected value
+ value=$( task_match -vw bbb < $data )
+ expected="aaa${newline}bbbccc${newline}${newline}ddd aaa${newline}${newline}aaa eee${newline}* Menu:"
+ if [ "$value" != "$expected" ]; then
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="word reverse match multiple lines"
+ local expected value
+ value=$( task_match -vw aaa < $data )
+ expected="bbb ccc${newline}bbbccc${newline}${newline}ddd aaa${newline}${newline}* Menu:"
+ if [ "$value" != "$expected" ]; then
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="exact plain match no lines"
+ local value
+ value=$( task_match ccc < $data )
+ if [ -n "$value" ]; then
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="word plain match silent"
+ if task_match -qw aaa < $data; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="word reverse match silent"
+ if task_match -qvw aaa < $data; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="exact plain match no lines silent"
+ if task_match -q ccc < $data; then
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="exact reverse match no lines silent"
+ if task_match -qv ccc < $data; then
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="plain glob match one line"
+ local expected value
+ value=$( task_match "[*][ ][mM]enu:*" < $data )
+ expected="* Menu:"
+ if [ "$value" != "$expected" ]; then
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_ocaml_findlib.sh b/pkgtools/pkgtasks/files/t/t_ocaml_findlib.sh
new file mode 100644
index 00000000000..c6b40e61840
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_ocaml_findlib.sh
@@ -0,0 +1,346 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load ocaml_findlib
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+
+ PKG_PREFIX=${TEST_CURDIR}
+ PKG_DESTDIR=
+
+ ldconf="ld.conf"
+ ldconf_lock="$ldconf.lock"
+
+ datafile="datafile"
+ ${CAT} > $datafile << EOF
+# FINDLIB: pcre $ldconf
+# FINDLIB: base64 $ldconf
+# FINDLIB: expat $ldconf
+# FINDLIB: pcre $ldconf
+EOF
+}
+
+test_destdir_setup()
+{
+ : ${MKDIR:=mkdir}
+ : ${MV:=mv}
+
+ PKG_DESTDIR="${TEST_CURDIR}/destdir"
+ ${MKDIR} -p "${PKG_DESTDIR}${PKG_PREFIX}"
+}
+
+test1()
+{
+ describe="check-add findlib dirs with empty ld.conf"
+ if task_ocaml_findlib check-add < $datafile; then
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="add findlib dirs"
+ if task_ocaml_findlib add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ ! -f "$ldconf" ]; then
+ describe="$describe: $ldconf missing!"
+ return 1
+ fi
+ if [ -f "$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="verify uniqueness"
+ task_ocaml_findlib add < $datafile
+ local count=0
+ local line
+ while read line; do
+ case $line in
+ */pcre) count="$count + 1" ;;
+ esac
+ done < $ldconf
+ count=$(( $count ))
+ if [ $count -gt 1 ]; then
+ describe="$describe: too many pcre!"
+ return 1
+ fi
+ if [ -f "$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="check-add findlib dirs with all dirs added"
+ task_ocaml_findlib add < $datafile
+ if task_ocaml_findlib check-add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="check-remove findlib dirs with no dirs removed"
+ task_ocaml_findlib add < $datafile
+ if task_ocaml_findlib check-remove < $datafile; then
+ return 1
+ fi
+ if [ -f "$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="remove findlib dirs"
+ task_ocaml_findlib add < $datafile
+ if task_ocaml_findlib remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="verify empty ld.conf"
+ task_ocaml_findlib add < $datafile
+ task_ocaml_findlib remove < $datafile
+ local count=0
+ local line
+ while read line; do
+ count="$count + 1"
+ done < $ldconf
+ count=$(( $count ))
+ if [ $count -gt 0 ]; then
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="check-remove findlib dirs with empty ld.conf"
+ task_createfile "$ldconf"
+ if task_ocaml_findlib check-remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="add findlib dirs with PKG_DESTDIR"
+ test_destdir_setup
+ if task_ocaml_findlib add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ ! -f "${PKG_DESTDIR}${PKG_PREFIX}/$ldconf" ]; then
+ describe="$describe: ${PKG_DESTDIR}${PKG_PREFIX}/$ldconf missing!"
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$ldconf" ]; then
+ describe="$describe: $ldconf exists!"
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="verify uniqueness with PKG_DESTDIR"
+ test_destdir_setup
+ task_ocaml_findlib add < $datafile
+ local count=0
+ local line
+ while read line; do
+ case $line in
+ */pcre) count="$count + 1" ;;
+ esac
+ done < ${PKG_DESTDIR}${PKG_PREFIX}/$ldconf
+ count=$(( $count ))
+ if [ $count -gt 1 ]; then
+ describe="$describe: too many pcre!"
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$ldconf" ]; then
+ describe="$describe: $ldconf exists!"
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="check-add findlib dirs with all dirs added with PKG_DESTDIR"
+ test_destdir_setup
+ task_ocaml_findlib add < $datafile
+ if task_ocaml_findlib check-add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$ldconf" ]; then
+ describe="$describe: $ldconf exists!"
+ return 1
+ fi
+ return 0
+}
+
+test12()
+{
+ describe="check-remove findlib dirs with no dirs removed with PKG_DESTDIR"
+ test_destdir_setup
+ task_ocaml_findlib add < $datafile
+ if task_ocaml_findlib check-remove < $datafile; then
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$ldconf" ]; then
+ describe="$describe: $ldconf exists!"
+ return 1
+ fi
+ return 0
+}
+
+test13()
+{
+ describe="remove findlib dirs with PKG_DESTDIR"
+ test_destdir_setup
+ task_ocaml_findlib add < $datafile
+ if task_ocaml_findlib remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$ldconf" ]; then
+ describe="$describe: $ldconf exists!"
+ return 1
+ fi
+ return 0
+}
+
+test14()
+{
+ describe="verify empty ld.conf with PKG_DESTDIR"
+ test_destdir_setup
+ task_ocaml_findlib add < $datafile
+ task_ocaml_findlib remove < $datafile
+ local count=0
+ local line
+ while read line; do
+ count="$count + 1"
+ done < ${PKG_DESTDIR}${PKG_PREFIX}/$ldconf
+ count=$(( $count ))
+ if [ $count -gt 0 ]; then
+ return 1
+ fi
+ if [ -f "$ldconf" ]; then
+ describe="$describe: $ldconf exists!"
+ return 1
+ fi
+ return 0
+}
+
+test15()
+{
+ describe="check-remove findlib dirs with empty ld.conf with PKG_DESTDIR"
+ test_destdir_setup
+ task_createfile "${PKG_DESTDIR}${PKG_PREFIX}/$ldconf"
+ if task_ocaml_findlib check-remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$ldconf_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$ldconf" ]; then
+ describe="$describe: $ldconf exists!"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_permissions.sh b/pkgtools/pkgtasks/files/t/t_permissions.sh
new file mode 100644
index 00000000000..d098e2899ea
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_permissions.sh
@@ -0,0 +1,172 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load permissions
+task_load unittest
+
+test_setup()
+{
+ : ${LS:=ls}
+
+ PKG_PREFIX=${TEST_CURDIR}
+ PKG_DESTDIR=
+}
+
+test_destdir_setup()
+{
+ : ${MKDIR:=mkdir}
+ : ${MV:=mv}
+
+ PKG_DESTDIR="${TEST_CURDIR}/destdir"
+ ${MKDIR} -p "${PKG_DESTDIR}${PKG_PREFIX}"
+}
+
+test1()
+{
+ describe="missing file"
+ echo "# PERMS: file1 0444" | task_permissions check-add
+ if echo "# PERMS: file1 0444" | task_permissions add; then
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="change only file mode"
+ task_createfile file1
+ echo "# PERMS: file1 0444" | task_permissions add
+ echo "# PERMS: file1 0444" | task_permissions check-add
+ if task_check_permissions file1 0444; then
+ : "success"
+ else
+ describe="$describe: file1"
+ ${LS} -ln file1 |
+ ( read mode
+ if [ "$mode" != "-r--r--r--" ]; then
+ describe="$describe: wrong mode \`$mode'"
+ return 1
+ fi ) || return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="change to root/wheel"
+ task_requires_root || return 0
+ task_createfile file1
+ echo "# PERMS: file1 0600 root wheel" | task_permissions add
+ echo "# PERMS: file1 0600 root wheel" | task_permissions check-add
+ if task_check_permissions file1 0600 root wheel; then
+ : "success"
+ else
+ describe="$describe: file1"
+ ${LS} -ln file1 |
+ ( read mode x owner group x;
+ if [ "$mode" != "-rw-------" ]; then
+ describe="$describe: wrong mode \`$mode'"
+ return 1
+ fi
+ if [ "$owner" != 0 ]; then
+ describe="$describe: wrong owner \`$owner'"
+ return 1
+ fi
+ if [ "$group" != 0 ]; then
+ describe="$describe: wrong group \`$group'"
+ return 1
+ fi ) || return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="missing file with PKG_DESTDIR"
+ test_destdir_setup
+ echo "# PERMS: file1 0444" | task_permissions check-add
+ if echo "# PERMS: file1 0444" | task_permissions add; then
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="change only file mode with PKG_DESTDIR"
+ test_destdir_setup
+ local file="${PKG_DESTDIR}${PKG_PREFIX}/file1"
+ task_createfile $file
+ echo "# PERMS: file1 0444" | task_permissions add
+ echo "# PERMS: file1 0444" | task_permissions check-add
+ if task_check_permissions "$file" 0444; then
+ : "success"
+ else
+ describe="$describe: $file"
+ ${LS} -ln "$file" |
+ ( read mode
+ if [ "$mode" != "-r--r--r--" ]; then
+ describe="$describe: wrong mode \`$mode'"
+ return 1
+ fi ) || return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="change to root/wheel with PKG_DESTDIR"
+ task_requires_root || return 0
+ test_destdir_setup
+ local file="${PKG_DESTDIR}${PKG_PREFIX}/file1"
+ task_createfile "$file"
+ echo "# PERMS: file1 0600 root wheel" | task_permissions add
+ echo "# PERMS: file1 0600 root wheel" | task_permissions check-add
+ if task_check_permissions "$file" 0600 root wheel; then
+ : "success"
+ else
+ describe="$describe: $file"
+ ${LS} -ln "$file" |
+ ( read mode x owner group x;
+ if [ "$mode" != "-rw-------" ]; then
+ describe="$describe: wrong mode \`$mode'"
+ return 1
+ fi
+ if [ "$owner" != 0 ]; then
+ describe="$describe: wrong owner \`$owner'"
+ return 1
+ fi
+ if [ "$group" != 0 ]; then
+ describe="$describe: wrong group \`$group'"
+ return 1
+ fi ) || return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_platform.sh b/pkgtools/pkgtasks/files/t/t_platform.sh
new file mode 100644
index 00000000000..ae39a4d6175
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_platform.sh
@@ -0,0 +1,68 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load platform
+task_load unittest
+
+# Mock uname() needed by platform.subr.
+mock_uname()
+{
+ echo "N-e-t/B-S-D"
+}
+
+mock_uname_cygwin()
+{
+ echo "CYGWIN"
+}
+
+test1()
+{
+ describe="uname with dashes and slashes"
+ local expected value
+ expected="NetBSD"
+ value=$( UNAME=mock_uname task_platform )
+ if [ "$value" != "$expected" ]; then
+ echo "$value"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="cygwin"
+ local expected value
+ expected="Cygwin"
+ value=$( UNAME=mock_uname_cygwin task_platform )
+ if [ "$value" != "$expected" ]; then
+ echo "$value"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_postinstall.sh b/pkgtools/pkgtasks/files/t/t_postinstall.sh
new file mode 100644
index 00000000000..215b5eb8e58
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_postinstall.sh
@@ -0,0 +1,199 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load postinstall
+task_load unittest
+
+test_setup()
+{
+ datafile="empty"
+ task_createfile "$datafile"
+
+ TASK_DIRECTORIES_SUCCESS="yes"
+ TASK_FILES_SUCCESS="yes"
+ TASK_FONTS_SUCCESS="yes"
+ TASK_FUNCTION_SUCCESS="yes"
+ TASK_INFO_FILES_SUCCESS="yes"
+ TASK_OCAML_FINDLIB_SUCCESS="yes"
+ TASK_PERMISSIONS_SUCCESS="yes"
+ TASK_SHELLS_SUCCESS="yes"
+ TASK_SHLIBS_SUCCESS="yes"
+}
+
+# Mock actions that return the truthiness of environment variables.
+task_directories()
+{
+ [ "${TASK_DIRECTORIES_SUCCESS}" = "yes" ]
+}
+
+task_files()
+{
+ [ "${TASK_FILES_SUCCESS}" = "yes" ]
+}
+
+task_fonts()
+{
+ [ "${TASK_FONTS_SUCCESS}" = "yes" ]
+}
+
+task_function()
+{
+ [ "${TASK_FUNCTION_SUCCESS}" = "yes" ]
+}
+
+task_info_files()
+{
+ [ "${TASK_INFO_FILES_SUCCESS}" = "yes" ]
+}
+
+task_ocaml_findlib()
+{
+ [ "${TASK_OCAML_FINDLIB_SUCCESS}" = "yes" ]
+}
+
+task_permissions()
+{
+ [ "${TASK_PERMISSIONS_SUCCESS}" = "yes" ]
+}
+
+task_shells()
+{
+ [ "${TASK_SHELLS_SUCCESS}" = "yes" ]
+}
+
+task_shlibs()
+{
+ [ "${TASK_SHLIBS_SUCCESS}" = "yes" ]
+}
+
+# Only succeed if all of the actions were successful.
+
+test1()
+{
+ describe="dirs fail"
+ TASK_DIRECTORIES_SUCCESS="no"
+ if task_postinstall "$datafile"; then
+ : "dirs should only be used to check"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="files fail"
+ TASK_FILES_SUCCESS="no"
+ if task_postinstall "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="fonts fail"
+ TASK_FONTS_SUCCESS="no"
+ if task_postinstall "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="function fail"
+ TASK_FUNCTION_SUCCESS="no"
+ if task_postinstall "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="info_files fail"
+ TASK_INFO_FILES_SUCCESS="no"
+ if task_postinstall "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="ocaml_findlib fail"
+ TASK_OCAML_FINDLIB_SUCCESS="no"
+ if task_postinstall "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="permissions fail"
+ TASK_PERMISSIONS_SUCCESS="no"
+ if task_postinstall "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="shells fail"
+ TASK_SHELLS_SUCCESS="no"
+ if task_postinstall "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="shlibs fail"
+ TASK_SHLIBS_SUCCESS="no"
+ if task_postinstall "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="all succeed"
+ if task_postinstall "$datafile"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_postremove.sh b/pkgtools/pkgtasks/files/t/t_postremove.sh
new file mode 100644
index 00000000000..b117e983333
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_postremove.sh
@@ -0,0 +1,217 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load postremove
+task_load unittest
+
+test_setup()
+{
+ datafile="empty"
+ task_createfile "$datafile"
+
+ TASK_DIRECTORIES_SUCCESS="yes"
+ TASK_FILES_SUCCESS="yes"
+ TASK_FONTS_SUCCESS="yes"
+ TASK_FUNCTION_SUCCESS="yes"
+ TASK_GROUPS_SUCCESS="yes"
+ TASK_INFO_FILES_SUCCESS="yes"
+ TASK_OCAML_FINDLIB_SUCCESS="yes"
+ TASK_SHELLS_SUCCESS="yes"
+ TASK_SHLIBS_SUCCESS="yes"
+ TASK_USERS_SUCCESS="yes"
+}
+
+# Mock actions that return the truthiness of environment variables.
+task_directories()
+{
+ [ "${TASK_DIRECTORIES_SUCCESS}" = "yes" ]
+}
+
+task_files()
+{
+ [ "${TASK_FILES_SUCCESS}" = "yes" ]
+}
+
+task_fonts()
+{
+ [ "${TASK_FONTS_SUCCESS}" = "yes" ]
+}
+
+task_function()
+{
+ [ "${TASK_FUNCTION_SUCCESS}" = "yes" ]
+}
+
+task_groups()
+{
+ [ "${TASK_GROUPS_SUCCESS}" = "yes" ]
+}
+
+task_info_files()
+{
+ [ "${TASK_INFO_FILES_SUCCESS}" = "yes" ]
+}
+
+task_ocaml_findlib()
+{
+ [ "${TASK_OCAML_FINDLIB_SUCCESS}" = "yes" ]
+}
+
+task_shells()
+{
+ [ "${TASK_SHELLS_SUCCESS}" = "yes" ]
+}
+
+task_shlibs()
+{
+ [ "${TASK_SHLIBS_SUCCESS}" = "yes" ]
+}
+
+task_users()
+{
+ [ "${TASK_USERS_SUCCESS}" = "yes" ]
+}
+
+# Only succeed if all of the actions were successful.
+
+test1()
+{
+ describe="dirs fail"
+ TASK_DIRECTORIES_SUCCESS="no"
+ if task_postremove "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="files fail"
+ TASK_FILES_SUCCESS="no"
+ if task_postremove "$datafile"; then
+ : "files should only be used to check"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="fonts fail"
+ TASK_FONTS_SUCCESS="no"
+ if task_postremove "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="function fail"
+ TASK_FUNCTION_SUCCESS="no"
+ if task_postremove "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="groups fail"
+ TASK_GROUPS_SUCCESS="no"
+ if task_postremove "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="info_files fail"
+ TASK_INFO_FILES_SUCCESS="no"
+ if task_postremove "$datafile"; then
+ : "info_files should only be used to check"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="ocaml_findlib fail"
+ TASK_OCAML_FINDLIB_SUCCESS="no"
+ if task_postremove "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="shells fail"
+ TASK_SHELLS_SUCCESS="no"
+ if task_postremove "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="shlibs fail"
+ TASK_SHLIBS_SUCCESS="no"
+ if task_postremove "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="users fail"
+ TASK_USERS_SUCCESS="no"
+ if task_postremove "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="all succeed"
+ if task_postremove "$datafile"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_preinstall.sh b/pkgtools/pkgtasks/files/t/t_preinstall.sh
new file mode 100644
index 00000000000..e86a88409b0
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_preinstall.sh
@@ -0,0 +1,117 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load preinstall
+task_load unittest
+
+test_setup()
+{
+ datafile="empty"
+ task_createfile "$datafile"
+
+ TASK_DIRECTORIES_SUCCESS="yes"
+ TASK_FUNCTION_SUCCESS="yes"
+ TASK_GROUPS_SUCCESS="yes"
+ TASK_USERS_SUCCESS="yes"
+}
+
+# Mock actions that return the truthiness of environment variables.
+task_directories()
+{
+ [ "${TASK_DIRECTORIES_SUCCESS}" = "yes" ]
+}
+
+task_function()
+{
+ [ "${TASK_FUNCTION_SUCCESS}" = "yes" ]
+}
+
+task_groups()
+{
+ [ "${TASK_GROUPS_SUCCESS}" = "yes" ]
+}
+
+task_users()
+{
+ [ "${TASK_USERS_SUCCESS}" = "yes" ]
+}
+
+test1()
+{
+ describe="dirs fail"
+ TASK_DIRECTORIES_SUCCESS="no"
+ if task_preinstall "$datafile"; then
+ : "dirs errors in preinstall are non-fatal"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="function fail"
+ TASK_FUNCTION_SUCCESS="no"
+ if task_preinstall "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="groups fail"
+ TASK_GROUPS_SUCCESS="no"
+ if task_preinstall "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="users fail"
+ TASK_USERS_SUCCESS="no"
+ if task_preinstall "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="all succeed"
+ if task_preinstall "$datafile"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_preremove.sh b/pkgtools/pkgtasks/files/t/t_preremove.sh
new file mode 100644
index 00000000000..301b40f01b7
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_preremove.sh
@@ -0,0 +1,105 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load preremove
+task_load unittest
+
+test_setup()
+{
+ datafile="empty"
+ task_createfile "$datafile"
+
+ TASK_FILES_SUCCESS="yes"
+ TASK_FUNCTION_SUCCESS="yes"
+ TASK_INFO_FILES_SUCCESS="yes"
+}
+
+# Mock actions whose return values are ignored.
+task_files()
+{
+ [ "${TASK_FILES_SUCCESS}" = "yes" ]
+}
+
+task_function()
+{
+ [ "${TASK_FUNCTION_SUCCESS}" = "yes" ]
+}
+
+task_info_files()
+{
+ [ "${TASK_INFO_FILES_SUCCESS}" = "yes" ]
+}
+
+# Always succeed.
+
+test1()
+{
+ describe="files fail"
+ TASK_FILES_SUCCESS="no"
+ if task_preremove "$datafile"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="function fail"
+ TASK_FUNCTION_SUCCESS="no"
+ if task_preremove "$datafile"; then
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="info_files fail"
+ TASK_INFO_FILES_SUCCESS="no"
+ if task_preremove "$datafile"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="all succeed"
+ if task_preremove "$datafile"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_quote.sh b/pkgtools/pkgtasks/files/t/t_quote.sh
new file mode 100644
index 00000000000..b06c2a485b8
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_quote.sh
@@ -0,0 +1,118 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load quote
+task_load unittest
+
+test_setup()
+{
+ # Create files in the test directory to catch wildcard expansion.
+ task_createfile a b c
+}
+
+test1()
+{
+ describe="6 words"
+ local quoted
+ task_quote "1 *" "2 *" "3 *"
+ set -- $quoted
+ if [ $# -eq 6 ]; then
+ : "success"
+ else
+ return 1
+ fi
+}
+
+test2()
+{
+ describe="1 word"
+ local quoted
+ task_quote "1 *" "2 *" "3 *"
+ set -- "$quoted"
+ if [ $# -eq 1 ]; then
+ : "success"
+ else
+ return 1
+ fi
+}
+
+test3()
+{
+ describe="3 words (correct quoting)"
+ local quoted
+ task_quote "1 *" "2 *" "3 *"
+ eval set -- $quoted
+ if [ $# -eq 3 ]; then
+ : "success"
+ else
+ return 1
+ fi
+}
+
+test4()
+{
+ describe="3 words, extraneous quotes (correct quoting)"
+ local quoted
+ task_quote "1 *" "2 *" "3 *"
+ eval set -- "$quoted"
+ if [ $# -eq 3 ]; then
+ : "success"
+ else
+ return 1
+ fi
+}
+
+test5()
+{
+ describe="1 word (correct quoting)"
+ local quoted
+ task_quote "*"
+ eval set -- $quoted
+ local arg; for arg; do echo "$arg"; done
+ if [ $# -eq 1 ]; then
+ : "success"
+ else
+ return 1
+ fi
+}
+
+test6()
+{
+ describe="1 word, extraneous quotes (correct quoting)"
+ local quoted
+ task_quote "*"
+ eval set -- "$quoted"
+ local arg; for arg; do echo "$arg"; done
+ if [ $# -eq 1 ]; then
+ : "success"
+ else
+ return 1
+ fi
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_random.sh b/pkgtools/pkgtasks/files/t/t_random.sh
new file mode 100644
index 00000000000..375b2cb8f4d
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_random.sh
@@ -0,0 +1,61 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load random
+task_load unittest
+
+test1()
+{
+ describe="each \$RANDOM is different"
+ local rand1 rand2 rand3
+ task_random && rand1=$RANDOM
+ task_random && rand2=$RANDOM
+ task_random && rand3=$RANDOM
+ [ "$rand1" != "$rand2" ] &&
+ [ "$rand1" != "$rand3" ] &&
+ [ "$rand2" != "$rand3" ]
+}
+
+test2()
+{
+ describe="task_random -i yields reproducible \$RANDOM"
+ local first1 first2 first3
+ task_random -i "12345"
+ task_random && rand1=$RANDOM
+ task_random && rand2=$RANDOM
+ task_random && rand3=$RANDOM
+ local second1 second2 second3
+ task_random -i "12345"
+ task_random && rand1=$RANDOM
+ task_random && rand2=$RANDOM
+ task_random && rand3=$RANDOM
+ [ "$first1" = "$second1" ] &&
+ [ "$first2" = "$second2" ] &&
+ [ "$first3" = "$second3" ]
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_refcount.sh b/pkgtools/pkgtasks/files/t/t_refcount.sh
new file mode 100644
index 00000000000..95ccb58c7df
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_refcount.sh
@@ -0,0 +1,397 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load refcount
+task_load unittest
+
+test_setup()
+{
+ PKG_REFCOUNT_DBDIR="${TEST_CURDIR}/refcount"
+ PKG_DESTDIR=
+
+ nonexistent="${TEST_CURDIR}/nonexistent"
+}
+
+test_destdir_setup()
+{
+ : ${MKDIR:=mkdir}
+ : ${MV:=mv}
+
+ PKG_DESTDIR="${TEST_CURDIR}/destdir"
+ ${MKDIR} -p "${PKG_DESTDIR}${TEST_CURDIR}"
+}
+
+test1()
+{
+ describe="add nonexistent file"
+ if task_refcount add refs "$nonexistent"; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount exists refs "$nonexistent"; then
+ : "success"
+ else
+ describe="$describe: reference missing!"
+ return 1
+ fi
+ if task_refcount prop_exists refs "$nonexistent" permissions; then
+ describe="$describe: permissions found!"
+ return 1
+ fi
+ if task_refcount prop_exists refs "$nonexistent" preexist; then
+ describe="$describe: preexist found!"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="put permissions"
+ local permissions="0400 root wheel"
+ task_refcount add refs "$nonexistent"
+ if task_refcount prop_put refs "$nonexistent" permissions $permissions; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount prop_match refs "$nonexistent" permissions $permissions; then
+ : "success"
+ else
+ describe="$describe: permissions not matching!"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="put preexist"
+ task_refcount add refs "$nonexistent"
+ if task_refcount prop_put refs "$nonexistent" preexist; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount prop_exists refs "$nonexistent" preexist; then
+ : "success"
+ else
+ describe="$describe: preexist not found!"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="remove after add twice"
+ task_refcount add refs "$nonexistent"
+ task_refcount add refs "$nonexistent"
+ if task_refcount remove refs "$nonexistent"; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount exists refs "$nonexistent"; then
+ describe="$describe: reference found!"
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="remove pkg1 after add pkg1 and pkg2"
+ ( PKGNAME="package1"; task_refcount add refs "$nonexistent" )
+ ( PKGNAME="package2"; task_refcount add refs "$nonexistent" )
+ ( PKGNAME="package1"; task_refcount remove refs "$nonexistent" )
+ if task_refcount exists refs "$nonexistent"; then
+ : "success"
+ else
+ return 1
+ fi
+}
+
+test6()
+{
+ describe="put property with no refcount"
+ local permissions="0400 root wheel"
+ if task_refcount prop_put refs "$nonexistent" permissions $permissions; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount exists refs "$nonexistent"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+}
+
+test7()
+{
+ describe="delete refcount"
+ task_refcount add refs "$nonexistent"
+ task_refcount prop_put refs "$nonexistent" owner
+ if task_refcount delete refs "$nonexistent"; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount exists refs "$nonexistent"; then
+ describe="$describe: reference found!"
+ return 1
+ fi
+}
+
+test8()
+{
+ describe="remove refcount after putting property"
+ task_refcount add refs "$nonexistent"
+ task_refcount prop_put refs "$nonexistent" owner
+ if task_refcount remove refs "$nonexistent"; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount exists refs "$nonexistent"; then
+ describe="$describe: reference found!"
+ return 1
+ fi
+ if task_refcount prop_exists refs "$nonexistent" owner; then
+ : "success"
+ else
+ describe="$describe: property not found!"
+ return 1
+ fi
+}
+
+test9()
+{
+ describe="delete property"
+ task_refcount prop_put refs "$nonexistent" owner
+ if task_refcount prop_delete refs "$nonexistent" owner; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount prop_exists refs "$nonexistent" owner; then
+ describe="$describe: property found!"
+ return 1
+ fi
+}
+
+test10()
+{
+ describe="add nonexistent file with PKG_DESTDIR"
+ test_destdir_setup
+ if task_refcount add refs "$nonexistent"; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount exists refs "$nonexistent"; then
+ : "success"
+ else
+ describe="$describe: reference missing!"
+ return 1
+ fi
+ if task_refcount prop_exists refs "$nonexistent" permissions; then
+ describe="$describe: permissions found!"
+ return 1
+ fi
+ if task_refcount prop_exists refs "$nonexistent" preexist; then
+ describe="$describe: preexist found!"
+ return 1
+ fi
+ if [ -d "${PKG_REFCOUNT_DBDIR}" ]; then
+ describe="$describe: wrong refcount directory!"
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="put permissions with PKG_DESTDIR"
+ test_destdir_setup
+ local permissions="0400 root wheel"
+ task_refcount add refs "$nonexistent"
+ if task_refcount prop_put refs "$nonexistent" permissions $permissions; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount prop_match refs "$nonexistent" permissions $permissions; then
+ : "success"
+ else
+ describe="$describe: permissions not matching!"
+ return 1
+ fi
+ if [ -d "${PKG_REFCOUNT_DBDIR}" ]; then
+ describe="$describe: wrong refcount directory!"
+ return 1
+ fi
+ return 0
+}
+
+test12()
+{
+ describe="put preexist with DESTDIR"
+ test_destdir_setup
+ task_refcount add refs "$nonexistent"
+ if task_refcount prop_put refs "$nonexistent" preexist; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount prop_exists refs "$nonexistent" preexist; then
+ : "success"
+ else
+ describe="$describe: preexist not found!"
+ return 1
+ fi
+ if [ -d "${PKG_REFCOUNT_DBDIR}" ]; then
+ describe="$describe: wrong refcount directory!"
+ return 1
+ fi
+ return 0
+}
+
+test13()
+{
+ describe="remove after add twice with PKG_DESTDIR"
+ test_destdir_setup
+ task_refcount add refs "$nonexistent"
+ task_refcount add refs "$nonexistent"
+ if task_refcount remove refs "$nonexistent"; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount exists refs "$nonexistent"; then
+ describe="$describe: reference found!"
+ return 1
+ fi
+ return 0
+}
+
+test14()
+{
+ describe="remove pkg1 after add pkg1 and pkg2 with PKG_DESTDIR"
+ test_destdir_setup
+ ( PKGNAME="package1"; task_refcount add refs "$nonexistent" )
+ ( PKGNAME="package2"; task_refcount add refs "$nonexistent" )
+ ( PKGNAME="package1"; task_refcount remove refs "$nonexistent" )
+ if task_refcount exists refs "$nonexistent"; then
+ : "success"
+ else
+ return 1
+ fi
+}
+
+test15()
+{
+ describe="put property with no refcount with PKG_DESTDIR"
+ test_destdir_setup
+ local permissions="0400 root wheel"
+ if task_refcount prop_put refs "$nonexistent" permissions $permissions; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount exists refs "$nonexistent"; then
+ describe="$describe: refcount exists!"
+ return 1
+ fi
+ if [ -d "${PKG_REFCOUNT_DBDIR}" ]; then
+ describe="$describe: wrong refcount directory!"
+ return 1
+ fi
+}
+
+test16()
+{
+ describe="delete refcount with PKG_DESTDIR"
+ test_destdir_setup
+ task_refcount add refs "$nonexistent"
+ task_refcount prop_put refs "$nonexistent" owner
+ if task_refcount delete refs "$nonexistent"; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount exists refs "$nonexistent"; then
+ describe="$describe: reference found!"
+ return 1
+ fi
+}
+
+test17()
+{
+ describe="remove refcount after putting property with PKG_DESTDIR"
+ test_destdir_setup
+ task_refcount add refs "$nonexistent"
+ task_refcount prop_put refs "$nonexistent" owner
+ if task_refcount remove refs "$nonexistent"; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount exists refs "$nonexistent"; then
+ describe="$describe: reference found!"
+ return 1
+ fi
+ if task_refcount prop_exists refs "$nonexistent" owner; then
+ : "success"
+ else
+ describe="$describe: property not found!"
+ return 1
+ fi
+ if [ -d "${PKG_REFCOUNT_DBDIR}" ]; then
+ describe="$describe: wrong refcount directory!"
+ return 1
+ fi
+}
+
+test18()
+{
+ describe="delete property with PKG_DESTDIR"
+ test_destdir_setup
+ task_refcount prop_put refs "$nonexistent" owner
+ if task_refcount prop_delete refs "$nonexistent" owner; then
+ : "success"
+ else
+ return 1
+ fi
+ if task_refcount prop_exists refs "$nonexistent" owner; then
+ describe="$describe: property found!"
+ return 1
+ fi
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_shells.sh b/pkgtools/pkgtasks/files/t/t_shells.sh
new file mode 100644
index 00000000000..d522f74a2ca
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_shells.sh
@@ -0,0 +1,339 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load shells
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${MKDIR:=mkdir}
+
+ PKG_PREFIX="${TEST_CURDIR}"
+ PKG_DESTDIR=
+
+ shelldb="etc/shells"
+ shelldb_lock="$shelldb.lock"
+
+ datafile="datafile"
+ ${CAT} > $datafile << EOF
+# SHELL: bin/pdksh $shelldb
+# SHELL: bin/bash $shelldb
+# SHELL: ${PKG_PREFIX}/bin/pdksh $shelldb
+EOF
+
+ ${MKDIR} -p etc
+}
+
+test_destdir_setup()
+{
+ : ${MKDIR:=mkdir}
+ : ${MV:=mv}
+
+ PKG_DESTDIR="${TEST_CURDIR}/destdir"
+ ${MKDIR} -p "${PKG_DESTDIR}${PKG_PREFIX}"
+ ${MV} etc "${PKG_DESTDIR}${PKG_PREFIX}"
+}
+
+test1()
+{
+ describe="check-add shells with empty shell database"
+ if task_shells check-add < $datafile; then
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="add shells"
+ if task_shells add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="verify uniqueness"
+ task_shells add < $datafile
+ local count=0
+ local line
+ while read line; do
+ case $line in
+ */pdksh*) count="$count + 1" ;;
+ esac
+ done < $shelldb
+ count=$(( $count ))
+ if [ $count -gt 1 ]; then
+ describe="$describe: too many pdksh!"
+ return 1
+ fi
+ if [ -f "$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="check-add shells with all shells added"
+ task_shells add < $datafile
+ if task_shells check-add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="check-remove shells with no shells removed"
+ task_shells add < $datafile
+ if task_shells check-remove < $datafile; then
+ return 1
+ fi
+ if [ -f "$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="remove shells"
+ task_shells add < $datafile
+ if task_shells remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="verify empty shell database"
+ task_shells add < $datafile
+ task_shells remove < $datafile
+ local count=0
+ while read line; do
+ count="$count + 1"
+ done < $shelldb
+ count=$(( $count ))
+ if [ $count -gt 0 ]; then
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="check-remove shells with empty shell database"
+ task_createfile "$shelldb"
+ if task_shells check-remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="add shells with PKG_DESTDIR"
+ test_destdir_setup
+ if task_shells add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$shelldb" ]; then
+ describe="$describe: $shelldb exists!"
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="verify uniqueness with PKG_DESTDIR"
+ test_destdir_setup
+ task_shells add < $datafile
+ local count=0
+ local line
+ while read line; do
+ case $line in
+ */pdksh*) count="$count + 1" ;;
+ esac
+ done < "${PKG_DESTDIR}${PKG_PREFIX}/$shelldb"
+ count=$(( $count ))
+ if [ $count -gt 1 ]; then
+ describe="$describe: too many pdksh!"
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$shelldb" ]; then
+ describe="$describe: $shelldb exists!"
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="check-add shells with all shells added with PKG_DESTDIR"
+ test_destdir_setup
+ task_shells add < $datafile
+ if task_shells check-add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$shelldb" ]; then
+ describe="$describe: $shelldb exists!"
+ return 1
+ fi
+ return 0
+}
+
+test12()
+{
+ describe="check-remove shells with no shells removed with PKG_DESTDIR"
+ test_destdir_setup
+ task_shells add < $datafile
+ if task_shells check-remove < $datafile; then
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$shelldb" ]; then
+ describe="$describe: $shelldb exists!"
+ return 1
+ fi
+ return 0
+}
+
+test13()
+{
+ describe="remove shells with PKG_DESTDIR"
+ test_destdir_setup
+ task_shells add < $datafile
+ if task_shells remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$shelldb" ]; then
+ describe="$describe: $shelldb exists!"
+ return 1
+ fi
+ return 0
+}
+
+test14()
+{
+ describe="verify empty shell database"
+ test_destdir_setup
+ task_shells add < $datafile
+ task_shells remove < $datafile
+ local count=0
+ while read line; do
+ count="$count + 1"
+ done < "${PKG_DESTDIR}${PKG_PREFIX}/$shelldb"
+ count=$(( $count ))
+ if [ $count -gt 0 ]; then
+ return 1
+ fi
+ if [ -f "$shelldb" ]; then
+ describe="$describe: $shelldb exists!"
+ return 1
+ fi
+ return 0
+}
+
+test15()
+{
+ describe="check-remove shells with empty shell database"
+ test_destdir_setup
+ task_createfile "${PKG_DESTDIR}${PKG_PREFIX}/$shelldb"
+ if task_shells check-remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if [ -f "${PKG_DESTDIR}${PKG_PREFIX}/$shelldb_lock" ]; then
+ describe="$describe: lock exists!"
+ return 1
+ fi
+ if [ -f "$shelldb" ]; then
+ describe="$describe: $shelldb exists!"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_shlibs.sh b/pkgtools/pkgtasks/files/t/t_shlibs.sh
new file mode 100644
index 00000000000..0904a1fc712
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_shlibs.sh
@@ -0,0 +1,106 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load shlibs
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${GREP:=grep}
+ : ${MV:=mv}
+
+ : ${PKGNAME:=${0##*/}}
+
+ PKG_PREFIX="${TEST_CURDIR}"
+ PKG_DESTDIR=
+
+ datafile="datafile"
+ ${CAT} > $datafile << EOF
+# SHLIB: lib
+EOF
+
+ dbfile="shlibs"
+ dbfile_tmp="$dbfile.tmp.$$"
+ task_createfile "$dbfile"
+}
+
+# Mock ldconfig that just toggles between adding and removing paths
+# from a flat text file.
+#
+ldconfig()
+{
+ : ${GREP:=grep}
+ : ${MV:=mv}
+
+ [ $# -gt 0 ] || set -- ${PKG_PREFIX}/lib
+ for path; do
+ if ${GREP} -q '^'"$path"'$' < $dbfile; then
+ ${GREP} -v '^'"$path"'$' < $dbfile > $dbfile_tmp
+ ${MV} -f "$dbfile_tmp" "$dbfile"
+ else
+ echo "$path" >> $dbfile
+ fi
+ done
+ return 0
+}
+
+test1()
+{
+ describe="add with empty cache"
+ if task_shlibs add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if ${GREP} -cq "^" "$dbfile"; then
+ : "success"
+ else
+ describe="$describe: not in $dbfile!"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="remove after adding to cache"
+ task_shlibs add < $datafile
+ if task_shlibs remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ if ${GREP} -cq "^" "$dbfile"; then
+ describe="$describe: still in $dbfile!"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_sort.sh b/pkgtools/pkgtasks/files/t/t_sort.sh
new file mode 100644
index 00000000000..3f9d289eb78
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_sort.sh
@@ -0,0 +1,155 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load sort
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${CMP:=cmp}
+
+ ${CAT} > data << EOF
+c
+e
+d
+a
+d
+b
+c
+b
+e
+a
+EOF
+ ${CAT} > sorted << EOF
+a
+a
+b
+b
+c
+c
+d
+d
+e
+e
+EOF
+ ${CAT} > reversed << EOF
+e
+e
+d
+d
+c
+c
+b
+b
+a
+a
+EOF
+ ${CAT} > unique-sorted << EOF
+a
+b
+c
+d
+e
+EOF
+ ${CAT} > unique-reversed << EOF
+e
+d
+c
+b
+a
+EOF
+}
+
+test1()
+{
+ describe="sort"
+ task_sort < data > output
+ if ${CMP} -s output sorted; then
+ : "success"
+ else
+ ${CAT} output
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="reverse sort"
+ task_sort -r < data > output
+ if ${CMP} -s output reversed; then
+ : "success"
+ else
+ ${CAT} output
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="empty input"
+ task_createfile empty
+ task_sort < empty > output
+ if ${CMP} -s output empty; then
+ : "success"
+ else
+ ${CAT} output
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="unique sort"
+ task_sort -u < data > output
+ if ${CMP} -s output unique-sorted; then
+ : "success"
+ else
+ ${CAT} output
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="unique reverse-sort"
+ task_sort -ru < data > output
+ if ${CMP} -s output unique-reversed; then
+ : "success"
+ else
+ ${CAT} output
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_taskfunc.sh b/pkgtools/pkgtasks/files/t/t_taskfunc.sh
new file mode 100644
index 00000000000..a9d77a12fc9
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_taskfunc.sh
@@ -0,0 +1,173 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load taskfunc
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${CMP:=cmp}
+
+ ${CAT} > data << EOF
+# ( ) junk
+# TASK: hello # GREET: world one
+# TASK: bye # FAREWELL: dear one
+# TASK: hello # GREET: world two
+# TASK: bye # FAREWELL: dear two
+# TASK: hello # GREET: world three
+# TASK: bye # FAREWELL: dear three
+EOF
+ ${CAT} > expected-add << EOF
+hello add: world one
+hello add: world two
+hello add: world three
+bye add: dear one
+bye add: dear two
+bye add: dear three
+EOF
+ ${CAT} > expected-remove << EOF
+hello remove: world one
+hello remove: world two
+hello remove: world three
+bye remove: dear one
+bye remove: dear two
+bye remove: dear three
+EOF
+}
+
+mock_function()
+{
+ local name="$1"; shift
+ local nametag="$1"; shift
+ local action="$1"; shift
+ local stage="$1"
+
+ case $action in
+ add|remove|check-add|check-remove)
+ : "valid action" ;;
+ *) return 0 ;;
+ esac
+ case $stage in
+ postinstall|"")
+ : "valid stage" ;;
+ *) return 0 ;;
+ esac
+
+ local hash tag line
+ while read hash tag line; do
+ case $hash/$tag in
+ "#/$nametag")
+ case $line in FAIL) return 1 ;; esac
+ echo "$name $action: $line" ;;
+ esac
+ done
+}
+
+hello()
+{
+ mock_function hello "GREET:" "$@"
+}
+
+bye()
+{
+ mock_function bye "FAREWELL:" "$@"
+}
+
+test1()
+{
+ describe="missing function"
+ if echo "# TASK: missing arg1 arg2 arg3" | task_function add; then
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="add"
+ task_function add < data > value
+ if ${CMP} -s expected-add value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="remove"
+ task_function remove < data > value
+ if ${CMP} -s expected-remove value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="add fail"
+ if echo "# TASK: hello # GREET: FAIL" | task_function add; then
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="wrong stage"
+ task_function add preinstall < data > value
+ task_createfile expected
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="correct stage"
+ task_function add postinstall < data > value
+ if ${CMP} -s expected-add value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_tee.sh b/pkgtools/pkgtasks/files/t/t_tee.sh
new file mode 100644
index 00000000000..a90563c64c9
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_tee.sh
@@ -0,0 +1,133 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load tee
+task_load unittest
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${CMP:=cmp}
+ : ${CP:=cp}
+
+ ${CAT} > data << EOF
+line 1
+line 2
+line 3
+line 4
+line 5
+EOF
+}
+
+test1()
+{
+ describe="no files"
+ ${CP} data expected
+ task_tee < data > value
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="output files"
+ ${CP} data expected
+ task_tee out1 out2 < data > value
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ if ${CMP} -s expected out1; then
+ : "success"
+ else
+ describe="$describe: out1"
+ ${CAT} out1
+ return 1
+ fi
+ if ${CMP} -s expected out2; then
+ : "success"
+ else
+ describe="$describe: out2"
+ ${CAT} out2
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="overwrite existing files"
+ ${CP} data expected
+ echo "overwritten" > out
+ task_tee out < data > value
+ if ${CMP} -s expected value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ if ${CMP} -s expected out; then
+ : "success"
+ else
+ describe="$describe: out"
+ ${CAT} out
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="append existing files"
+ echo "append" > out
+ ${CP} out expected
+ ${CAT} data >> expected
+ task_tee -a out < data > value
+ if ${CMP} -s data value; then
+ : "success"
+ else
+ ${CAT} value
+ return 1
+ fi
+ if ${CMP} -s expected out; then
+ : "success"
+ else
+ describe="$describe: out"
+ ${CAT} out
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_truthy.sh b/pkgtools/pkgtasks/files/t/t_truthy.sh
new file mode 100644
index 00000000000..85fb25e643a
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_truthy.sh
@@ -0,0 +1,72 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load truthy
+task_load unittest
+
+test1()
+{
+ describe="task_is_truthy yes"
+ task_is_truthy yes
+}
+
+test2()
+{
+ describe="task_is_truthy true"
+ task_is_truthy true
+}
+
+test3()
+{
+ describe="task_is_truthy on"
+ task_is_truthy on
+}
+
+test4()
+{
+ describe="task_is_truthy 1"
+ task_is_truthy 1
+}
+
+test5()
+{
+ describe="task_is_truthy case-insensitive"
+ task_is_truthy YES
+}
+
+test6()
+{
+ describe="task_is_truthy no"
+ if task_is_truthy no; then
+ return 1
+ else
+ : "success"
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_usergroup.sh b/pkgtools/pkgtasks/files/t/t_usergroup.sh
new file mode 100644
index 00000000000..8f4f26ac2c6
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_usergroup.sh
@@ -0,0 +1,194 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load unittest
+task_load usergroup
+task_load usergroup_mock
+
+# If this script is not directly included by another script, then define
+# mock platform_groupadd() and platform_useradd() functions needed by
+# usergroup.subr.
+#
+if [ -z "$__platform_usergroup__" ]; then
+ platform_groupadd()
+ {
+ mock_groupadd "$@"
+ }
+
+ platform_useradd()
+ {
+ mock_useradd "$@"
+ }
+fi
+
+test_setup()
+{
+ ETC_GROUP="${TEST_CURDIR}/etc.group"
+ ETC_PASSWD="${TEST_CURDIR}/etc.master.passwd"
+ mock_usergroup_setup
+
+ existent_gid=110
+ existent_group="groupB"
+ nonexistent_gid=300
+ nonexistent_group="groupG"
+
+ existent_uid=110
+ existent_user="userB"
+ nonexistent_uid=300
+ nonexistent_user="userG"
+
+ # Run any platform-specific setup.
+ if task_is_function platform_test_setup; then
+ platform_test_setup
+ fi
+}
+
+test_teardown()
+{
+ # Run any platform-specific teardown.
+ if task_is_function platform_test_teardown; then
+ platform_test_teardown
+ fi
+}
+
+test1()
+{
+ describe="nonexistent group, no groupid"
+ if task_addgroup "$nonexistent_group"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="nonexistent group, nonexistent groupid"
+ if task_addgroup "$nonexistent_group" "$nonexistent_gid"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="nonexistent group, existent groupid"
+ if task_addgroup "$nonexistent_group" "$existent_gid"; then
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="existent group, no groupid"
+ if task_addgroup "$existent_group"; then
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="existent group, nonexistent groupid"
+ if task_addgroup "$existent_group" "$nonexistent_gid"; then
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="existent group, existent groupid"
+ if task_addgroup "$existent_group" "$existent_gid"; then
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="nonexistent user, no userid"
+ if task_adduser "$nonexistent_user" "$existent_group"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="nonexistent user, nonexistent userid"
+ if task_adduser "$nonexistent_user" "$existent_group" "$nonexistent_uid"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="nonexistent user, existent userid"
+ if task_adduser "$nonexistent_user" "$existent_group" "$existent_uid"; then
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="existent user, no userid"
+ if task_adduser "$existent_user" "$existent_group"; then
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="existent user, nonexistent userid"
+ if task_adduser "$existent_user" "$existent_group" "$nonexistent_uid"; then
+ return 1
+ fi
+ return 0
+}
+
+test12()
+{
+ describe="existent user, existent userid"
+ if task_adduser "$existent_user" "$existent_group" "$existent_uid"; then
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_usergroup_FreeBSD.sh b/pkgtools/pkgtasks/files/t/t_usergroup_FreeBSD.sh
new file mode 100644
index 00000000000..66b819dbba3
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_usergroup_FreeBSD.sh
@@ -0,0 +1,53 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load unittest
+task_load usergroup_mock
+
+# Mock uname to select usergroup_FreeBSD.subr.
+uname()
+{
+ # DragonFly also uses usergroup_FreeBSD.subr.
+ echo "DragonFly"
+}
+
+# Mock pw needed for usergroup_FreeBSD.subr.
+pw()
+{
+ case $1 in
+ groupadd)
+ local group="$2"; shift 2
+ mock_groupadd "$@" "$group" ;;
+ useradd)
+ local user="$2"; shift 2
+ mock_useradd "$@" "$user" ;;
+ esac
+}
+
+__platform_usergroup__="yes"
+
+task_load_test t_usergroup "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_usergroup_Linux.sh b/pkgtools/pkgtasks/files/t/t_usergroup_Linux.sh
new file mode 100644
index 00000000000..80505b9036d
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_usergroup_Linux.sh
@@ -0,0 +1,102 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load quote
+task_load unittest
+task_load usergroup_mock
+
+# Mock uname() to select usergroup_Linux.subr.
+uname()
+{
+ echo "Linux"
+}
+
+# Mock groupadd and useradd needed for usergroup_Linux.subr.
+groupadd()
+{
+ # Skip "-r" and pass all other options through to mock_groupadd().
+ local groupadd_args=
+ local quoted
+ local arg
+ local OPTIND=1
+ while getopts ":g:r" arg "$@"; do
+ case $arg in
+ g) task_quote "${OPTARG}"
+ groupadd_args="$groupadd_args -$arg $quoted" ;;
+ r) : "silently accept" ;;
+ *) return 127 ;;
+ esac
+ done
+ shift $(( ${OPTIND} - 1 ))
+ [ $# -eq 1 ] || return 127
+ local group="$1"; shift
+
+ [ -n "$group" ] || return 1
+ task_quote "$group"
+ groupadd_args="$groupadd_args $quoted"
+
+ eval mock_groupadd $groupadd_args
+}
+
+useradd()
+{
+ # Skip "-M" and "-r" and pass all other options through to
+ # mock_useradd().
+ #
+ local useradd_args=
+ local quoted
+ local arg
+ local OPTIND=1
+ while getopts ":c:d:g:Mrs:u:" arg "$@"; do
+ case $arg in
+ [Mr]) : "silently accept" ;;
+ [cdgsu])
+ task_quote "${OPTARG}"
+ useradd_args="$useradd_args -$arg $quoted" ;;
+ *) return 127 ;;
+ esac
+ done
+ shift $(( ${OPTIND} - 1 ))
+ [ $# -eq 1 ] || return 127
+ local user="$1"; shift
+
+ [ -n "$user" ] || return 1
+ task_quote "$user"
+ useradd_args="$useradd_args $quoted"
+
+ eval mock_useradd $useradd_args
+}
+
+platform_test_setup()
+{
+ LOGIN_DEFS="${TEST_CURDIR}/etc.login.defs"
+ echo "CREATE_HOME yes" > ${LOGIN_DEFS}
+}
+
+__platform_usergroup__="yes"
+
+task_load_test t_usergroup "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_usergroup_MirBSD.sh b/pkgtools/pkgtasks/files/t/t_usergroup_MirBSD.sh
new file mode 100644
index 00000000000..0939ec12c51
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_usergroup_MirBSD.sh
@@ -0,0 +1,378 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+# Mock uname() to select usergroup_MirBSD.subr.
+uname()
+{
+ echo "MirBSD"
+}
+
+task_load unittest
+task_load usergroup
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${GREP:=grep}
+ : ${MV:=mv}
+
+ ETC_GROUP="${TEST_CURDIR}/etc.group"
+ ${CAT} > ${ETC_GROUP} << EOF
+groupA:*:100:
+groupB:*:105:
+groupC:*:110:
+EOF
+ existent_gid=110
+ existent_group="groupB"
+ matching_gid=105
+ nonexistent_gid=300
+ nonexistent_group="groupG"
+
+ ETC_PASSWD="${TEST_CURDIR}/etc.master.passwd"
+ ${CAT} > ${ETC_PASSWD} << EOF
+userA:*:100:100::0:0:package A user:/nonexistent:/bin/sh
+userB:*:105:105::0:0:package B user:/nonexistent:/bin/sh
+userC:*:110:110::0:0:package C user:/nonexistent:/bin/sh
+EOF
+ existent_uid=110
+ existent_user="userB"
+ nonexistent_uid=300
+ nonexistent_user="userG"
+
+ # Set CHOWN and PWD_MKDB to "working" mocks.
+ CHOWN="chown"
+ PWD_MKDB="pwd_mkdb"
+}
+
+# Mock utilities needed by MirBSD platform_groupadd() and platform_useradd().
+chown()
+{
+ return 0
+}
+
+mock_false()
+{
+ return 1
+}
+
+pwd_mkdb()
+{
+ local arg
+ local OPTIND=1
+ while getopts ":cd:psu:" arg "$@"; do
+ case $arg in
+ [cpsdu])
+ : "silently ignore" ;;
+ *) return 127 ;;
+ esac
+ done
+ shift $(( ${OPTIND} - 1 ))
+ [ $# -gt 0 ] || return 127
+
+ ${MV} -f "$1" "${ETC_PASSWD}"
+}
+
+test1()
+{
+ describe="nonexistent group, no groupid"
+ if task_addgroup "$nonexistent_group"; then
+ : "success"
+ else
+ return 1
+ fi
+ if ${GREP} -q "^$nonexistent_group:" "${ETC_GROUP}"; then
+ : "success"
+ else
+ describe="$describe: group missing!"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="nonexistent group, nonexistent groupid"
+ if task_addgroup "$nonexistent_group" "$nonexistent_gid"; then
+ : "success"
+ else
+ return 1
+ fi
+ if ${GREP} -q "^$nonexistent_group:[^:]*:$nonexistent_gid:" "${ETC_GROUP}"; then
+ : "success"
+ else
+ describe="$describe: group missing!"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="nonexistent group, existent groupid"
+ if task_addgroup "$nonexistent_group" "$existent_gid"; then
+ return 1
+ fi
+ if ${GREP} -q "^$nonexistent_group:" "${ETC_GROUP}"; then
+ describe="$describe: group exists!"
+ return 1
+ fi
+ if ${GREP} -q "^[^:]*:[^:]*:$existent_gid:" "${ETC_GROUP}"; then
+ : "success"
+ else
+ describe="$describe: group ID missing!"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="existent group, no groupid"
+ if task_addgroup "$existent_group"; then
+ return 1
+ fi
+ if ${GREP} -q "^$existent_group:" "${ETC_GROUP}"; then
+ : "success"
+ else
+ describe="$describe: group missing!"
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="existent group, nonexistent groupid"
+ if task_addgroup "$existent_group" "$nonexistent_gid"; then
+ return 1
+ fi
+ if ${GREP} -q "^$existent_group:" "${ETC_GROUP}"; then
+ : "success"
+ else
+ describe="$describe: group missing!"
+ return 1
+ fi
+ if ${GREP} -q "^[^:]*:[^:]*:$nonexistent_gid:" "${ETC_GROUP}"; then
+ describe="$describe: group ID exists!"
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="existent group, existent groupid"
+ if task_addgroup "$existent_group" "$existent_gid"; then
+ return 1
+ fi
+ if ${GREP} -q "^$existent_group:" "${ETC_GROUP}"; then
+ : "success"
+ else
+ describe="$describe: group missing!"
+ return 1
+ fi
+ if ${GREP} -q "^[^:]*:[^:]*:$existent_gid:" "${ETC_GROUP}"; then
+ : "success"
+ else
+ describe="$describe: group ID missing!"
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="broken chown(8) when adding group"
+ CHOWN="mock_false"
+ if task_addgroup "$nonexistent_group"; then
+ return 1
+ fi
+ if ${GREP} -q "^$nonexistent_group:" "${ETC_GROUP}"; then
+ describe="$describe: group exists!"
+ return 1
+ fi
+ set -- ${ETC_GROUP}.tmp.*
+ case $1 in
+ "${ETC_GROUP}.tmp.*")
+ : "group tmpdir not found" ;;
+ *) describe="$describe: group tmpdir exists!"
+ return 1 ;;
+ esac
+ return 0
+}
+
+test8()
+{
+ describe="nonexistent user, no userid"
+ if task_adduser "$nonexistent_user" "$existent_group"; then
+ : "success"
+ else
+ return 1
+ fi
+ if ${GREP} -q "^$nonexistent_user:[^:]*:[^:]*:$matching_gid:" "${ETC_PASSWD}"; then
+ : "success"
+ else
+ describe="$describe: user missing!"
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="nonexistent user, nonexistent userid"
+ if task_adduser "$nonexistent_user" "$existent_group" "$nonexistent_uid"; then
+ : "success"
+ else
+ return 1
+ fi
+ if ${GREP} -q "^$nonexistent_user:[^:]*:$nonexistent_uid:$matching_gid:" "${ETC_PASSWD}"; then
+ : "success"
+ else
+ describe="$describe: user missing!"
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="nonexistent user, existent userid"
+ if task_adduser "$nonexistent_user" "$existent_group" "$existent_uid"; then
+ return 1
+ fi
+ if ${GREP} -q "^$nonexistent_user:" "${ETC_PASSWD}"; then
+ describe="$describe: user exists!"
+ return 1
+ fi
+ if ${GREP} -q "^[^:]*:[^:]*:[^:]*:$existent_uid:" "${ETC_PASSWD}"; then
+ : "success"
+ else
+ describe="$describe: user ID missing!"
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="existent user, no userid"
+ if task_adduser "$existent_user" "$existent_group"; then
+ return 1
+ fi
+ if ${GREP} -q "^$existent_user:" "${ETC_PASSWD}"; then
+ : "success"
+ else
+ describe="$describe: user missing!"
+ return 1
+ fi
+ return 0
+}
+
+test12()
+{
+ describe="existent user, nonexistent userid"
+ if task_adduser "$existent_user" "$existent_group" "$nonexistent_uid"; then
+ return 1
+ fi
+ if ${GREP} -q "^$existent_user:" "${ETC_PASSWD}"; then
+ : "success"
+ else
+ describe="$describe: user missing!"
+ return 1
+ fi
+ if ${GREP} -q "^[^:]*:[^:]*:[^:]*:$nonexistent_uid:" "${ETC_PASSWD}"; then
+ describe="$describe: user ID exists!"
+ return 1
+ fi
+ return 0
+}
+
+test13()
+{
+ describe="existent user, existent userid"
+ if task_adduser "$existent_user" "$existent_group" "$existent_uid"; then
+ return 1
+ fi
+ if ${GREP} -q "^$existent_user:" "${ETC_PASSWD}"; then
+ : "success"
+ else
+ describe="$describe: user missing!"
+ return 1
+ fi
+ if ${GREP} -q "^[^:]*:[^:]*:[^:]*:$existent_uid:" "${ETC_PASSWD}"; then
+ : "success"
+ else
+ describe="$describe: user ID missing!"
+ return 1
+ fi
+ return 0
+}
+
+test14()
+{
+ describe="broken chown(8) when adding user"
+ CHOWN="mock_false"
+ if task_adduser "$nonexistent_user" "$existent_group"; then
+ return 1
+ fi
+ if ${GREP} -q "^$nonexistent_user:" "${ETC_PASSWD}"; then
+ describe="$describe: user exists!"
+ return 1
+ fi
+ set -- ${ETC_PASSWD}.tmp.*
+ case $1 in
+ "${ETC_PASSWD}.tmp.*")
+ : "user tmpdir not found" ;;
+ *) describe="$describe: user tmpdir exists!"
+ return 1 ;;
+ esac
+ return 0
+}
+
+test15()
+{
+ describe="broken pwd_mkdb(8) when adding user"
+ PWD_MKDB="mock_false"
+ if task_adduser "$nonexistent_user" "$existent_group"; then
+ return 1
+ fi
+ if ${GREP} -q "^$nonexistent_user:" "${ETC_PASSWD}"; then
+ describe="$describe: user exists!"
+ return 1
+ fi
+ set -- ${ETC_PASSWD}.tmp.*
+ case $1 in
+ "${ETC_PASSWD}.tmp.*")
+ : "user tmpdir not found" ;;
+ *) describe="$describe: user tmpdir exists!"
+ return 1 ;;
+ esac
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_usergroup_NetBSD.sh b/pkgtools/pkgtasks/files/t/t_usergroup_NetBSD.sh
new file mode 100644
index 00000000000..d94c50a8e8b
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_usergroup_NetBSD.sh
@@ -0,0 +1,51 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load unittest
+task_load usergroup_mock
+
+# Mock uname() to select usergroup_NetBSD.subr.
+uname()
+{
+ # SunOS also uses usergroup_NetBSD.subr.
+ echo "SunOS"
+}
+
+# Mock groupadd and useradd needed for usergroup_NetBSD.subr
+groupadd()
+{
+ mock_groupadd "$@"
+}
+
+useradd()
+{
+ mock_useradd "$@"
+}
+
+__platform_usergroup__="yes"
+
+task_load_test t_usergroup "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_usergroup_exists.sh b/pkgtools/pkgtasks/files/t/t_usergroup_exists.sh
new file mode 100644
index 00000000000..46a547125d1
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_usergroup_exists.sh
@@ -0,0 +1,206 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load unittest
+task_load usergroup_exists
+
+test_setup()
+{
+ : ${MKDIR:=mkdir}
+
+ TMPDIR="${TEST_CURDIR}/tmp"
+ ${MKDIR} -p "${TMPDIR}"
+
+ # These values may need to be corrected.
+ existent_gid=32766
+ existent_group="nogroup"
+ nonexistent_gid=27777
+ nonexistent_group="nonexistent_group"
+
+ existent_uid=32767
+ existent_user="nobody"
+ nonexistent_uid=27777
+ nonexistent_user="nonexistent_user"
+}
+
+test1()
+{
+ describe="nonexistent group, no groupid"
+ task_requires_root || return 0
+ task_group_exists $nonexistent_group
+ local result=$?
+ if [ $result -ne 1 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="nonexistent group, nonexistent groupid"
+ task_requires_root || return 0
+ task_group_exists $nonexistent_group $nonexistent_gid
+ local result=$?
+ if [ $result -ne 1 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="nonexistent group, existent groupid"
+ task_requires_root || return 0
+ task_group_exists $nonexistent_group $existent_gid
+ local result=$?
+ if [ $result -ne 2 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="existent group, no groupid"
+ task_requires_root || return 0
+ task_group_exists $existent_group
+ local result=$?
+ if [ $result -ne 0 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="existent group, nonexistent groupid"
+ task_requires_root || return 0
+ task_group_exists $existent_group $nonexistent_gid
+ local result=$?
+ if [ $result -ne 2 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="existent group, existent groupid"
+ task_requires_root || return 0
+ task_group_exists $existent_group $existent_gid
+ local result=$?
+ if [ $result -ne 0 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="nonexistent user, no userid"
+ task_requires_root || return 0
+ task_user_exists $nonexistent_user
+ local result=$?
+ if [ $result -ne 1 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="nonexistent user, nonexistent userid"
+ task_requires_root || return 0
+ task_user_exists $nonexistent_user $nonexistent_uid
+ local result=$?
+ if [ $result -ne 1 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="nonexistent user, existent userid"
+ task_requires_root || return 0
+ task_user_exists $nonexistent_user $existent_uid
+ local result=$?
+ if [ $result -ne 2 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="existent user, no userid"
+ task_requires_root || return 0
+ task_user_exists $existent_user
+ local result=$?
+ if [ $result -ne 0 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="existent user, nonexistent userid"
+ task_requires_root || return 0
+ task_user_exists $existent_user $nonexistent_uid
+ local result=$?
+ if [ $result -ne 2 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test12()
+{
+ describe="existent user, existent userid"
+ task_requires_root || return 0
+ task_user_exists $existent_user $existent_uid
+ local result=$?
+ if [ $result -ne 0 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_usergroup_mock.sh b/pkgtools/pkgtasks/files/t/t_usergroup_mock.sh
new file mode 100644
index 00000000000..5291b78535c
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_usergroup_mock.sh
@@ -0,0 +1,334 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load unittest
+task_load usergroup_mock
+
+test_setup()
+{
+ ETC_GROUP="${TEST_CURDIR}/etc.group"
+ ETC_PASSWD="${TEST_CURDIR}/etc.passwd"
+ mock_usergroup_setup
+
+ existent_gid=110
+ existent_group="groupB"
+ matching_gid=105
+ nonexistent_gid=300
+ nonexistent_group="groupG"
+
+ existent_uid=110
+ existent_user="userB"
+ matching_gid=105
+ nonexistent_uid=200
+ nonexistent_user="userD"
+}
+
+test1()
+{
+ describe="exists: nonexistent group, no groupid"
+ mock_group_exists $nonexistent_group
+ local result=$?
+ if [ $result -ne 1 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="exists: nonexistent group, nonexistent groupid"
+ mock_group_exists $nonexistent_group $nonexistent_gid
+ local result=$?
+ if [ $result -ne 1 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="exists: nonexistent group, existent groupid"
+ mock_group_exists $nonexistent_group $existent_gid
+ local result=$?
+ if [ $result -ne 2 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="exists: existent group, no groupid"
+ mock_group_exists $existent_group
+ local result=$?
+ if [ $result -ne 0 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="exists: existent group, nonexistent groupid"
+ mock_group_exists $existent_group $nonexistent_gid
+ local result=$?
+ if [ $result -ne 2 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="exists: existent group, existent groupid"
+ mock_group_exists $existent_group $existent_gid
+ local result=$?
+ if [ $result -ne 2 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="exists: existent group, matching groupid"
+ mock_group_exists $existent_group $matching_gid
+ local result=$?
+ if [ $result -ne 0 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test8()
+{
+ describe="exists: nonexistent user, no userid"
+ mock_user_exists $nonexistent_user
+ local result=$?
+ if [ $result -ne 1 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="exists: nonexistent user, nonexistent userid"
+ mock_user_exists $nonexistent_user $nonexistent_uid
+ local result=$?
+ if [ $result -ne 1 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test10()
+{
+ describe="exists: nonexistent user, existent userid"
+ mock_user_exists $nonexistent_user $existent_uid
+ local result=$?
+ if [ $result -ne 2 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test11()
+{
+ describe="exists: existent user, no userid"
+ mock_user_exists $existent_user
+ local result=$?
+ if [ $result -ne 0 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test12()
+{
+ describe="exists: existent user, nonexistent userid"
+ mock_user_exists $existent_user $nonexistent_uid
+ local result=$?
+ if [ $result -ne 2 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test13()
+{
+ describe="exists: existent user, existent userid"
+ mock_user_exists $existent_user $existent_uid
+ local result=$?
+ if [ $result -ne 2 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test14()
+{
+ describe="exists: existent user, matching userid"
+ mock_user_exists $existent_user $matching_uid
+ local result=$?
+ if [ $result -ne 0 ]; then
+ describe="$describe: $result"
+ return 1
+ fi
+ return 0
+}
+
+test15()
+{
+ describe="add: nonexistent group, no groupid"
+ if mock_groupadd "$nonexistent_group"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test16()
+{
+ describe="add: nonexistent group, nonexistent groupid"
+ if mock_groupadd -g "$nonexistent_gid" "$nonexistent_group"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test17()
+{
+ describe="add: nonexistent group, existent groupid"
+ if mock_groupadd -g "$existent_gid" "$nonexistent_group"; then
+ return 1
+ fi
+ return 0
+}
+
+test18()
+{
+ describe="add: existent group, no groupid"
+ if mock_groupadd "$existent_group"; then
+ return 1
+ fi
+ return 0
+}
+
+test19()
+{
+ describe="add: existent group, nonexistent groupid"
+ if mock_groupadd -g "$nonexistent_gid" "$existent_group"; then
+ return 1
+ fi
+ return 0
+}
+
+test20()
+{
+ describe="add: existent group, existent groupid"
+ if mock_groupadd -g "$existent_gid" "$existent_group"; then
+ return 1
+ fi
+ return 0
+}
+
+test21()
+{
+ describe="add: nonexistent user, no userid"
+ if mock_useradd -g "$existent_group" "$nonexistent_user"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test22()
+{
+ describe="add: nonexistent user, nonexistent userid"
+ if mock_useradd -g "$existent_group" -u "$nonexistent_uid" "$nonexistent_user"; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test23()
+{
+ describe="add: nonexistent user, existent userid"
+ if mock_useradd -g "$existent_group" -u "$existent_uid" "$nonexistent_user"; then
+ return 1
+ fi
+ return 0
+}
+
+test24()
+{
+ describe="add: existent user, no userid"
+ if mock_useradd -g "$existent_group" "$existent_user"; then
+ return 1
+ fi
+ return 0
+}
+
+test25()
+{
+ describe="add: existent user, nonexistent userid"
+ if mock_useradd -g "$existent_group" -u "$nonexistent_uid" "$existent_user"; then
+ return 1
+ fi
+ return 0
+}
+
+test26()
+{
+ describe="add: existent user, existent userid"
+ if mock_useradd -g "$existent_group" -u "$existent_uid" "$existent_user"; then
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_users.sh b/pkgtools/pkgtasks/files/t/t_users.sh
new file mode 100644
index 00000000000..fd1fc4cb76b
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_users.sh
@@ -0,0 +1,194 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load unittest
+task_load usergroup_mock
+task_load users
+
+# Mock platform_useradd() needed by usergroup.subr, and task_user_exists()
+# needed by users.subr.
+#
+platform_useradd()
+{
+ mock_useradd "$@"
+}
+
+task_user_exists()
+{
+ mock_user_exists "$@"
+}
+
+test_setup()
+{
+ : ${CAT:=cat}
+ : ${MKDIR:=mkdir}
+
+ PKG_DBDIR="${TEST_CURDIR}/var/db/pkg"
+ PKG_REFCOUNT_DBDIR="${PKG_DBDIR}.refcount"
+ ${MKDIR} -p "${PKG_DBDIR}"
+
+ ETC_GROUP="${TEST_CURDIR}/etc.group"
+ ETC_PASSWD="${TEST_CURDIR}/etc.passwd"
+ mock_usergroup_setup
+
+ datafile="datafile"
+ ${CAT} > $datafile << EOF
+# USER: userD:groupD
+# USER: userE:groupE:200
+# USER: userF:groupF:205
+EOF
+}
+
+test1()
+{
+ describe="check-add missing users"
+ if task_users check-add < $datafile; then
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="add nonexistent users"
+ if task_users add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ local name
+ for name in userD userE userF; do
+ if task_user_exists "$name"; then
+ : "success"
+ else
+ describe="$describe: missing $name"
+ return 1
+ fi
+ done
+ return 0
+}
+
+test3()
+{
+ describe="add existent and nonexistent users"
+ task_adduser userE groupE 200
+ if task_users add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ local name
+ for name in userD userE userF; do
+ if task_user_exists "$name"; then
+ : "success"
+ else
+ describe="$describe: missing $name"
+ return 1
+ fi
+ done
+ return 0
+}
+
+test4()
+{
+ describe="add conflicting user"
+ task_adduser userE groupE 300
+ if task_users add < $datafile; then
+ return 1
+ fi
+ return 0
+}
+
+test5()
+{
+ describe="check-add users with all users added"
+ task_users add < $datafile
+ if task_users check-add < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test6()
+{
+ describe="check-remove users with no users removed"
+ task_users add < $datafile
+ if task_users check-remove < $datafile; then
+ return 1
+ fi
+ return 0
+}
+
+test7()
+{
+ describe="remove existent users"
+ task_users add < $datafile
+ # This always returns 0 because no users are ever removed.
+ if task_users remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ local name
+ for name in userD userE userF; do
+ # No users should have been removed.
+ if task_user_exists "$name"; then
+ : "success"
+ else
+ describe="$describe: missing $name"
+ return 1
+ fi
+ done
+ return 0
+}
+
+test8()
+{
+ describe="remove nonexistent users"
+ # This always returns 0 because no users are ever removed.
+ if task_users remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+test9()
+{
+ describe="check-remove users with users already removed"
+ if task_users check-remove < $datafile; then
+ : "success"
+ else
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_valid_options.sh b/pkgtools/pkgtasks/files/t/t_valid_options.sh
new file mode 100644
index 00000000000..bf743e0c3b8
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_valid_options.sh
@@ -0,0 +1,95 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load valid_options
+task_load unittest
+
+test1()
+{
+ describe="valid substring"
+ task_valid_options "ab" "abcd."
+}
+
+test2()
+{
+ describe="valid first character"
+ task_valid_options "a" "abcd."
+}
+
+test3()
+{
+ describe="valid middle character"
+ task_valid_options "b" "abcd."
+}
+
+test4()
+{
+ describe="valid last character"
+ task_valid_options "." "abcd."
+}
+
+test5()
+{
+ describe="invalid substring"
+ if task_valid_options "abCD" "abcd."; then
+ return 1
+ fi
+}
+
+test6()
+{
+ describe="invalid first character"
+ if task_valid_options "Abc" "abcd."; then
+ return 1
+ fi
+}
+
+test7()
+{
+ describe="invalid middle character"
+ if task_valid_options "aBc" "abcd."; then
+ return 1
+ fi
+}
+
+test8()
+{
+ describe="invalid last character"
+ if task_valid_options "abD" "abcd."; then
+ return 1
+ fi
+}
+
+test9()
+{
+ describe="invalid only"
+ if task_valid_options "C" "abcd."; then
+ return 1
+ fi
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_version.sh b/pkgtools/pkgtasks/files/t/t_version.sh
new file mode 100644
index 00000000000..d1d8239ac3f
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_version.sh
@@ -0,0 +1,322 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load unittest
+task_load version 2>/dev/null || task_load -s ".subr.in" version
+
+test1()
+{
+ describe="1 < 1+1"
+ task_version_compare -v 1 1+1
+}
+
+test2()
+{
+ describe="1.0 < 1.0.1"
+ task_version_compare -v 1.0 1.0.1
+}
+
+test3()
+{
+ describe="1.23.2 < 1.23.11"
+ task_version_compare -v 1.23.2 1.23.11
+}
+
+test4()
+{
+ describe="1.2alpha < 1.2"
+ task_version_compare -v 1.2alpha 1.2
+}
+
+test5()
+{
+ describe="1.2alpha < 1.2alpha1"
+ task_version_compare -v 1.2alpha 1.2alpha1
+}
+
+test6()
+{
+ describe="1.2alpha2 < 1.2alpha11"
+ task_version_compare -v 1.2alpha2 1.2alpha11
+}
+
+test7()
+{
+ describe="1.2alpha < 1.2beta"
+ task_version_compare -v 1.2alpha 1.2beta
+}
+
+test8()
+{
+ describe="1.2alpha < 1.2rc"
+ task_version_compare -v 1.2alpha 1.2rc
+}
+
+test9()
+{
+ describe="1.2beta < 1.2rc"
+ task_version_compare -v 1.2beta 1.2rc
+}
+
+test10()
+{
+ describe="1.2alpha < 1.2e"
+ task_version_compare -v 1.2alpha 1.2e
+}
+
+test11()
+{
+ describe="1.2a < 1.2b"
+ task_version_compare -v 1.2a 1.2b
+}
+
+test12()
+{
+ describe="1.2a2 < 1.2a11"
+ task_version_compare -v 1.2a2 1.2a11
+}
+
+test13()
+{
+ describe="1.2rc1 < 1.2a"
+ task_version_compare -v 1.2rc1 1.2a
+}
+
+test14()
+{
+ describe="1.2 < 1.2+1"
+ task_version_compare -v 1.2 1.2+1
+}
+
+test15()
+{
+ describe="1.2alpha99 < 1.2+1"
+ task_version_compare -v 1.2alpha99 1.2+1
+}
+
+test16()
+{
+ describe="1.2+2 < 1.2+11"
+ task_version_compare -v 1.2+2 1.2+11
+}
+
+test17()
+{
+ describe="(null) < 1.0"
+ task_version_compare -v "" "1.0"
+}
+
+test18()
+{
+ describe="1.2.5 = 1.2e"
+ task_version_compare -v 1.2.5 1.2e
+ [ $? -eq 1 ]
+}
+
+test19()
+{
+ describe="1.0.0 = 1.0.0"
+ task_version_compare -v 1.0.0 1.0.0
+ [ $? -eq 1 ]
+}
+
+test20()
+{
+ describe="1.2.3 < 1abc2.3"
+ task_version_compare -v 1.2.3 1abc2.3
+}
+
+test21()
+{
+ describe="Bravo < Charlie"
+ task_version_compare -v Bravo Charlie
+}
+
+test22()
+{
+ describe="1.2+1 < 1.2.1"
+ task_version_compare -v 1.2+1 1.2.1
+}
+
+test23()
+{
+ describe="1_2_0 = 1.2.0"
+ task_version_compare -v 1_2_0 1.2.0
+ [ $? -eq 1 ]
+}
+
+test24()
+{
+ describe="1.2alpha < 1.2alpha+1"
+ task_version_compare -v 1.2alpha 1.2alpha+1
+}
+
+test25()
+{
+ describe="1.2~ < 1.2"
+ task_version_compare -v 1.2~ 1.2
+}
+
+test26()
+{
+ describe="1.2~alpha1 = 1.2alpha1"
+ task_version_compare -v 1.2~alpha1 1.2alpha1
+ [ $? -eq 1 ]
+}
+
+test27()
+{
+ describe="1.2~a1 < 1.2alpha1"
+ task_version_compare -v 1.2~a1 1.2alpha1
+}
+
+test28()
+{ describe="1.2~a~b < 1.2~a"
+ task_version_compare -v 1.2~a~b 1.2~a
+}
+
+test29()
+{
+ describe="1.2alpha1 < 1.2~b1"
+ task_version_compare -v 1.2alpha1 1.2~b1
+}
+
+test30()
+{
+ describe="~~ < ~"
+ task_version_compare -v "~~" "~"
+}
+
+test31()
+{
+ describe="~ < ~a"
+ task_version_compare -v "~" "~a"
+}
+
+test32()
+{
+ describe="version_check 1.2 >= 1.0"
+ task_version_check 1.2 ">=" 1.0
+}
+
+test33()
+{
+ describe="version_check 1.2 >= 2.0 is false"
+ if task_version_check 1.2 ">=" 2.0; then
+ return 1
+ fi
+}
+
+test34()
+{
+ describe="version_check 1.2 > 1.0"
+ task_version_check 1.2 ">" 1.0
+}
+
+test35()
+{
+ describe="version_check 1.2 > 2.0 is false"
+ if task_version_check 1.2 ">" 2.0; then
+ return 1
+ fi
+}
+
+test36()
+{
+ describe="version_check 1.2 = 1.2"
+ task_version_check 1.2 "=" 1.2
+}
+
+test37()
+{
+ describe="version_check 1.2 = 2.0 is false"
+ if task_version_check 1.2 "=" 2.0; then
+ return 1
+ fi
+}
+
+test38()
+{
+ describe="version_check 1.2 < 2.0"
+ task_version_check 1.2 "<" 2.0
+}
+
+test39()
+{
+ describe="version_check 1.2 < 1.0 is false"
+ if task_version_check 1.2 "<" 1.0; then
+ return 1
+ fi
+}
+
+test40()
+{
+ describe="version_check 1.2 <= 2.0"
+ task_version_check 1.2 "<=" 2.0
+}
+
+test41()
+{
+ describe="version_check 1.2 <= 1.0 is false"
+ if task_version_check 1.2 "<=" 1.0; then
+ return 1
+ fi
+}
+
+test42()
+{
+ describe="version_check 1.2 *"
+ task_version_check 1.2 "*" ""
+}
+
+test43()
+{
+ describe="version_check 1.2 >= 1.0 < 2.0"
+ task_version_check 1.2 ">=" 1.0 "<" 2.0
+}
+
+test44()
+{
+ describe="version_check 1.2 >= 1.0 < 1.1 is false"
+ if task_version_check 1.2 ">=" 1.0 "<" 1.1; then
+ return 1
+ fi
+}
+
+test45()
+{
+ describe="version_check Charlie < Delta"
+ task_version_check Charlie "<" Delta
+}
+
+test46()
+{
+ describe="version_check Delta > Charlie"
+ task_version_check Delta ">" Charlie
+}
+
+task_run_tests "$@"
diff --git a/pkgtools/pkgtasks/files/t/t_which.sh b/pkgtools/pkgtasks/files/t/t_which.sh
new file mode 100644
index 00000000000..be9e097490e
--- /dev/null
+++ b/pkgtools/pkgtasks/files/t/t_which.sh
@@ -0,0 +1,96 @@
+# Copyright (c) 2017 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Johnny C. Lam.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+task_load createfile
+task_load makedir
+task_load which
+task_load unittest
+
+test_setup()
+{
+ : ${CHMOD:=chmod}
+
+ task_makedir bin usr/bin
+ task_createfile bin/cmd1 usr/bin/cmd2
+ ${CHMOD} +x bin/cmd1 usr/bin/cmd2
+
+ TEST_PATH="${TEST_CURDIR}/bin:${TEST_CURDIR}/usr/bin"
+}
+
+test1()
+{
+ describe="cmd in first directory"
+ local expected value
+ expected="${TEST_CURDIR}/bin/cmd1"
+ value=$( PATH="${TEST_PATH}" task_which cmd1 )
+ if [ "$value" != "$expected" ]; then
+ echo "$value"
+ return 1
+ fi
+ return 0
+}
+
+test2()
+{
+ describe="cmd in second directory"
+ local expected value
+ expected="${TEST_CURDIR}/usr/bin/cmd2"
+ value=$( PATH="${TEST_PATH}" task_which cmd2 )
+ if [ "$value" != "$expected" ]; then
+ echo "$value"
+ return 1
+ fi
+ return 0
+}
+
+test3()
+{
+ describe="cmd in no directories"
+ local expected value
+ expected=""
+ value=$( PATH="${TEST_PATH}" task_which cmd3 )
+ if [ "$value" != "$expected" ]; then
+ echo "$value"
+ return 1
+ fi
+ return 0
+}
+
+test4()
+{
+ describe="empty cmd"
+ local expected value
+ expected=""
+ value="$( task_which '' )"
+ if [ "$value" != "$expected" ]; then
+ echo "$value"
+ return 1
+ fi
+ return 0
+}
+
+task_run_tests "$@"