commit 991d115e68a80435a0bfeee4268cb569e606c259 from: Sven M. Hallberg date: Mon Jul 21 11:31:41 2025 UTC add -x option (exit on failed test) commit - 8256f5dffdca364cde5c43fcaa001bfe255f4fcd commit + 991d115e68a80435a0bfeee4268cb569e606c259 blob - 9446a3b3d20d03a46d354f149a677ed155005458 blob + 3add364e7c31d76d06a05ee5f42d84b7fe8b7d62 --- exercise +++ exercise @@ -16,6 +16,7 @@ set opts(-ps) {*.ts} ;# pattern for test su set opts(-pt) {*.t} ;# pattern for test executable files set opts(-q) 0 ;# quiet mode set opts(-v) 0 ;# verbose mode +set opts(-x) 0 ;# exit on failed test # executing tests @@ -54,9 +55,10 @@ proc execute_test {job basedir path} { # Pass stderr through when calling test suites. set errfile @stderr - # Pass -v(v) and -n on to test suites. - if {$opts(-v) > 0} {set args "-[string repeat v $opts(-v)] $args"} + # Pass -n, -v(v), and -x(x) on to test suites. if {$opts(-n)} {set args "-n $args"} + if {$opts(-v) > 0} {set args "$args -[string repeat v $opts(-v)]"} + if {$opts(-x) > 0} {set args "$args -[string repeat x $opts(-x)]"} } elseif {$opts(-n)} { # Dry run requested; stop here. return error ;# dummy to signal we did not create a channel @@ -279,6 +281,12 @@ proc inconsistent {counters} { } } +proc failed {counters} { + dict with counters { + expr {$fail > 0 || $error > 0} + } +} + proc notok {counters} { dict with counters { expr {[inconsistent $counters] || $ok != $run} @@ -448,9 +456,9 @@ proc main {argc argv} { if {[info exists env(EXERCISEDIR)]} {set opts(-D) $env(EXERCISEDIR)} # handle command line options - set u {[-nqv] [-B dir] [-C dir] [-D dir] [-j n] [-p k=pattern] [path ...]} + set u {[-nqvx] [-B dir] [-C dir] [-D dir] [-j n] [-p k=pattern] [path ...]} set prog [file tail $::argv0] - while {[getopt argv {B:C:D:j:np:qv} opt arg]} { + while {[getopt argv {B:C:D:j:np:qvx} opt arg]} { if {$opt eq "?"} { puts stderr "usage: $prog $u" exit 1 @@ -476,8 +484,8 @@ proc main {argc argv} { set opt p$k set arg $v } - if {$opt eq "v"} { - set arg [expr $opts(-v) + 1] ;# increment + if {$opt eq "v" || $opt eq "x"} { + set arg [expr $opts(-$opt) + 1] ;# increment } set opts(-$opt) $arg } @@ -508,6 +516,9 @@ proc main {argc argv} { # wait for a slot to become available while {$J >= $opts(-j)} {vwait J} + # exit after a test failure if requested with -x + if {$opts(-x) && [failed $counters]} break + # start job set job job[incr i] set chan [coroutine $job execute_test $job $basedir $file] blob - ec62f029162839840dd8b1b2f2416f79e5bc8650 blob + c298a3d1a1fe836f8baa0723a17e0829349ebe3c --- exercise.1 +++ exercise.1 @@ -8,7 +8,7 @@ . .Sh SYNOPSIS .Nm exercise -.Op Fl nqv +.Op Fl nqvx .Op Fl B Ar dir .Op Fl C Ar dir .Op Fl D Ar dir @@ -104,6 +104,10 @@ Print the name of each test to standard output precede If given twice, also print any test standard output with an additional level of quoting using .Dq "> " . +This flag is passed on to test suites. +.It Fl x +Exit immediately after a test failure or error. +This flag is passed on to test suites. .El . .Ss Test Files @@ -138,10 +142,11 @@ Consequently, the .Nm utility can be used as a (nested) test suite runner if desired. .Pp -A test suite must admit the -.Fl n +A test suite must accept the +.Fl n , +.Fl v and -.Fl v +.Fl x options. It must honor .Fl n @@ -159,6 +164,14 @@ is given, more diagnostics may be printed which, by convention, should be prefixed with .Dq ". >" (period, space, greater-than). +The +.Fl x +option should cause the test suite to exit after a test failure +if it would normally continue. +Given +.Fl xx , +it may exit even earlier, +i.e. on the first failed condition within a test. .Pp After running a test suite, its final report is checked for consistency. If any of the conditions (listed below) are not satisfied, blob - 63a4c86af485f4ff8efa935e36dadf3eeea2aae7 blob + 9e6c71d8e143191a39ebc3acfa8309aa69d8ae54 --- support/adapt-tst +++ support/adapt-tst @@ -18,12 +18,14 @@ shift # handle command line flags nflag=0 vflag=0 -while getopts nv ch +xflag=0 +while getopts nvx ch do case $ch in n) nflag=1 ;; v) vflag=$(($vflag + 1)) ;; - ?) echo "usage: adapt-tst cmd [-v] [arg ...]" + x) xflag=$(($xflag + 1)) ;; + ?) echo "usage: adapt-tst cmd [-nvx] [arg ...]" esac done shift $(($OPTIND - 1)) @@ -60,8 +62,10 @@ then exit 0 fi -# let -vv set V, but not for dry runs +# let -vv set V (but not for dry runs) [ $vflag -ge 2 ] && export V=1 +# let -xx set X (-x is already our normal behavior) +[ $xflag -ge 2 ] && export X=1 # run the tests in the background, redirecting output to a fifo rm -f $tmp blob - 3d4dffafc2e6a23ee1786320e3ac01e1f57301c8 blob + ba29b3f3e0985b91b3d29d15e6c346d1b489df7f --- tests/exercise/flag/n.t +++ tests/exercise/flag/n.t @@ -3,8 +3,8 @@ set -e ./assert-exercise $0 \ - "run 1 ok 0 fail 0 error 0\n" \ - '' \ + "run 1 ok 0 fail 0 error 0\n" \ + '' \ -n < hallo\nrun 1 ok 0 fail 0 error 0\n" \ - '' \ + ". $0.ts\n. . test1\n. . > hallo\nrun 1 ok 0 fail 0 error 0\n" \ + '' \ -nvv <$tmp <<-"EOF" [ -n "$V" ] && echo " bemerke auch" echo "test_2() OK" echo "something something unexpected" >&2 + [ -n "$X" ] && exit 1 echo "test_3() FAIL" exit 1 fi @@ -80,3 +81,11 @@ run 3 ok 0 fail 0 error 0\n" \ #!/bin/sh exec ../../support/adapt-tst $tmp "\$@" EOF + +./assert-exercise $0 \ + "run 3 ok 2 fail 0 error 0\n" \ + "something something unexpected\nfail $tst\n\n" \ + -xx <<-EOF + #!/bin/sh + exec ../../support/adapt-tst $tmp "\$@" + EOF