commit - 9d3bc9e22e36abc872ea2082e4bad194d395cdf4
commit + 8256f5dffdca364cde5c43fcaa001bfe255f4fcd
blob - 78fc2082dc1554a3a5beb1ad0275fe109b350328
blob + 9446a3b3d20d03a46d354f149a677ed155005458
--- exercise
+++ exercise
# config options
set opts(-B) . ;# basedir
set opts(-j) 1 ;# number of concurrent jobs
+set opts(-n) 0 ;# dry run
set opts(-pd) {*} ;# pattern for test search directories
set opts(-ps) {*.ts} ;# pattern for test suite executable files
set opts(-pt) {*.t} ;# pattern for test executable files
# sequential operation. If set to non-blocking, an event handler should be set
# up that resumes the coroutine whenever the channel becomes readable. When
# the coroutine ends, the channel is closed and any event handler vanishes.
+# In dry runs, the routine terminates before executing the test and returns
+# a bogus result of "error", to signal only that no job was started.
proc execute_test {job basedir path} {
global opts counters
set args {}
# Pass stderr through when calling test suites.
set errfile @stderr
- # Pass -v(v) on to test suites.
- if {$opts(-v) > 0} {set args "-[string repeat v $opts(-v)] $args"}
+ # Pass -v(v) and -n on to test suites.
+ if {$opts(-v) > 0} {set args "-[string repeat v $opts(-v)] $args"}
+ if {$opts(-n)} {set args "-n $args"}
+ } elseif {$opts(-n)} {
+ # Dry run requested; stop here.
+ return error ;# dummy to signal we did not create a channel
} else {
# Capture stderr in a temporary file.
# Unfortunately, 'chan pipe' only appears in Tcl 8.6. :(
if {[info exists env(EXERCISEDIR)]} {set opts(-D) $env(EXERCISEDIR)}
# handle command line options
- set u {[-qv] [-B dir] [-C dir] [-D dir] [-j n] [-p k=pattern] [path ...]}
+ set u {[-nqv] [-B dir] [-C dir] [-D dir] [-j n] [-p k=pattern] [path ...]}
set prog [file tail $::argv0]
- while {[getopt argv {B:C:D:j:p:qv} opt arg]} {
+ while {[getopt argv {B:C:D:j:np:qv} opt arg]} {
if {$opt eq "?"} {
puts stderr "usage: $prog $u"
exit 1
exit 127
}
+ if {$opts(-n)} {exit 0} ;# dry run
exit [notok $counters]
}
blob - 24b4a6ffedbf654c6f198a9cc8b3e051a1f9450f
blob + ec62f029162839840dd8b1b2f2416f79e5bc8650
--- exercise.1
+++ exercise.1
.
.Sh SYNOPSIS
.Nm exercise
-.Op Fl qv
+.Op Fl nqv
.Op Fl B Ar dir
.Op Fl C Ar dir
.Op Fl D Ar dir
Execute up to
.Ar n
test jobs concurrently.
+.It Fl n
+Dry run.
+Do not execute the tests.
+Test suite executables
+.Em are
+called, with the
+.Fl n
+option passed on to them.
.It Fl p Sy d= Ns Ar pattern
When searching for tests,
only descend into directories that match the given pattern.
utility can be used as a (nested) test suite runner if desired.
.Pp
A test suite must admit the
+.Fl n
+and
.Fl v
-option.
-It may honor it by printing test names to its standard output,
+options.
+It must honor
+.Fl n
+by performing a dry run, reporting status as usual
+without actually executing any tests.
+In addition, it may honor the
+.Fl v
+option by printing test names to its standard output,
prefixed with
.Dq ". "
to distinguish them from regular status lines.
blob - 012ad1fc058bde22aa41aa231fb36d9baab8d986
blob + 63a4c86af485f4ff8efa935e36dadf3eeea2aae7
--- support/adapt-tst
+++ support/adapt-tst
# This script adapts a test suite that exposes the simple report protocol of
# test.h for use with exercise.
#
-# Usage: adapt-tst cmd [-v] [arg ...]
+# Usage: adapt-tst cmd [-nv] [arg ...]
#
# Example: Given a test suite in 'foo.tst.c' that is built into an executable
# 'foo.tst', create the script 'foo.ts' containing the following:
shift
# handle command line flags
+nflag=0
vflag=0
-while getopts v ch
+while getopts nv ch
do
case $ch in
+ n) nflag=1 ;;
v) vflag=$(($vflag + 1)) ;;
?) echo "usage: adapt-tst cmd [-v] [arg ...]"
esac
# clear the flag variables for the test executable
unset D V K X
-[ $vflag -ge 2 ] && export V=1
# determine the total number of tests by performing a dry run
D=1 "$cmd" "$@" >$tmp || exit 127
run=$(echo $(wc -l <$tmp))
+# was a dry run requested in the first place?
+if [ $nflag -eq 1 ]
+then
+ if [ $vflag -ge 1 ]
+ then
+ # just dump the test names
+ IFS=
+ while read -r line
+ do
+ echo ". $line"
+ done <$tmp
+ fi
+
+ # succeed with a plain count
+ echo "run $run ok 0 fail 0 error 0"
+ exit 0
+fi
+
+# let -vv set V, but not for dry runs
+[ $vflag -ge 2 ] && export V=1
+
# run the tests in the background, redirecting output to a fifo
rm -f $tmp
mkfifo $tmp || exit 127
blob - /dev/null
blob + 3d4dffafc2e6a23ee1786320e3ac01e1f57301c8 (mode 755)
--- /dev/null
+++ tests/exercise/flag/n.t
+#!/bin/sh
+
+set -e
+
+./assert-exercise $0 \
+ "run 1 ok 0 fail 0 error 0\n" \
+ '' \
+ -n <<EOF
+#!/bin/sh
+ exit 0
+EOF
+
+./assert-exercise $0 \
+ ". $0.tst\nrun 1 ok 0 fail 0 error 0\n" \
+ '' \
+ -nv <<EOF
+#!/bin/sh
+ exit 0
+EOF
+
+export tst=$0.ts
+./assert-exercise $0 \
+ "run 2 ok 0 fail 0 error 0\n" \
+ '' \
+ -n <<EOF
+#!/bin/sh
+ echo "run 2 ok 0 fail 0 error 0"
+ echo "run 2 ok 0 fail 0 error 0"
+ echo "run 2 ok 0 fail 0 error 0"
+ test "\$1" = "-n"
+EOF
+
+export tst=$0.ts
+./assert-exercise $0 \
+ ". $0.ts\n. . test1\n. . test2\nrun 2 ok 0 fail 0 error 0\n" \
+ '' \
+ -nv <<EOF
+#!/bin/sh
+ echo "run 2 ok 0 fail 0 error 0"
+ echo ". test1"
+ echo "run 2 ok 0 fail 0 error 0"
+ echo ". test2"
+ echo "run 2 ok 0 fail 0 error 0"
+ test "\$1" = "-n" -a "\$2" = "-v"
+EOF
+
+export tst=$0.ts
+./assert-exercise $0 \
+ ". $0.ts\n. . test1\n. . > hallo\nrun 1 ok 0 fail 0 error 0\n" \
+ '' \
+ -nvv <<EOF
+#!/bin/sh
+ echo "run 1 ok 0 fail 0 error 0"
+ echo ". test1"
+ echo ". > hallo"
+ echo "run 1 ok 0 fail 0 error 0"
+ test "\$1" = "-n" -a "\$2" = "-vv"
+EOF
blob - 366dc8f8ffb7e1bda6ee182c13795b2854bf6ba6
blob + ecdb3353b3508b43c2d7028dbf7a266ec4e00433
--- tests/support/adapt-tst.t
+++ tests/support/adapt-tst.t
#!/bin/sh
if [ -n "$D" ]
then
+ [ -n "$V" ] && echo "foo() -"
echo "test_1()"
echo "test_2()"
echo "test_3()"
#!/bin/sh
exec ../../support/adapt-tst $tmp "\$@"
EOF
+
+./assert-exercise $0 \
+ "run 3 ok 0 fail 0 error 0\n" \
+ '' \
+ -n \
+ <<-EOF
+ #!/bin/sh
+ exec ../../support/adapt-tst $tmp "\$@"
+ EOF
+
+./assert-exercise $0 \
+ ". $tst\n. . test_1()\n. . test_2()\n. . test_3()\n\
+run 3 ok 0 fail 0 error 0\n" \
+ '' \
+ -nv \
+ <<-EOF
+ #!/bin/sh
+ exec ../../support/adapt-tst $tmp "\$@"
+ EOF
+
+./assert-exercise $0 \
+ ". $tst\n. . test_1()\n\
+. . test_2()\n. . test_3()\nrun 3 ok 0 fail 0 error 0\n" \
+ '' \
+ -nvv \
+ <<-EOF
+ #!/bin/sh
+ exec ../../support/adapt-tst $tmp "\$@"
+ EOF