Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Changes in version 1.8
user can now pass the names of the tests to be run on the command line
via the `-t` flag and the test program will only execute those tests.

* Added the `-w` option to `shtk_process_run` and
`shtk_unittest_assert_command` to allow running commands under different
directories than the current one.

* Migrated to using Automake to run shtk's own test suite instead of Kyua.


Expand Down
15 changes: 14 additions & 1 deletion man/shtk_process_run.3
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
.\" 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.
.Dd November 7, 2014
.Dd January 6, 2025
.Dt SHTK_PROCESS_RUN 3
.Os
.Sh NAME
Expand All @@ -36,6 +36,7 @@ shtk_import run
.Sh SYNOPSIS
.Nm
.Op Fl t Ar seconds
.Op Fl w Ar work_dir
.Ar command
.Op Ar arg1 .. argN
.Sh DESCRIPTION
Expand All @@ -47,6 +48,12 @@ and logs, using the logging functions offered by
.Xr shtk_cli 3 ,
the invocation of the command and its termination status.
.Pp
The command given to
.Nm
is executed in the current directory, unless the
.Fl w Ar work_dir
flag is used to specify a different work directory.
.Pp
Optionally,
.Nm
can enforce a maximum run time for the executed command.
Expand Down Expand Up @@ -74,3 +81,9 @@ The
flag appeared in
.Nm shtk
1.5.
.Pp
The
.Fl w
flag appeared in
.Nm shtk
1.8.
16 changes: 15 additions & 1 deletion man/shtk_unittest_assert_command.3
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
.\" 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.
.Dd November 10, 2014
.Dd January 6, 2025
.Dt SHTK_UNITTEST_ASSERT_COMMAND 3
.Os
.Sh NAME
Expand All @@ -38,6 +38,7 @@ shtk_import unittest
.Op Fl e output_spec
.Op Fl o output_spec
.Op Fl s exit_code_spec
.Op Fl w work_dir
.Ar command Op arg1 .. argN
.Sh DESCRIPTION
The
Expand All @@ -52,6 +53,13 @@ is the most versatile check offered by
.Xr shtk_unittest 3
and should be used to validate the majority of the executions performed
by test cases.
.Pp
The command given to
.Nm
is executed in the current directory unless a different directory is specified
via the
.Fl w Ar work_dir
flag.
.Ss Exit checks
The
.Fl s
Expand Down Expand Up @@ -152,3 +160,9 @@ assert_command -s exit:42 -o inline:"sent to stdout\\n" \\
first appeared in
.Nm shtk
1.6.
.Pp
The
.Fl w Ar work_dir
flag was added in
.Nm shtk
1.8.
19 changes: 16 additions & 3 deletions process.subr
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,19 @@ shtk_import cli

shtk_process_run() {
local timeout=
local workdir=

local OPTIND
while getopts ':t:' arg "${@}"; do
while getopts ':t:w:' arg "${@}"; do
case "${arg}" in
t) # Timeout.
timeout="${OPTARG}"
;;

w) # Work directory.
workdir="${OPTARG}"
;;

:)
shtk_cli_error "Missing argument to option -${OPTARG} in" \
"shtk_process_run"
Expand All @@ -58,7 +63,11 @@ shtk_process_run() {
local ret=
if [ -z "${timeout}" ]; then
ret=0
"${@}" || ret="${?}"
if [ "${workdir}" = . ]; then
"${@}" || ret="${?}"
else
( cd "${workdir}" && "${@}" ) || ret="${?}"
fi
else
# Spawning a process with a timeout is tricky because we have to spawn
# two subprocesses: one to run the actual process and one to act as a
Expand Down Expand Up @@ -98,7 +107,11 @@ shtk_process_run() {

(
local ret=0
"${@}" || ret="${?}"
if [ "${workdir}" = . ]; then
"${@}" || ret="${?}"
else
( cd "${workdir}" && "${@}" ) || ret="${?}"
fi
kill -9 "${watchdog}"
while [ -z "$(cat "${cookie}")" ]; do
# Race protection: the parent has not yet written the cookie.
Expand Down
44 changes: 44 additions & 0 deletions process_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,28 @@ EOF
}


shtk_unittest_add_test run__workdir__ok
run__workdir__ok_test() {
mkdir tmp
cat >tmp/helper.sh <<EOF
#! /bin/sh
echo "This exits cleanly:" "\${@}"
exit 0
EOF
chmod +x tmp/helper.sh

cat >expout <<EOF
This exits cleanly: one two three
EOF
cat >experr <<EOF
process_test: I: Running './helper.sh one two three' in $(pwd)/tmp
process_test: I: Command finished successfully
EOF
expect_command -o file:expout -e file:experr -w tmp \
shtk_process_run ./helper.sh one two three
}


shtk_unittest_add_test run__timeout__ok
run__timeout__ok_test() {
cat >helper.sh <<EOF
Expand All @@ -93,6 +115,28 @@ EOF
}


shtk_unittest_add_test run__timeout__workdir__ok
run__timeout__workdir__ok_test() {
mkdir tmp
cat >tmp/helper.sh <<EOF
#! /bin/sh
echo "This exits quickly:" "\${@}"
exit 0
EOF
chmod +x tmp/helper.sh

cat >expout <<EOF
This exits quickly: one two three
EOF
cat >experr <<EOF
process_test: I: Running './helper.sh one two three' in $(pwd)/tmp
process_test: I: Command finished successfully
EOF
expect_command -o file:expout -e file:experr -w tmp \
shtk_process_run -t 10 ./helper.sh one two three
}


shtk_unittest_add_test run__timeout__fail
run__timeout__fail_test() {
cat >helper.sh <<EOF
Expand Down
19 changes: 15 additions & 4 deletions unittest/commands.subr
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,25 @@ _shtk_unittest_check_command_do_run() {
local actual_stderr="${1}"; shift

local OPTIND
while getopts ':e:o:s:' arg "${@}"; do
local workdir=.
while getopts ':e:o:s:w:' arg "${@}"; do
case "${arg}" in
e) ;;
o) ;;
s) ;;
w) workdir="${OPTARG}" ;;
\?) shtk_cli_error "getopts list out of sync; internal error" ;;
esac
done
shift $((${OPTIND} - 1))
OPTIND=1 # Should not be necessary due to the 'local' above.

if [ "${workdir}" != . ]; then
actual_stdout="$(pwd)/${actual_stdout}"
actual_stderr="$(pwd)/${actual_stderr}"
cd "${workdir}"
fi

echo "Running checked command: ${*}"

"${@}" >"${actual_stdout}" 2>"${actual_stderr}"
Expand Down Expand Up @@ -91,12 +99,13 @@ _shtk_unittest_check_command() {

# First pass through the options: make sure they are valid.
local OPTIND
while getopts ':e:o:s:' arg "${@}"; do
while getopts ':e:o:s:w:' arg "${@}"; do
case "${arg}" in
# TODO(jmmv): Might be nice to validate argument values early.
e) ;;
o) ;;
s) ;;
w) ;;
\?) shtk_cli_error "Invalid option -${OPTARG} to ${wrapper}" ;;
esac
done
Expand All @@ -114,7 +123,7 @@ _shtk_unittest_check_command() {

# Second pass through the options: execute any given -s checks.
local exit_code_done=no
while getopts ':e:o:s:' arg "${@}"; do
while getopts ':e:o:s:w:' arg "${@}"; do
case "${arg}" in
e) ;;
o) ;;
Expand All @@ -123,6 +132,7 @@ _shtk_unittest_check_command() {
"${actual_exit_code}" || failed=yes
exit_code_done=yes
;;
w) ;;
\?) shtk_cli_error "getopts list out of sync; internal error" ;;
esac
done
Expand All @@ -142,7 +152,7 @@ _shtk_unittest_check_command() {
local stdout_done=no stderr_done=no

# Third pass through the options: execute any given -o and -e checks.
while getopts ':e:o:s:' arg "${@}"; do
while getopts ':e:o:s:w:' arg "${@}"; do
case "${arg}" in
e) # Expected stderr behavior.
_shtk_unittest_check_file "${wrapper}" false "${OPTARG}" \
Expand All @@ -155,6 +165,7 @@ _shtk_unittest_check_command() {
stdout_done=yes
;;
s) ;;
w) ;;
\?) shtk_cli_error "getopts list out of sync; internal error" ;;
esac
done
Expand Down
12 changes: 12 additions & 0 deletions unittest/commands_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,18 @@ EOF
}


shtk_unittest_add_test change_workdir
change_workdir_test() {
mkdir tmp
echo "expected contents" >tmp/data1
echo "expected contents" >tmp/data2
( shtk_unittest_assert_command -w tmp -o file:tmp/data2 cat data1 \
>out 2>err ) || fail "Failed to validate successful command"
expect_file inline:"Running checked command: cat data1\n" out
expect_file empty err
}


shtk_unittest_add_test unknown_flag
unknown_flag_test() {
( shtk_unittest_assert_command -Z foo >out 2>err ) \
Expand Down
Loading