For some physical simulators, we have multiple SNR iterations. The previous version of the script correctly retained only the last measurement, but if a previous measurement condition set RC=1, the script would fail although the final "good" run might fulfil the measurement condition (IOW, it would show SUCCESS, but still fail on the check). Instead, check if all measurement lines finish on SUCCESS, which handles the above case.
86 lines
2.9 KiB
Bash
Executable File
86 lines
2.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# This bash script builds an awk script. The awk script tries to match
|
|
# (provided) patterns and compares them against given thresholds condition
|
|
# (e.g., threshold is "< 10").
|
|
|
|
function die() { echo $@ 1>&2; exit 1; }
|
|
|
|
# Print every line, because the logs are piped into this script, but a user is
|
|
# typically also interested into the raw logs.
|
|
SCRIPT='
|
|
{ print $0 }
|
|
'
|
|
|
|
NUM=0
|
|
# for each pair of <pattern>/<condition>, add corresponding rules.
|
|
while [ $# -gt 0 ]; do
|
|
[ $# -ne 1 ] || die "unmatched <pattern>/<condition>"
|
|
PATTERN=${1}
|
|
COND=${2}
|
|
shift 2
|
|
|
|
# Add a rule that searches for a PATTERN + number, and checks against
|
|
# CONDition. If the condition does not hold, it is counted as a failure. In
|
|
# both cases, the result is logged in an array to output at the end of the
|
|
# script.
|
|
#
|
|
# To search for the number, first substr() returns what has been matched
|
|
# (PATTERN + number), and sub() deletes PATTERN and whitespace, resulting in
|
|
# the number (measurement). To force number into a numeric context, we add 0,
|
|
# as awk would otherwise compare a string to a number (example:
|
|
# gawk 'BEGIN { meas = "117"; if (meas > 96) { } else { print "fail";}}'
|
|
# printfs "fail").
|
|
#
|
|
# Example: pattern "PHY proc tx", condition "< 200"
|
|
# The awk script tries to match every line for "PHY proc tx _NUMBER_" (where
|
|
# number is a decimal), and compares _NUMBER_ against condition "< 200",
|
|
# i.e., "_NUMBER_ < 200".
|
|
# If the condition holds, will set "CHECK PHY proc tx _NUMBER_ < 200 SUCCESS".
|
|
# If the condition fails, will set "CHECK PHY proc tx _NUMBER_ < 200 FAIL".
|
|
SCRIPT+='
|
|
match($0, /'${PATTERN}' +([0-9]+(\.[0-9]+)?)/) {
|
|
meas = substr($0, RSTART, RLENGTH);
|
|
sub(/'${PATTERN}' +/, "", meas);
|
|
if ((meas+0) '${COND}') {
|
|
r = "SUCCESS";
|
|
} else {
|
|
r = "FAIL";
|
|
}
|
|
RESULTS['${NUM}']=sprintf("CHECK %-35s %7.2f %-8s %s", "'${PATTERN}'", meas, " '${COND}'", r);
|
|
}
|
|
'
|
|
|
|
# Generate an additional rule for the end of the logs: if the pattern is not
|
|
# found, it is counted as a failure and logged appropriately.
|
|
# Following the above example "PHY proc tx" and "< 200": if such log is not
|
|
# found, will set "CHECK PHY proc tx < 200 NOTFOUND"
|
|
SCRIPT+='
|
|
END {
|
|
if (!RESULTS['${NUM}']) {
|
|
RESULTS['${NUM}']=sprintf("CHECK %-35s %-7s NOTFOUND", "'${PATTERN}'", "'${COND}'");
|
|
}
|
|
}
|
|
'
|
|
|
|
let NUM=${NUM}+1
|
|
done
|
|
|
|
# After passing through all logs, print all results, and exit with return code
|
|
# (0 on success, i.e..all conditions checked, otherwise 1 on failure).
|
|
SCRIPT+='
|
|
END {
|
|
RC = 0;
|
|
for (i = 0; i < '${NUM}'; ++i) {
|
|
print RESULTS[i]
|
|
if (!(RESULTS[i] ~ /SUCCESS$/))
|
|
RC = 1;
|
|
}
|
|
exit RC
|
|
}
|
|
'
|
|
|
|
# Read from separate file descriptor 3: this allows us to pipe the actual log
|
|
# to analyze into awk (by using the script like so: analyze-timing.sh < log)
|
|
awk -f /dev/fd/3 3<<< ${SCRIPT}
|