| 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) | |
| +} |