144 lines
3.8 KiB
Bash
Executable File
144 lines
3.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# Assert that a program can be derived from the ASG as expected.
|
|
#
|
|
# See `./README.md` for more information.
|
|
|
|
set -euo pipefail
|
|
|
|
mypath=$(dirname "$0")
|
|
. "$mypath/../../conf.sh"
|
|
|
|
# Performing this check within `<()` below won't cause a failure.
|
|
: "${P_XMLLINT?}" # conf.sh
|
|
|
|
tamer-flag-or-exit-ok wip-asg-derived-xmli
|
|
|
|
run-test() {
|
|
local name="${1?Missing test name}"
|
|
local dir="${2?Missing dir}"
|
|
shift 2
|
|
|
|
rm -f "$dir/"*.log
|
|
|
|
header "$dir" "$name"
|
|
|
|
"test-$name" "$dir" "$@" || {
|
|
local ret=$?
|
|
echo ' [FAIL]'
|
|
return "$ret"
|
|
}
|
|
|
|
echo ' [ OK ]'
|
|
}
|
|
|
|
timed-tamec() {
|
|
local dir="${1?Missing directory name}"
|
|
local in="${2?Missing input filename}"
|
|
local out="${3?Missing output filename}"
|
|
|
|
dir="${dir%/}" # strip trailing slash, if any (just to style output)
|
|
|
|
local -i ret=0
|
|
|
|
# /usr/bin/time does not have high enough precision
|
|
# This won't be wholly accurate because time is spent in shell,
|
|
# but it'll be close enough.
|
|
local -i start_ns=$(date +%s%N)
|
|
|
|
command time -f "%F/%Rfault %I/%Oio %Mrss %c/%wctx \n%C" -o "$dir/time.log" \
|
|
"${TAMER_PATH_TAMEC?}" -o "$dir/$out" --emit xmlo "$dir/$in" \
|
|
&> "$dir/tamec-$out.log" \
|
|
|| ret=$?
|
|
|
|
local -i end_ns=$(date +%s%N)
|
|
local -i elapsed_ms=$(( (end_ns - start_ns) / 1000000 ))
|
|
|
|
# First line will be "Command exited with non-zero status N" on failure.
|
|
# The last line will be '%C' above.
|
|
# So, we want the second-to-last line.
|
|
#
|
|
# Newline omission is intentional.
|
|
printf "<%3dms %s" "$elapsed_ms" "$(tail -n2 "$dir/time.log" | head -n1)"
|
|
|
|
return "$ret"
|
|
}
|
|
|
|
header() {
|
|
# allocate enough space based on the path we'll output
|
|
local -i mypath_len=${#mypath}
|
|
local -i dirlen=$((mypath_len + 12))
|
|
|
|
# newline intentionally omitted
|
|
printf "%-${dirlen}s %-20s " "$@"
|
|
}
|
|
|
|
# Derive a program from `src.xml` and verify that it meets our expectations.
|
|
#
|
|
# This test is inherently fragile, as it will break any time we perform
|
|
# certain types of optimizations or change internal representations. _But
|
|
# that is intended._ We want to be well aware of such changes in derivation
|
|
# so that we can judge whether it needs adjustment.
|
|
test-derive-from-src() {
|
|
local dir="${1?Missing directory name}"
|
|
|
|
timed-tamec "$dir" src.xml out.xmli || return
|
|
|
|
diff <("$P_XMLLINT" --format "$dir/expected.xml" || echo 'ERR expected.xml') \
|
|
<("$P_XMLLINT" --format "$dir/out.xmli" || echo 'ERR out.xmli') \
|
|
&> "$dir/diff.log"
|
|
}
|
|
|
|
|
|
# Having taken `A` and derived `B`, we should be able to take `B` and derive
|
|
# `C`, where `B` and `C` are equivalent programs.
|
|
#
|
|
# That is, this derivation should be transitively equivalent and reach a
|
|
# fixpoint on the second derivation. This serves as a sanity check to
|
|
# ensure that the program we generated makes sense to our own system.
|
|
#
|
|
# Note that, in the future, we'll have to strip handoff metadata
|
|
# (`preproc:*` data) from the output so that it will be accepted by TAMER.
|
|
test-fixpoint() {
|
|
local dir="${1?Missing directory name}"
|
|
|
|
timed-tamec "$dir" out.xmli out-2.xmli || return
|
|
|
|
diff <("$P_XMLLINT" --format "$dir/expected.xml" || echo 'ERR expected.xml') \
|
|
<("$P_XMLLINT" --format "$dir/out-2.xmli" || echo 'ERR out.xmli') \
|
|
&> "$dir/diff.log"
|
|
}
|
|
|
|
|
|
main() {
|
|
local -a fail=()
|
|
|
|
for dir in "$mypath"/*/; do
|
|
run-test derive-from-src "$dir" && run-test fixpoint "$dir" \
|
|
|| fail=("${fail[@]}" "$dir")
|
|
done
|
|
|
|
test -z "${fail[@]}" || {
|
|
cat << EOF
|
|
!!! TEST FAILED
|
|
tamec: $TAMER_PATH_TAMEC
|
|
|
|
note: The compiler output and diff between the expected and given data
|
|
are below. Both files are formatted with \`xmllint\` automatically.
|
|
EOF
|
|
|
|
for dir in "${fail[@]}"; do
|
|
echo
|
|
echo ",=====[ $dir logs ]======"
|
|
echo "|"
|
|
cat "$dir/"*.log | sed 's/^/| /'
|
|
echo "|"
|
|
echo "\`====[ end $dir logs ]===="
|
|
done
|
|
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
main "$@"
|
|
|