diff options
Diffstat (limited to 'tests/test')
20 files changed, 2022 insertions, 114 deletions
diff --git a/tests/test/config-test/driver.cxx b/tests/test/config-test/driver.cxx index 5902854..7ea10e7 100644 --- a/tests/test/config-test/driver.cxx +++ b/tests/test/config-test/driver.cxx @@ -3,6 +3,9 @@ #include <iostream> +#undef NDEBUG +#include <cassert> + using namespace std; int diff --git a/tests/test/script/builtin/sleep.testscript b/tests/test/script/builtin/sleep.testscript index 21ed07b..c044027 100644 --- a/tests/test/script/builtin/sleep.testscript +++ b/tests/test/script/builtin/sleep.testscript @@ -6,3 +6,21 @@ : success : $c <'sleep 1' && $b + +: timeout +: +{ + : failure + : + $c <'env -t 1 -- sleep 86400' && $b 2>>~%EOE% != 0 + %testscript:.*: error: builtin sleep terminated: execution timeout expired% + %. + EOE + + : success + : + $c <<EOI && $b + timeout --success 1; + sleep 86400 + EOI +} diff --git a/tests/test/script/common.testscript b/tests/test/script/common.testscript index 4469d1c..651e056 100644 --- a/tests/test/script/common.testscript +++ b/tests/test/script/common.testscript @@ -31,7 +31,7 @@ end # Note that the buildfile is clever hack that relies on the first target # automatically becoming dir{./}'s prerequisite. # -c = cat >=testscript -b = $0 --no-default-options --serial-stop --quiet --buildfile - test \ +c = [cmdline] cat >=testscript +b = [cmdline] $0 --no-default-options --serial-stop --quiet --buildfile - test \ <"'testscript{testscript}: \$target'" \ &?test/*** diff --git a/tests/test/script/runner/cleanup.testscript b/tests/test/script/runner/cleanup.testscript index 03153e4..4638982 100644 --- a/tests/test/script/runner/cleanup.testscript +++ b/tests/test/script/runner/cleanup.testscript @@ -75,7 +75,7 @@ b += --no-column : Test cleanup of a directory as a file. : $c <'$* -d a &a' && $b 2>>/~%EOE% != 0 - %error: unable to remove file test/1/a: .+% + %testscript:1: error: unable to remove file test/1/a: .+% info: test id: 1 EOE } @@ -161,7 +161,7 @@ b += --no-column : Test cleanup of a file as a directory. : $c <'$* -f a &a/' && $b 2>>/~%EOE% != 0 - %error: unable to remove directory test/1/a/: .+% + %testscript:1: error: unable to remove directory test/1/a/: .+% info: test id: 1 EOE } @@ -240,7 +240,7 @@ b += --no-column : Test cleanup of a file as a wildcard. : $c <'$* -f a &a/***' && $b 2>>/~%EOE% != 0 - %error: unable to remove directory test/1/a/: .*% + %testscript:1: error: unable to remove directory test/1/a/: .*% info: test id: 1 EOE } diff --git a/tests/test/script/runner/driver.cxx b/tests/test/script/runner/driver.cxx index d5a74a4..b84f167 100644 --- a/tests/test/script/runner/driver.cxx +++ b/tests/test/script/runner/driver.cxx @@ -1,19 +1,29 @@ // file : tests/test/script/runner/driver.cxx -*- C++ -*- // license : MIT; see accompanying LICENSE file +#ifndef _WIN32 +# include <thread> // this_thread::sleep_for() +# include <chrono> +#else +# include <libbutl/win32-utility.hxx> +#endif + #include <limits> // numeric_limits #include <string> #include <cstdlib> // abort() -#include <cassert> #include <ostream> // endl, *bit #include <istream> // istream::traits_type::eof() #include <iostream> #include <exception> -#include <libbutl/path.mxx> -#include <libbutl/optional.mxx> -#include <libbutl/fdstream.mxx> -#include <libbutl/filesystem.mxx> +#include <libbutl/path.hxx> +#include <libbutl/path-io.hxx> +#include <libbutl/optional.hxx> +#include <libbutl/fdstream.hxx> +#include <libbutl/filesystem.hxx> + +#undef NDEBUG +#include <cassert> using namespace std; using namespace butl; @@ -36,10 +46,10 @@ main (int argc, char* argv[]) // Usage: driver [-i <int>] (-o <string>)* (-e <string>)* (-f <file>)* // (-d <dir>)* (-v <name>)* [(-t (a|m|s|z)) | (-s <int>)] // - // Execute actions specified by -i, -o, -e, -f, -d, and -v options in the - // order as they appear on the command line. After that terminate abnormally - // if -t option is provided, otherwise exit normally with the status - // specified by -s option (0 by default). + // Execute actions specified by -i, -o, -e, -f, -d, -w, -v, and -l options + // in the order as they appear on the command line. After that terminate + // abnormally if -t option is provided, otherwise exit normally with the + // status specified by -s option (0 by default). // // -i <fd> // Forward stdin data to the standard stream denoted by the file @@ -58,9 +68,15 @@ main (int argc, char* argv[]) // Create a directory with the path specified. Create parent directories // if required. // + // -w + // Print CWD to stdout. + // // -v <name> - // If the specified variable is set the print its value to stdout and the - // string '<none>' otherwise. + // If the specified variable is set then print its value to stdout and + // the string '<none>' otherwise. + // + // -l <sec> + // Sleep the specified number of seconds. // // -t <method> // Abnormally terminate itself using one of the following methods: @@ -83,10 +99,7 @@ main (int argc, char* argv[]) for (int i (1); i < argc; ++i) { - string o (argv[i++]); - assert (i < argc); - - string v (argv[i]); + string o (argv[i]); auto toi = [] (const string& s) -> int { @@ -106,57 +119,80 @@ main (int argc, char* argv[]) return r; }; - if (o == "-i") + if (o == "-w") { - assert (ifd == 3); // Make sure is not set yet. - - ifd = toi (v); - assert (ifd >= 0 && ifd < 3); + cout << dir_path::current_directory () << endl; + } + else // Handle options other than flags. + { + ++i; + assert (i < argc); + string v (argv[i]); - if (ifd == 0) - cin.ignore (numeric_limits<streamsize>::max ()); - else if (cin.peek () != istream::traits_type::eof ()) + if (o == "-i") { - ostream& o (ifd == 1 ? cout : cerr); - o << cin.rdbuf (); - o.flush (); + assert (ifd == 3); // Make sure is not set yet. + + ifd = toi (v); + assert (ifd >= 0 && ifd < 3); + + if (ifd == 0) + cin.ignore (numeric_limits<streamsize>::max ()); + else if (cin.peek () != istream::traits_type::eof ()) + { + ostream& o (ifd == 1 ? cout : cerr); + o << cin.rdbuf (); + o.flush (); + } } + else if (o == "-o") + { + cout << v << endl; + } + else if (o == "-e") + { + cerr << v << endl; + } + else if (o == "-f") + { + ofdstream os (v); + os.close (); + } + else if (o == "-d") + { + try_mkdir_p (dir_path (v)); + } + else if (o == "-v") + { + optional<string> var (getenv (v)); + cout << (var ? *var : "<none>") << endl; + } + else if (o == "-l") + { + size_t t (toi (v)); + + // MinGW GCC 4.9 doesn't implement this_thread so use Win32 Sleep(). + // +#ifndef _WIN32 + this_thread::sleep_for (chrono::seconds (t)); +#else + Sleep (static_cast<DWORD> (t * 1000)); +#endif + } + else if (o == "-t") + { + assert (aterm == '\0' && !status); // Make sure exit method is not set. + assert (v.size () == 1 && v.find_first_of ("amsz") != string::npos); + aterm = v[0]; + } + else if (o == "-s") + { + assert (!status && aterm == '\0'); // Make sure exit method is not set. + status = toi (v); + } + else + assert (false); } - else if (o == "-o") - { - cout << v << endl; - } - else if (o == "-e") - { - cerr << v << endl; - } - else if (o == "-f") - { - ofdstream os (v); - os.close (); - } - else if (o == "-d") - { - try_mkdir_p (dir_path (v)); - } - else if (o == "-v") - { - optional<string> var (getenv (v)); - cout << (var ? *var : "<none>") << endl; - } - else if (o == "-t") - { - assert (aterm == '\0' && !status); // Make sure exit method is not set. - assert (v.size () == 1 && v.find_first_of ("amsz") != string::npos); - aterm = v[0]; - } - else if (o == "-s") - { - assert (!status && aterm == '\0'); // Make sure exit method is not set. - status = toi (v); - } - else - assert (false); } switch (aterm) diff --git a/tests/test/script/runner/env.testscript b/tests/test/script/runner/env.testscript index 6fcedfa..512139a 100644 --- a/tests/test/script/runner/env.testscript +++ b/tests/test/script/runner/env.testscript @@ -3,5 +3,64 @@ .include ../common.testscript -$c <'env abc=xyz -- $* -v abc >xyz' && $b : set -$c <'env --unset=abc -- $* -v abc >"<none>"' && env abc=xyz -- $b : unset +: cwd +: +{ + : not-exist + : + $c <'env -c a -- $* -w' && $b 2>>/~%EOE% != 0 + %testscript:1:1: error: specified working directory .+/a/ does not exist% + info: test id: 1 + EOE + + : process + : + $c <<EOI && $b + mkdir a; + env -c a -- $* -w >/~%.+/a% + EOI + + : builtin + : + $c <<EOI && $b + mkdir a; + env -c a -- touch b; + test -f a/b + EOI + + : absolute + : + $c <<EOI && $b + mkdir a; + env -c $~/a -- touch b; + test -f a/b + EOI +} + +: variables +: +{ + $c <'env abc=xyz -- $* -v abc >xyz' && $b : set + $c <'env --unset=abc -- $* -v abc >"<none>"' && env abc=xyz -- $b : unset +} + +: timeout +: +{ + : expired + : + $c <'env --timeout 1 -- $* -l 5' && $b 2>>~%EOE% != 0 + %testscript:1:1: error: .+ terminated: execution timeout expired% + info: test id: 1 + EOE + + : not-expired + : + $c <'env --timeout 5 -- $* -l 1' && $b + + : invalid + : + $c <'env --timeout a -- $*' && $b 2>>EOE != 0 + testscript:1:15: error: env: invalid value 'a' for option '--timeout' + EOE +} diff --git a/tests/test/script/runner/exit.testscript b/tests/test/script/runner/exit.testscript index 24e51fa..8d3f052 100644 --- a/tests/test/script/runner/exit.testscript +++ b/tests/test/script/runner/exit.testscript @@ -76,7 +76,7 @@ empty_id = '' : unexpected : $c <'exit "foo" "bar"' && $b 2>>EOE != 0 - testscript:1:1: error: unexpected argument 'bar' + testscript:1:1: error: exit: unexpected argument 'bar' info: test id: 1 EOE } diff --git a/tests/test/script/runner/export.testscript b/tests/test/script/runner/export.testscript new file mode 100644 index 0000000..6ed7417 --- /dev/null +++ b/tests/test/script/runner/export.testscript @@ -0,0 +1,138 @@ +# file : tests/test/script/runner/export.testscript +# license : MIT; see accompanying LICENSE file + +.include ../common.testscript + +# Make sure that the foo variable, which may potentially be set in the build2 +# environment, doesn't affect the tests. +# ++export --unset foo + +: group +: +{ + : add + : + $c <<EOI && $b + { + +export foo=bar + + $* -v foo >'bar' + } + EOI + + : change + : + $c <<EOI && $b + { + +export foo=bar + +export foo=baz + + $* -v foo >'baz' + } + EOI + + : remove + : + $c <<EOI && $b + { + +export foo=bar + +export --unset foo + + $* -v foo >'<none>' + } + EOI + + : clear + : + { + : added + : + $c <<EOI && $b + { + +export foo=bar + +export --clear foo + + $* -v foo >'<none>' + } + EOI + + : removed + : + $c <<EOI && $b + { + +export foo=bar + +export --unset foo + +export --clear foo + + $* -v foo >'<none>' + } + EOI + + : non-existent + : + $c <<EOI && $b + { + +export --clear foo + + $* -v foo >'<none>' + } + EOI + } + + : override + : + $c <<EOI && $b + +export foo=bar + + { + +export --unset foo + + export foo=baz; + $* -v foo >'baz' + + -$* -v foo >'<none>' + } + + -$* -v foo >'bar' + EOI +} + +: test +: +{ + : override + : + $c <<EOI && $b + { + export foo=bar; + env foo=baz -- $* -v foo >'baz'; + $* -v foo >'bar' + } + EOI +} + +: invalid +: +{ + : set + : + $c <'export foo' && $b 2>>~%EOE% != 0 + testscript:1:1: error: export: expected variable assignment instead of 'foo' + %.+ + EOE + + : unset + : + $c <'export --unset foo=abc' && $b 2>>~%EOE% != 0 + testscript:1:1: error: export: invalid value 'foo=abc' for option -u|--unset: contains '=' + %.+ + EOE + + : clear + : + $c <'export --clear foo=abc' && $b 2>>~%EOE% != 0 + testscript:1:1: error: export: invalid value 'foo=abc' for option -c|--clear: contains '=' + %.+ + EOE +} diff --git a/tests/test/script/runner/expr.testscript b/tests/test/script/runner/expr.testscript index 98e495f..95d4bed 100644 --- a/tests/test/script/runner/expr.testscript +++ b/tests/test/script/runner/expr.testscript @@ -20,7 +20,7 @@ true = '$* >| -o' false = '$* -s 1 >| -o' - bf = $b 2>- + bf = [cmdline] $b 2>- : true : diff --git a/tests/test/script/runner/for.testscript b/tests/test/script/runner/for.testscript new file mode 100644 index 0000000..f43fcc2 --- /dev/null +++ b/tests/test/script/runner/for.testscript @@ -0,0 +1,502 @@ +# File : tests/test/script/runner/for.testscript +# license : MIT; see accompanying LICENSE file + +.include ../common.testscript + +: form-1 +: +: for x: ... +: +{ + : basics + : + $c <<EOI && $b >>EOO + for x: a b + echo "$x" >| + end + EOI + a + b + EOO + + : test-options + : + $c <<EOI && $b >>~%EOO% + for test.options: -a -b + echo $* >| + end + EOI + %.+ -a% + %.+ -b% + EOO + + : special-var + : + $c <<EOI && $b 2>>EOE != 0 + for ~: -a -b + echo $~ >| + end + EOI + testscript:1:5: error: attempt to set '~' variable directly + EOE + + : exit + : + $c <<EOI && $b >>EOO + for x: a b + echo "$x" >| + exit + end + EOI + a + EOO + + : error + : + $c <<EOI && $b >>EOO 2>>EOE != 0 + for x: a b + echo "$x" >| + exit 'fed up' + end + EOI + a + EOO + testscript:3:3: error: fed up + info: test id: 1 + EOE +} + +: form-2 +: +: ... | for x +: +{ + : whitespace-split + : + $c <<EOI && $b >>EOO + echo " a b " | for -w x + echo "'$x'" >| + end + EOI + 'a' + 'b' + EOO + + : newline-split + : + $c <<EOI && $b >>EOO + cat <<EOF | for -n x + + + a + + + b + + EOF + echo "'$x'" >| + end + EOI + '' + '' + 'a' + '' + '' + 'b' + '' + EOO + + : typed + : + $c <<EOI && $b >>/EOO + echo "a b" | for -w x [dir_path] + echo $x >| + end + EOI + a/ + b/ + EOO + + : nested + : + $c <<EOI && $b >>EOO + echo "a b" | for -w x + echo "x y" | for -w y + echo "'$x $y'" >| + end + end + EOI + 'a x' + 'a y' + 'b x' + 'b y' + EOO + + : nested-diag + : + $c <<EOI && $b 2>>/~%EOE% != 0 + echo "a b" | for -w x + echo "x y" | for -w y + echo "'$x $y'" >"'a x'" + end + end + EOI + testscript:3:5: error: echo stdout doesn't match expected + info: stdout: test/1/stdout-i1-i2-n3 + info: expected stdout: test/1/stdout-i1-i2-n3.orig + info: stdout diff: test/1/stdout-i1-i2-n3.diff + %.+ + EOE + + : nested-diag-test-id + : + $c <<EOI && $b 2>>EOE != 0 + echo "a b" | for -w x + echo "x y" | for -w y + test -f $x$y + end + end + EOI + testscript:3:5: error: builtin test exited with code 1 + info: test id: 1 + EOE + + : var-value + : + $c <<EOI && $b >>EOO + x = 'x'; + echo "a b" | for -w x + end; + echo $x >| + EOI + b + EOO + + : both-sep-options + : + $c <<EOI && $b 2>>/~%EOE% != 0 + echo "a b" | for -n -w x + echo $x >| + end + EOI + testscript:1:1: error: for: both -n|--newline and -w|--whitespace specified + %.+ + EOE + + : invalid-option + : + $c <<EOI && $b 2>>/~%EOE% != 0 + echo "a b" | for -a x + echo $x >| + end + EOI + testscript:1:1: error: for: unknown option '-a' + %.+ + EOE + + : no-variable + : + $c <<EOI && $b 2>>/~%EOE% != 0 + echo "a b" | for -w + echo $x >| + end + EOI + testscript:1:1: error: for: missing variable name + %.+ + EOE + + : special-var + : + $c <<EOI && $b 2>>EOE != 0 + echo "a b" | for -w ~ + echo $* >| + end + EOI + testscript:1:1: error: attempt to set '~' variable directly + info: test id: 1 + EOE + + : unsep-attrs + : + $c <<EOI && $b 2>>EOE != 0 + echo "a b" | for -w x[string] + echo $x >| + end + EOI + testscript:1:1: error: for: expected variable name instead of x[string] + info: test id: 1 + EOE + + : misuse + : + { + : after-var + : + $c <<EOI && $b 2>>EOE != 0 + echo "a b" | for v: + echo $v >| + end + EOI + testscript:1:19: error: expected newline instead of ':' + EOE + + : after-attrs + : + $c <<EOI && $b 2>>EOE != 0 + echo "a b" | for v [string]: + echo $v >| + end + EOI + testscript:1:28: error: expected newline instead of ':' + EOE + } + + : exit + : + $c <<EOI && $b >>EOO + echo "a b" | for x + echo "$x" >| + exit + end + EOI + a + EOO + + : error + : + $c <<EOI && $b >>EOO 2>>EOE != 0 + echo "a b" | for x + echo "$x" >| + exit 'fed up' + end + EOI + a + EOO + testscript:3:3: error: fed up + info: test id: 1 + EOE +} + +: form-3 +: +: for x <... +: +{ + : whitespace-split + : + $c <<EOI && $b >>EOO + for -w x <" a b " + echo "'$x'" >| + end + EOI + 'a' + 'b' + EOO + + : quoted-opt + : + $c <<EOI && $b >>EOO + o = -n + for "$o" x <<EOF + a + b + EOF + echo "'$x'" >| + end; + for "($o)" x <<EOF + c + d + EOF + echo "'$x'" >| + end + EOI + 'a' + 'b' + 'c' + 'd' + EOO + + : newline-split + : + $c <<EOI && $b >>EOO + for -n x <<EOF + + + a + + + b + + EOF + echo "'$x'" >| + end + EOI + '' + '' + 'a' + '' + '' + 'b' + '' + EOO + + : string-before-var + : + $c <<EOI && $b >>EOO + for <"a b" -w x + echo "'$x'" >| + end + EOI + 'a' + 'b' + EOO + + : here-doc-before-var + : + $c <<EOI && $b >>EOO + for <<EOF -n x + a + b + EOF + echo "'$x'" >| + end + EOI + 'a' + 'b' + EOO + + : typed + : + $c <<EOI && $b >>/EOO + for -w x [dir_path] <"a b" + echo $x >| + end + EOI + a/ + b/ + EOO + + : typed-no-ops + : + $c <<EOI && $b >>/EOO + for x [dir_path] <"a b" + echo $x >| + end + EOI + a/ + b/ + EOO + + : nested + : + $c <<EOI && $b >>EOO + for -w x <"a b" + for -w y <"x y" + echo "'$x $y'" >| + end + end + EOI + 'a x' + 'a y' + 'b x' + 'b y' + EOO + + : nested-diag + : + $c <<EOI && $b 2>>/~%EOE% != 0 + for -w x <"a b" + for -w y <"x y" + echo "'$x $y'" >"'a x'" + end + end + EOI + testscript:3:5: error: echo stdout doesn't match expected + info: stdout: test/1/stdout-i1-i2-n3 + info: expected stdout: test/1/stdout-i1-i2-n3.orig + info: stdout diff: test/1/stdout-i1-i2-n3.diff + %.+ + EOE + + : nested-diag-test-id + : + $c <<EOI && $b 2>>EOE != 0 + for -w x <"a b" + for -w y <"x y" + test -f $x$y + end + end + EOI + testscript:3:5: error: builtin test exited with code 1 + info: test id: 1 + EOE + + : var-value + : + $c <<EOI && $b >>EOO + x = 'x'; + for -w x <"a b" + end; + echo $x >| + EOI + b + EOO + + : invalid-option + : + $c <<EOI && $b 2>>/~%EOE% != 0 + for -a x <"a b" + echo $x >| + end + EOI + testscript:1:1: error: for: unknown option '-a' + %. + EOE + + + : no-variable + : + $c <<EOI && $b 2>>/~%EOE% != 0 + for -w <"a b" + echo $x >| + end + EOI + testscript:1:1: error: for: missing variable name + %. + EOE + + : special-var + : + $c <<EOI && $b 2>>EOE != 0 + for ~ <"a b" + echo $~ >| + end + EOI + testscript:1:5: error: attempt to set '~' variable directly + EOE + + : exit + : + $c <<EOI && $b >>EOO + for x <"a b" + echo "$x" >| + exit + end + EOI + a + EOO + + : error + : + $c <<EOI && $b >>EOO 2>>EOE != 0 + for x <"a b" + echo "$x" >| + exit 'fed up' + end + EOI + a + EOO + testscript:3:3: error: fed up + info: test id: 1 + EOE +} diff --git a/tests/test/script/runner/pipe.testscript b/tests/test/script/runner/pipe.testscript index 205fd55..cdd30a6 100644 --- a/tests/test/script/runner/pipe.testscript +++ b/tests/test/script/runner/pipe.testscript @@ -6,7 +6,6 @@ $c <'cat <foo | $* -i 1 >foo' && $b : builtin-to-process $c <'$* -o foo | cat >foo' && $b : process-to-builtin - : failure : : Note that while both commands for the pipe are faulty the diagnostics for @@ -15,19 +14,28 @@ $c <'$* -o foo | cat >foo' && $b : process-to-builtin { : exit-code : - $c <'$* -o foo -s 1 | $* -i 1 >foo -s 2' && $b 2>>/~%EOE% != 0 - %testscript:1:1: error: .+ exited with code 2% - info: stdout: test/1/stdout-2 + : Also verify that the command line is printed. + : + $c <'$* -o foo -s 1 | $* -i 1 -s 2 >foo' && $b --verbose 1 2>>/~%EOE% != 0 + %. + %testscript:1:1: error: process .+ exited with code 1% + % info: command line: .+driver.* -o foo -s 1% + info: test id: 1 + %. + %testscript:1:1: error: process .+ exited with code 2% + % info: command line: .+driver.* -i 1 -s 2% + info: stdout: test/1/stdout-c2 info: test id: 1 + %.{2} EOE : stderr : $c <'$* -o foo -e foo 2>bar | $* -i 2 2>baz' && $b 2>>/~%EOE% != 0 %testscript:1:1: error: .+ stderr doesn't match expected% - info: stderr: test/1/stderr-2 - info: expected stderr: test/1/stderr-2.orig - info: stderr diff: test/1/stderr-2.diff + info: stderr: test/1/stderr-c2 + info: expected stderr: test/1/stderr-c2.orig + info: stderr diff: test/1/stderr-c2.diff %.{3} -baz +foo diff --git a/tests/test/script/runner/redirect.testscript b/tests/test/script/runner/redirect.testscript index 0fe3aa3..209c4ce 100644 --- a/tests/test/script/runner/redirect.testscript +++ b/tests/test/script/runner/redirect.testscript @@ -654,9 +654,9 @@ psr = ($cxx.target.class != 'windows' ? '/' : '\\') # Path separator in regex. $* -o bar >?out EOI %testscript:2: error: ../../../../../driver(.exe)? stdout doesn't match expected% - info: stdout: test/1/stdout-2 + info: stdout: test/1/stdout-n2 info: expected stdout: test/1/out - info: stdout diff: test/1/stdout-2.diff + info: stdout diff: test/1/stdout-n2.diff %--- \.*% %\+\+\+ \.*% %@@ \.*% diff --git a/tests/test/script/runner/set.testscript b/tests/test/script/runner/set.testscript index 9219cbb..1800a7d 100644 --- a/tests/test/script/runner/set.testscript +++ b/tests/test/script/runner/set.testscript @@ -52,7 +52,7 @@ : both-newline-whitespace : $c <'set -nw' && $b 2>>EOE != 0 - testscript:1:1: error: both -n|--newline and -w|--whitespace specified + testscript:1:1: error: set: both -n|--newline and -w|--whitespace specified info: test id: 1 EOE } @@ -63,28 +63,28 @@ : none : $c <'set -e' && $b 2>>EOE != 0 - testscript:1:1: error: missing variable name + testscript:1:1: error: set: missing variable name info: test id: 1 EOE : unexpected : $c <'set foo bar baz' && $b 2>>EOE != 0 - testscript:1:1: error: unexpected argument 'baz' + testscript:1:1: error: set: unexpected argument 'baz' info: test id: 1 EOE : empty-attrs : - $c <"set '' baz" && $b 2>>EOE != 0 - testscript:1:1: error: empty variable attributes + $c <"set baz ''" && $b 2>>EOE != 0 + testscript:1:1: error: set: empty variable attributes info: test id: 1 EOE : empty-var : $c <"set ''" && $b 2>>EOE != 0 - testscript:1:1: error: empty variable name + testscript:1:1: error: set: empty variable name info: test id: 1 EOE } @@ -94,10 +94,28 @@ { : non-exact : - $c <<EOI && $b - set -w baz <' foo bar '; - echo $baz >'foo bar' - EOI + { + : non-empty + : + $c <<EOI && $b + set -w baz <' foo bar '; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"foo" "bar"' + EOI + + : empty + : + $c <<EOI && $b + set -w baz <:''; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'' + EOI + + : spaces + : + $c <<EOI && $b + set -w baz <' '; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'' + EOI + } : exact : @@ -106,7 +124,7 @@ : $c <<EOI && $b set --exact --whitespace baz <' foo bar '; - echo $baz >'foo bar ' + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"foo" "bar" ""' EOI : no-trailing-ws @@ -115,8 +133,22 @@ : ':' modifier. : $c <<EOI && $b - set --exact --whitespace baz <:' foo bar'; - echo $baz >'foo bar' + set -e -w baz <:' foo bar'; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"foo" "bar"' + EOI + + : empty + : + $c <<EOI && $b + set -e -w baz <:''; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'' + EOI + + : spaces + : + $c <<EOI && $b + set -e -w baz <' '; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'""' EOI } } @@ -134,7 +166,7 @@ bar EOF - echo $baz >' foo bar ' + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"" "foo" "" "bar" ""' EOI : exact @@ -150,7 +182,7 @@ bar EOF - echo $baz >' foo bar ' + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"" "foo" "" "bar" "" ""' EOI : no-trailing-newline @@ -162,7 +194,7 @@ bar EOF - echo $baz >' foo bar' + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"" "foo" "" "bar"' EOI } } @@ -180,7 +212,7 @@ bar EOF - echo $baz >>EOO + echo ($baz[0]) >>EOO foo @@ -209,7 +241,7 @@ bar EOF - echo "$baz" >>EOO + echo ($baz[0]) >>EOO foo @@ -227,7 +259,7 @@ bar EOF - echo "$baz" >>EOO + echo ($baz[0]) >>EOO foo @@ -237,20 +269,291 @@ } } +: special-vars +: +{ + $c <<EOI && $b + set -w test.options <'-o foo'; + $* >'foo' + EOI +} + +: deadline +: +{ + : not-reached + : + $c <<EOI && $b + env -t 10 -- $* -o 'foo' | set bar; + echo "$bar" >'foo' + EOI + + : non-pipe + : + $c <<EOI && $b + env -t 10 -- set bar <'foo'; + echo "$bar" >'foo' + EOI + + : set-reached + : + $c <<EOI && $b 2>>~%EOE% != 0 + $* -o 'foo' -l 10 | env -t 1 -- set bar + EOI + %testscript:.*: error: .+driver.* terminated: execution timeout expired% + %. + EOE + + : driver-reached + : + $c <<EOI && $b 2>>~%EOE% != 0 + env -t 1 -- $* -o 'foo' -l 10 | set bar + EOI + %testscript:.*: error: .+driver.* terminated: execution timeout expired% + %. + EOE + + : read-some-data + : + { + s="----------------------------------------------------------------------" + s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s" + s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s" + + : failure + : + $c <<EOI && $b 2>>~%EOE% != 0 + echo "$s" >=f; + $* -o 'foo' -l 10 | cat f - | env -t 2 -- set bar + EOI + %testscript:.*: error: process .+driver.* terminated: execution timeout expired% + %. + %testscript:.*: error: builtin cat terminated: execution timeout expired% + %. + EOE + + : success + : + $c <<EOI && $b + echo "$s" >=f; + timeout --success 2; + + # Suppress cat's 'broken pipe' diagnostics. + # + $* -o 'foo' -l 10 | cat f - 2>- | set bar + EOI + } + + : split + : + : Test various splitting modes as above, but now reading the stream in the + : non-blocking mode. + : + { + : whitespace-separated-list + : + { + : non-exact + : + { + : non-empty + : + $c <<EOI && $b + timeout 10; + set -w baz <' foo bar '; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"foo" "bar"' + EOI + + : empty + : + $c <<EOI && $b + timeout 10; + set -w baz <:''; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'' + EOI + + : spaces + : + $c <<EOI && $b + timeout 10; + set -w baz <' '; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'' + EOI + } + + : exact + : + { + : trailing-ws + : + $c <<EOI && $b + timeout 10; + set --exact --whitespace baz <' foo bar '; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"foo" "bar" ""' + EOI + + : no-trailing-ws + : + : Note that we need to strip the default trailing newline as well with the + : ':' modifier. + : + $c <<EOI && $b + timeout 10; + set -e -w baz <:' foo bar'; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"foo" "bar"' + EOI + + : empty + : + $c <<EOI && $b + timeout 10; + set -e -w baz <:''; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'' + EOI + + : spaces + : + $c <<EOI && $b + timeout 10; + set -e -w baz <' '; + echo $regex.apply($baz, '^(.*)$', '"\1"') >'""' + EOI + } + } + + : newline-separated-list + : + { + : non-exact + : + $c <<EOI && $b + timeout 10; + set -n baz <<EOF; + + foo + + bar + + EOF + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"" "foo" "" "bar" ""' + EOI + + : exact + : + { + : trailing-newline + : + $c <<EOI && $b + timeout 10; + set --exact --newline baz <<EOF; + + foo + + bar + + EOF + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"" "foo" "" "bar" "" ""' + EOI + + : no-trailing-newline + : + $c <<EOI && $b + timeout 10; + set --exact --newline baz <<:EOF; + + foo + + bar + EOF + echo $regex.apply($baz, '^(.*)$', '"\1"') >'"" "foo" "" "bar"' + EOI + } + } + + : string + : + { + : non-exact + : + $c <<EOI && $b + timeout 10; + set baz <<EOF; + + foo + + bar + + EOF + echo ($baz[0]) >>EOO + + foo + + bar + + EOO + EOI + + : exact + : + : Note that echo adds the trailing newline, so EOF and EOO here-documents + : differ by this newline. + : + { + : trailing-newline + : + $c <<EOI && $b + timeout 10; + set -e baz <<EOF; + + foo + + bar + EOF + echo ($baz[0]) >>EOO + + foo + + bar + + EOO + EOI + + : no-trailing-newline + : + $c <<EOI && $b + timeout 10; + set -e baz <<:EOF; + + foo + + bar + EOF + echo ($baz[0]) >>EOO + + foo + + bar + EOO + EOI + } + } + } +} + : attributes : { : dir_path : $c <<EOI && $b - set [dir_path] bar <'foo'; + set bar [dir_path] <'foo'; echo $bar >/'foo/' EOI : null : $c <<EOI && $b - set [null] foo <-; + set foo [null] <-; echo $foo >'' EOI @@ -268,7 +571,7 @@ : empty-brackets : $c <<EOI && $b 2>>EOE != 0 - set -w '[]' baz <'foo bar'; + set -w baz '[]' <'foo bar'; echo "$baz" EOI testscript:2:8: error: concatenating variable expansion contains multiple values @@ -277,7 +580,7 @@ : no-left-bracket : $c <<EOI && $b 2>>EOE != 0 - set -w x baz + set -w baz x EOI <attributes>:1:1: error: expected '[' instead of 'x' testscript:1:1: info: while parsing attributes 'x' @@ -287,7 +590,7 @@ : unknown : $c <<EOI && $b 2>>EOE != 0 - set -w [x] baz + set -w baz [x] EOI <attributes>:1:1: error: unknown value attribute x testscript:1:1: info: while parsing attributes '[x]' @@ -297,7 +600,7 @@ : junk : $c <<EOI && $b 2>>EOE != 0 - set -w '[string] x' baz + set -w baz '[string] x' EOI <attributes>:1:10: error: trailing junk after ']' testscript:1:1: info: while parsing attributes '[string] x' diff --git a/tests/test/script/runner/status.testscript b/tests/test/script/runner/status.testscript index e4586d9..461fd5c 100644 --- a/tests/test/script/runner/status.testscript +++ b/tests/test/script/runner/status.testscript @@ -15,7 +15,7 @@ b += --no-column : false : $c <'$* -s 1 == 0' && $b 2>>/~%EOE%d != 0 - %testscript:1: error: ../../../../driver(.exe)? exit code 1 != 0% + %testscript:1: error: process ../../../../driver(.exe)? exit code 1 != 0% info: test id: 1 EOE } @@ -30,7 +30,7 @@ b += --no-column : false : $c <'$* -s 1 != 1' && $b 2>>/~%EOE% != 0 - %testscript:1: error: ../../../../driver(.exe)? exit code 1 == 1% + %testscript:1: error: process ../../../../driver(.exe)? exit code 1 == 1% info: test id: 1 EOE } @@ -38,7 +38,7 @@ b += --no-column : error : $c <'$* -s 1 -e "Error"' && $b 2>>/~%EOE% != 0 -%testscript:1: error: ../../../driver(.exe)? exited with code 1% +%testscript:1: error: process ../../../driver(.exe)? exited with code 1% info: stderr: test/1/stderr Error info: test id: 1 @@ -47,7 +47,7 @@ EOE : error-check : $c <'$* -s 1 -e "Error" == 0' && $b 2>>/~%EOE% != 0 -%testscript:1: error: ../../../driver(.exe)? exit code 1 != 0% +%testscript:1: error: process ../../../driver(.exe)? exit code 1 != 0% info: stderr: test/1/stderr Error info: test id: 1 diff --git a/tests/test/script/runner/test-runner.testscript b/tests/test/script/runner/test-runner.testscript new file mode 100644 index 0000000..372330b --- /dev/null +++ b/tests/test/script/runner/test-runner.testscript @@ -0,0 +1,57 @@ +# file : tests/test/script/runner/test-runner.testscript +# license : MIT; see accompanying LICENSE file + +.include ../common.testscript + ++if ($cxx.target.class == 'windows') + exit +end + ++cat <<EOI >=run + #!/bin/sh + if test "$1" = "--trace"; then + shift + echo "$*" + fi + "$@" + EOI + ++chmod u+x run + +run=$~/run + +: basic +: +$c <<EOI && $b "config.test.runner=$run --trace" + +cat <'text' >'text' # Non-test program. + + +$* -o 'text' >>~%EOO% # Test program. + %.+/driver -o text% + text + EOO + + { + prog = $0 + test=cat + + +cat <'text' >>EOO # Test program. + cat + text + EOO + + +$prog -o 'text' >>~%EOO% # Non-test program. + text + EOO + + test=$prog + + { + cat <'text' >'text'; # Non-test program. + + $* -o 'text' >>~%EOO% # Test program. + %.+/driver -o text% + text + EOO + } + } + EOI diff --git a/tests/test/script/runner/timeout.testscript b/tests/test/script/runner/timeout.testscript new file mode 100644 index 0000000..f9b6ec7 --- /dev/null +++ b/tests/test/script/runner/timeout.testscript @@ -0,0 +1,521 @@ +# file : tests/test/script/runner/timeout.testscript +# license : MIT; see accompanying LICENSE file + +.include ../common.testscript + +: test +: +{ + : fragment-timeout + : + { + : set + : + $c <<EOI && $b 2>>~%EOE% != 0 + timeout 1; + $* -l 3 + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : reset + : + $c <<EOI && $b + timeout 1; + timeout 0; + $* -l 3 + EOI + + : override + : + $c <<EOI && $b 2>>~%EOE% != 0 + +timeout /10 + + { + +timeout /10 + + timeout 1; + env -t 10 -- $* -l 3 + } + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : successful + : + $c <<EOI && $b + timeout --success 1; + $* -l 3 + EOI + } + + : missing + : + $c <'timeout' && $b 2>>~%EOE% != 0 + testscript:1:1: error: timeout: missing timeout + %. + EOE + + : invalid + : + $c <'timeout foo' && $b 2>>~%EOE% != 0 + testscript:1:1: error: timeout: invalid test fragment timeout 'foo' + %. + EOE +} + +: group +: +{ + : group-timeout + : + { + : set + : + $c <<EOI && $b 2>>~%EOE% != 0 + { + +timeout 1 + + $* -l 3 + } + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : reset + : + $c <<EOI && $b + { + +timeout 1 + +timeout 0 + + $* -l 3 + } + EOI + + : override + : + : Also test slash usage inside the timeout value. + : + $c <<EOI && $b 2>>~%EOE% != 0 + +timeout 10/10 + + { + +timeout 1/ + + timeout 10; + env -t 10 -- $* -l 3 + } + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : invalid + : + $c <<EOI && $b 2>>~%EOE% != 0 + { + +timeout foo/ + } + EOI + testscript:2:4: error: timeout: invalid test group timeout 'foo' + %. + EOE + } + + : test-timeout + : + { + : set + : + $c <<EOI && $b 2>>~%EOE% != 0 + { + +timeout /1 + + $* -l 3 + } + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : reset + : + $c <<EOI && $b + { + +timeout /1 + +timeout /0 + + $* -l 3 + } + EOI + + : override + : + $c <<EOI && $b 2>>~%EOE% != 0 + +timeout 10/10 + + { + +timeout /1 + + timeout 10; + env -t 10 -- $* -l 3 + } + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : invalid + : + $c <<EOI && $b 2>>~%EOE% != 0 + { + +timeout /foo + } + EOI + testscript:2:4: error: timeout: invalid test timeout 'foo' + %. + EOE + } +} + +: script +: +{ + : group-timeout + : + { + : set + : + $c <<EOI && $b 2>>~%EOE% != 0 + +timeout 1 + + $* -l 3 + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : reset + : + $c <<EOI && $b + +timeout 1 + +timeout 0 + + $* -l 3 + EOI + + : override + : + $c <<EOI && $b 2>>~%EOE% != 0 + +timeout 1 + + { + +timeout 10 + + timeout 10; + env -t 10 -- $* -l 3 + } + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : invalid + : + $c <<EOI && $b 2>>~%EOE% != 0 + +timeout foo/ + EOI + testscript:1:2: error: timeout: invalid testscript timeout 'foo' + %. + EOE + + : successful + : + $c <<EOI && $b + +timeout --success 1 + + $* -l 3 + EOI + } + + : test-timeout + : + { + : set + : + $c <<EOI && $b 2>>~%EOE% != 0 + +timeout /1 + + $* -l 3 + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : reset + : + $c <<EOI && $b + +timeout /1 + +timeout /0 + + $* -l 3 + EOI + + : override + : + $c <<EOI && $b 2>>~%EOE% != 0 + +timeout /1 + + { + +timeout --success /1 + + { + +timeout 10/10 + + timeout 10; + env -t 10 -- $* -l 3 + } + } + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : successful + : + $c <<EOI && $b + +timeout --success /1 + + $* -l 3 + EOI + + : invalid + : + $c <<EOI && $b 2>>~%EOE% != 0 + { + +timeout /foo + } + EOI + testscript:2:4: error: timeout: invalid test timeout 'foo' + %. + EOE + } +} + +: config +: +{ + : operation + : + { + : set + : + $c <<EOI && $b config.test.timeout=1 2>>~%EOE% != 0 + timeout 10; + $* -l 3 + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : reset + : + $c <<EOI && $b config.test.timeout=1 config.test.timeout=0/10 + timeout 10; + $* -l 3 + EOI + + : override + : + $c <<EOI && $b config.test.timeout=1/10 2>>~%EOE% != 0 + +timeout 10 + + { + +timeout 10/10 + + timeout 10; + env -t 10 -- $* -l 3 + } + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : invalid + : + $c && $b config.test.timeout=foo 2>>EOE != 0 + error: invalid config.test.timeout test operation timeout value 'foo' + EOE + } + + : test + : + { + : set + : + $c <<EOI && $b config.test.timeout=/1 2>>~%EOE% != 0 + timeout 10; + $* -l 3 + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : reset + : + $c <<EOI && $b config.test.timeout=/1 config.test.timeout=10/0 + timeout 10; + $* -l 3 + EOI + + : override + : + $c <<EOI && $b config.test.timeout=10/1 2>>~%EOE% != 0 + +timeout 10 + + { + +timeout 10/10 + + timeout 10; + env -t 10 -- $* -l 3 + } + EOI + %testscript:.*: error: .+ terminated: execution timeout expired% + %. + EOE + + : invalid + : + $c && $b config.test.timeout=/foo 2>>EOE != 0 + error: invalid config.test.timeout test timeout value 'foo' + EOE + } +} + +: failures +: +: Here we test that the left-hand side processes are terminated on failure. +: +{ + : set + : + $c <<EOI && $b 2>>~%EOE% != 0 + env -t 1 -- $* -l 86400 -o 'foo' | set --foo bar + EOI + %testscript:.*: error: set: unknown option '--foo'% + %. + EOE + + : exit + : + $c <<EOI && $b 2>>~%EOE% != 0 + env -t 1 -- $* -l 86400 -o 'foo' | exit 0 + EOI + %testscript:.*: error: exit builtin must be the only pipe command% + %. + EOE + + : redirect + : + $c <<EOI && $b 2>>~%EOE% != 0 + env -t 1 -- $* -l 86400 -o 'foo' | touch $~/foo/bar + EOI + %testscript:.*: error: process .+driver.* terminated: execution timeout expired% + %. + %testscript:.*: error: builtin touch exited with code 1% + %.+ + EOE +} + +: pipeline +: +{ + : prog-tm-prog + : + $c <'$* -l 10 | env -t 1 -- $* -i 0' && $b 2>>~%EOE% != 0 + %testscript:.*: error: process .+driver.* terminated: execution timeout expired% + %. + %testscript:.*: error: process .+driver.* terminated: execution timeout expired% + %. + EOE + + : tm-prog-prog + : + $c <'env -t 1 -- $* -l 10 | $* -i 0' && $b 2>>~%EOE% != 0 + %testscript:.*: error: process .+driver.* terminated: execution timeout expired% + %. + %testscript:.*: error: process .+driver.* terminated: execution timeout expired% + %. + EOE + + : tm-cat-prog + : + $c <'env -t 3 -- cat <"test" | $* -l 10' && $b 2>>~%EOE% != 0 + %testscript:.*: error: builtin cat terminated: execution timeout expired% + %. + %testscript:.*: error: process .+driver.* terminated: execution timeout expired% + %. + EOE + + : cat-tm-prog + : + $c <'cat <"test" | env -t 1 -- $* -l 10' && $b 2>>~%EOE% != 0 + %testscript:.*: error: builtin cat terminated: execution timeout expired% + %. + %testscript:.*: error: process .+driver.* terminated: execution timeout expired% + %. + EOE + + : tm-prog-cat + : + $c <'env -t 1 -- $* -l 10 | cat >-' && $b 2>>~%EOE% != 0 + %testscript:.*: error: process .+driver.* terminated: execution timeout expired% + %. + %testscript:.*: error: builtin cat terminated: execution timeout expired% + %. + EOE + + : tm-echo-prog + : + $c <'env -t 3 -- echo "test" | $* -l 10' && $b 2>>~%EOE% != 0 + %testscript:.*: error: builtin echo terminated: execution timeout expired% + %. + %testscript:.*: error: process .+driver.* terminated: execution timeout expired% + %. + EOE + + : successful + : + { + : prog-prog + : + $c <<EOI && $b + timeout --success 1; + $* -l 10 | $* -i 0 + EOI + + : prog-cat + : + $c <<EOI && $b + timeout --success 1; + $* -l 10 | cat + EOI + + : cat-prog + : + $c <<EOI && $b + s="----------------------------------------------------------------------"; + s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s"; + s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s"; + s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s"; + timeout --success 1; + cat <"$s" 2>>~%EOE% | $* -l 10 -i 0 + %cat: unable to print stdin: .+% + EOE + EOI + } +} diff --git a/tests/test/script/runner/while.testscript b/tests/test/script/runner/while.testscript new file mode 100644 index 0000000..1c58827 --- /dev/null +++ b/tests/test/script/runner/while.testscript @@ -0,0 +1,16 @@ +# file : tests/test/script/runner/while.testscript +# license : MIT; see accompanying LICENSE file + +.include ../common.testscript + +: basics +: +$c <<EOI && $b >>EOO + while ($v != "aa") + echo "$v" >| + v = "$(v)a" + end + EOI + + a + EOO diff --git a/tests/test/simple/generated/buildfile b/tests/test/simple/generated/buildfile index 0809bdf..0344891 100644 --- a/tests/test/simple/generated/buildfile +++ b/tests/test/simple/generated/buildfile @@ -6,4 +6,5 @@ ./: testscript exe{driver} $b file{*.in} -exe{driver}: cxx{driver} +import libs = libbutl%lib{butl} +exe{driver}: cxx{driver} $libs diff --git a/tests/test/simple/generated/driver.cxx b/tests/test/simple/generated/driver.cxx index 1d911df..ca6dfcb 100644 --- a/tests/test/simple/generated/driver.cxx +++ b/tests/test/simple/generated/driver.cxx @@ -1,30 +1,71 @@ // file : tests/test/simple/generated/driver.cxx -*- C++ -*- // license : MIT; see accompanying LICENSE file +#ifndef _WIN32 +# include <chrono> +# include <thread> +#else +# include <libbutl/win32-utility.hxx> +#endif + #include <string> #include <fstream> #include <iostream> +#undef NDEBUG +#include <cassert> + using namespace std; +// If the -s option is specified, then also sleep for 5 seconds. +// int main (int argc, char* argv[]) { + int i (1); + for (; i != argc; ++i) + { + string a (argv[i]); + + if (a == "-s") + { + // MINGW GCC 4.9 doesn't implement this_thread so use Win32 Sleep(). + // +#ifndef _WIN32 + this_thread::sleep_for (chrono::seconds (5)); +#else + Sleep (5000); +#endif + } + else + break; + } + int r (0); - if (argc == 1) + if (i == argc) { cout << "1.2.3" << endl; } else { - ifstream ifs (argv[1]); + istream* is; + ifstream ifs; + + if (argv[i] != string ("-")) + { + ifs.open (argv[i]); + + if (!ifs.is_open ()) + cerr << "unable to open " << argv[1] << endl; - if (!ifs.is_open ()) - cerr << "unable to open " << argv[1] << endl; + is = &ifs; + } + else + is = &cin; string s; - r = getline (ifs, s) && s == "1.2.3" ? 0 : 1; + r = getline (*is, s) && s == "1.2.3" ? 0 : 1; } return r; diff --git a/tests/test/simple/generated/testscript b/tests/test/simple/generated/testscript index a04dccc..49ddbbd 100644 --- a/tests/test/simple/generated/testscript +++ b/tests/test/simple/generated/testscript @@ -42,3 +42,208 @@ driver = $src_root/../exe{driver} ./: file{output}: test.stdout = true file{output}: in{output} $src_root/manifest #@@ in module EOI + +: output-mismatch +: +{ + # Get rid of --serial-stop --quiet. + # + test.options = $regex.apply($test.options, '^(--serial-stop|--quiet)$', '') + + : verbose-0 + : + { + echo '1.2.3' >=input; + echo '3.4.5' >=output; + $* -q <<EOI 2>>/~%EOE% != 0 + driver = $src_root/../exe{driver} + ./: test = $driver + ./: $driver + ./: test.arguments = '-' + ./: file{input}: test.stdin = true + ./: file{output}: test.stdout = true + EOI + %.+ + -3.4.5 + error: test dir{./} failed + error: process diff exited with code 1 + EOE + } + + : verbose-1 + : + { + echo '1.2.3' >=input; + echo '3.4.5' >=output; + $* <<EOI 2>>/~%EOE% != 0 + driver = $src_root/../exe{driver} + ./: test = $driver + ./: $driver + ./: test.arguments = '-' + ./: file{input}: test.stdin = true + ./: file{output}: test.stdout = true + EOI + test dir{./} + %.+ + -3.4.5 + error: test dir{./} failed + error: process diff exited with code 1 + % info: test command line: cat .+/input \| .+/driver.* - \| diff -u .+% + info: while testing dir{./} + info: failed to test dir{./} + EOE + } + + : verbose-2 + : + { + echo '1.2.3' >=input; + echo '3.4.5' >=output; + $* --verbose 2 <<EOI 2>>/~%EOE% != 0 + driver = $src_root/../exe{driver} + ./: test = $driver + ./: $driver + ./: test.arguments = '-' + ./: file{input}: test.stdin = true + ./: file{output}: test.stdout = true + EOI + %cat .+/input \| .+/driver.* - \| diff -u .+% + %.+ + -3.4.5 + error: test dir{./} failed + error: process diff exited with code 1 + info: while testing dir{./} + info: failed to test dir{./} + EOE + } + + : verbose-3 + : + { + echo '1.2.3' >=input; + echo '3.4.5' >=output; + $* --verbose 3 <<EOI 2>>/~%EOE% != 0 + driver = $src_root/../exe{driver} + ./: test = $driver + ./: $driver + ./: test.arguments = '-' + ./: file{input}: test.stdin = true + ./: file{output}: test.stdout = true + EOI + %cat .+/input \| .+/driver.* - \| diff -u .+% + %.+ + -3.4.5 + %error: test .+dir\{.+\} failed% + error: process diff exited with code 1 + % info: while testing .+dir\{.+\}% + %info: failed to test .+dir\{.+\}% + EOE + } + + : input-not-found + : + { + echo '1.2.3' >=input; + echo '3.4.5' >=output; + $* -q <<EOI 2>>/~%EOE% != 0 + driver = $src_root/../exe{driver} + ./: test = $driver + ./: $driver + ./: test.arguments = 'foo' + ./: file{input}: test.stdin = true + ./: file{output}: test.stdout = true + EOI + unable to open foo + error: test dir{./} failed + % error: process .+/driver.* exited with code 1% + EOE + } +} + +: timeout +: +{ + : operation + : + { + : no-output + : + ln -s $src_base/output.in ./; + $* config.test.timeout=1 <<EOI 2>>/~%EOE% != 0 + driver = $src_root/../exe{driver} + ./: test = $driver + ./: test.options = -s + ./: $driver + EOI + error: test dir{./} failed + % error: process .+driver.* terminated: execution timeout expired% + EOE + + : stdin-stdout + : + ln -s $src_base/input.in ./; + ln -s $src_base/output.in ./; + $* config.test.timeout=1 --verbose 1 &input &input.d &output &output.d <<EOI 2>>/~%EOE% != 0 + driver = $src_root/../exe{driver} + ./: test = $driver + ./: test.options = -s + ./: $driver + ./: file{input}: test.stdin = true + ./: file{output}: test.stdout = true + file{input}: in{input} $src_root/manifest #@@ in module + file{output}: in{output} $src_root/manifest #@@ in module + EOI + %version in\{.+\} -> .+%{2} + test dir{./} + error: test dir{./} failed + % error: process .+driver.* terminated: execution timeout expired% + % info: test command line: cat .+/input \| .+driver.* -s \| diff -u .+% + info: while testing dir{./} + info: failed to test dir{./} + EOE + } + + : test + : + { + : no-output + : + ln -s $src_base/output.in ./; + $* config.test.timeout=/1 <<EOI 2>>/~%EOE% != 0 + driver = $src_root/../exe{driver} + ./: test = $driver + ./: test.options = -s + ./: $driver + EOI + error: test dir{./} failed + % error: process .+driver.* terminated: execution timeout expired% + EOE + } +} + +: runner +: +if ($cxx.target.class != 'windows') +{ + cat <<EOI >=run; + #!/bin/sh + if test "$1" = "--trace"; then + shift + echo "tracing" + fi + "$@" + EOI + + chmod u+x run; + + echo 'tracing' >=output.in; + cat $src_base/output.in >+output.in; + + $* config.test.runner="./run --trace" <<EOI + driver = $src_root/../exe{driver} + ./: test = $driver + ./: $driver + ./: file{output}: test.stdout = true + file{output}: in{output} $src_root/manifest #@@ in module + EOI +} |