tadd rangetest for binary search testing of programs - numtools - perform numer… | |
git clone git://src.adamsgaard.dk/numtools | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 75d269fb6d9921f0090d9ec5ddf7880d25fd0247 | |
parent b26d630f43826b38df0e7ec28242b28bb99178ab | |
Author: Anders Damsgaard <[email protected]> | |
Date: Wed, 13 Jan 2021 12:08:02 +0100 | |
add rangetest for binary search testing of programs | |
Diffstat: | |
A rangetest | 75 +++++++++++++++++++++++++++++… | |
1 file changed, 75 insertions(+), 0 deletions(-) | |
--- | |
diff --git a/rangetest b/rangetest | |
t@@ -0,0 +1,75 @@ | |
+#!/usr/bin/awk -f | |
+# uses a binary search to run a "cmd" where the first occurence of | |
+# string @PARAM@ is substituted for a value between "min_val" and | |
+# max_val". Successful runs are reported on stdout, failed runs on | |
+# stderr. The "cmd" command must successfully run with either "min_val" | |
+# or "max_val". | |
+ | |
+function die(s) { | |
+ printf "error: %s\n", s > "/dev/stderr" | |
+ exit 1 | |
+} | |
+ | |
+function launch(cmd, val) { | |
+ sub(/@PARAM@/, val, cmd) | |
+ if (system(cmd)) { | |
+ printf "%g\n", val > "/dev/stderr" | |
+ return 1 | |
+ } else { | |
+ printf "%g\n", val > "/dev/stdout" | |
+ return 0 | |
+ } | |
+} | |
+ | |
+function binary_search(cmd, min, max, maxiter) { | |
+ | |
+ minfail = launch(cmd, min) | |
+ maxfail = launch(cmd, max) | |
+ | |
+ if (minfail && maxfail) | |
+ die("both min_val and max_val runs errored") | |
+ | |
+ if (!minfail && !maxfail) | |
+ die("both min_val and max_val ran successfully") | |
+ | |
+ while (min <= max && iter < maxiter) { | |
+ val = min + 0.5 * (max - min) | |
+ | |
+ if (launch(cmd, val)) { # the cmd fails | |
+ if (maxfail) { | |
+ max = val | |
+ maxfail = 1 | |
+ } else { | |
+ min = val | |
+ minfail = 1 | |
+ } | |
+ } else { # the cmd is ok | |
+ if (maxfail) { | |
+ min = val | |
+ minfail = 0 | |
+ } else { | |
+ max = val | |
+ maxfail = 0 | |
+ } | |
+ } | |
+ iter++ | |
+ } | |
+} | |
+ | |
+BEGIN { | |
+ | |
+ if (ARGC != 4) | |
+ die("usage: rangetest cmd min_val max_val") | |
+ | |
+ cmd = ARGV[1] | |
+ min = ARGV[2] | |
+ max = ARGV[3] | |
+ | |
+ if (!match(cmd, /@PARAM@/)) | |
+ die("@PARAM@ not found in cmd") | |
+ | |
+ if (min >= max) | |
+ die("min_val must be smaller than max_val") | |
+ | |
+ binary_search(cmd, min, max, 20) | |
+} |