From 6a215246e0e2424ba652d0c377b216a2ecb2d226 Mon Sep 17 00:00:00 2001 From: Julio Merino Date: Mon, 6 Jan 2025 13:20:57 +0100 Subject: [PATCH] Allow setting the workdir when running processes Add the -w flag to shtk_process_run and shtk_unittest_assert_command so that the executed commands can use a different work directory than the current one. --- NEWS.md | 4 +++ man/shtk_process_run.3 | 15 +++++++++- man/shtk_unittest_assert_command.3 | 16 ++++++++++- process.subr | 19 +++++++++++-- process_test.sh | 44 ++++++++++++++++++++++++++++++ unittest/commands.subr | 19 ++++++++++--- unittest/commands_test.sh | 12 ++++++++ 7 files changed, 120 insertions(+), 9 deletions(-) diff --git a/NEWS.md b/NEWS.md index a2ba409..a4fcf8b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -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. diff --git a/man/shtk_process_run.3 b/man/shtk_process_run.3 index df8ee92..3da0c99 100644 --- a/man/shtk_process_run.3 +++ b/man/shtk_process_run.3 @@ -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 @@ -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 @@ -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. @@ -74,3 +81,9 @@ The flag appeared in .Nm shtk 1.5. +.Pp +The +.Fl w +flag appeared in +.Nm shtk +1.8. diff --git a/man/shtk_unittest_assert_command.3 b/man/shtk_unittest_assert_command.3 index ac69ede..ea28be2 100644 --- a/man/shtk_unittest_assert_command.3 +++ b/man/shtk_unittest_assert_command.3 @@ -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 @@ -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 @@ -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 @@ -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. diff --git a/process.subr b/process.subr index f92d3f2..defac07 100644 --- a/process.subr +++ b/process.subr @@ -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" @@ -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 @@ -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. diff --git a/process_test.sh b/process_test.sh index 5738648..400a954 100644 --- a/process_test.sh +++ b/process_test.sh @@ -72,6 +72,28 @@ EOF } +shtk_unittest_add_test run__workdir__ok +run__workdir__ok_test() { + mkdir tmp + cat >tmp/helper.sh <expout <experr <helper.sh <tmp/helper.sh <expout <experr <helper.sh <"${actual_stdout}" 2>"${actual_stderr}" @@ -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 @@ -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) ;; @@ -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 @@ -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}" \ @@ -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 diff --git a/unittest/commands_test.sh b/unittest/commands_test.sh index 3b5cd56..04d4e30 100644 --- a/unittest/commands_test.sh +++ b/unittest/commands_test.sh @@ -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 ) \