#!/usr/bin/env bash # This script runs the regression tests in src/regression. # It also compiles the tests in benchmark/tests # set -e name=`basename "$0"` usage () { echo >&2 "usage: $name [-fail] [-short] [-test-reg reg] [mlton flags ...]" exit 1 } fail='false' short='false' testReg='false' exitFail=false declare -a testRegs declare -a flags declare -a extraFlags flags[${#flags[@]}]="-type-check" flags[${#flags[@]}]="true" while [ "$#" -gt 0 ]; do case "$1" in -fail) fail='true' shift ;; -short) short='true' shift ;; -test-reg) testReg='true' shift if [ "$#" = 0 ]; then usage fi testRegs[${#testRegs[@]}]="$1" shift ;; *) flags[${#flags[@]}]="$1" shift ;; esac done dir=`dirname "$0"` src=`cd "$dir/.." && pwd` bin="$src/build/bin" lib="$src/build/lib/mlton" mlton="$bin/mlton" cont='callcc.sml callcc2.sml callcc3.sml once.sml' flatArray='finalize.sml flat-array.sml flat-array.2.sml' intInf='conv.sml conv2.sml fixed-integer.sml harmonic.sml int-inf.*.sml slow.sml slower.sml smith-normal-form.sml' signal='finalize.sml signals.sml signals2.sml signals3.sml signals4.sml suspend.sml weak.sml' thread='thread0.sml thread1.sml thread2.sml mutex.sml prodcons.sml same-fringe.sml timeout.sml' world='world1.sml world2.sml world3.sml world4.sml world5.sml world6.sml' tmp=/tmp/z.regression.$$ PATH="$bin:$PATH" # whitelist tests that are known to fail (will still run but exit cleanly) declare -A whitelisted if [ -a $src/regression/whitelist ] ; then while read f ; do echo "whitelisting $f..." whitelisted["$f"]=1 done <$src/regression/whitelist fi isWhitelisted () { local f=$1 if [[ ${whitelisted["$f"]} ]] ; then echo 1 else echo 0 fi } eval `"$src/bin/platform"` compFail () { echo "compilation of $f failed with ${flags[*]}" } "$mlton" -verbose 1 || (echo 'no mlton present' && exitFail=true) echo "flags = ${flags[*]}" cd "$src/regression" if $fail; then for f in fail/*.sml; do echo "testing $f" ( "$mlton" "${flags[@]}" -stop tc "$f" >/dev/null 2>&1 && echo "compilation of $f should have failed but did not" && ignore=$(isWhitelisted $f) && if [ "$ignore" -eq 0 ] ; then exitFail=true ; fi ) || true done if [ "$exitFail" = true ] ; then exit 1 else exit 0 fi fi forMinGW='false' if [ $HOST_OS = mingw ]; then forMinGW='true' fi for f in *.sml; do f=`basename "$f" .sml` if ($testReg); then skip='true' for (( i = 0 ; $i < ${#testRegs[@]} ; i++ )); do if [ "$f" = "${testRegs[$i]}" ]; then skip='false' fi done if ($skip); then continue fi fi case $HOST_OS in cygwin) case "$f" in textio.2) continue ;; esac ;; hurd) # Work-around hurd bug (http://bugs.debian.org/551470) case "$f" in mutex|prodcons|signals|signals2|signals3|signals4|suspend|thread2|timeout|world5) continue ;; esac ;; mingw) case "$f" in cmdline|command-line|echo|filesys|posix-exit|signals|signals2|signals3|signals4|socket|suspend|textio.2|unixpath|world*) continue ;; esac ;; esac case "$f" in serialize) continue ;; esac echo "testing $f" unset extraFlags case "$f" in exn-history*) extraFlags[${#extraFlags[@]}]="-const" extraFlags[${#extraFlags[@]}]="Exn.keepHistory true" ;; esac mlb="$f.mlb" echo "\$(SML_LIB)/basis/basis.mlb \$(SML_LIB)/basis/mlton.mlb \$(SML_LIB)/basis/sml-nj.mlb ann \"allowFFI true\" \"allowOverload true\" \"allowExtendedTextConsts true\" \"nonexhaustiveBind ignore\" \"nonexhaustiveMatch ignore\" \"redundantBind ignore\" \"redundantMatch ignore\" in $f.sml end" >"$mlb" "$mlton" "${flags[@]}" "${extraFlags[@]}" -output "$f" "$mlb" if [ "$?" -ne '0' ] || [ ! -x "$f" ]; then compFail "$f" exitFail=true fi rm "$mlb" if [ ! -r "$f".nonterm -a -x "$f" ]; then nonZeroMsg='Nonzero exit status.' if $forMinGW; then nonZeroMsg="$nonZeroMsg"'\r' fi ( "./$f" || echo -e "$nonZeroMsg" ) >$tmp 2>&1 if [ -r "$f.ok" ]; then compare="$f.$HOST_ARCH-$HOST_OS.ok" if [ ! -r $compare ]; then compare="$f.ok" fi if $forMinGW; then newcompare="$f.sed.ok" sed $'s/$/\r/' <"$compare" > "$newcompare" compare="$newcompare" fi if ! diff "$compare" "$tmp"; then echo "$f: difference with ${flags[*]} ${extraFlags[*]}" ignore=$(isWhitelisted $f) if [ "$ignore" -eq 0 ] ; then exitFail=true fi fi fi fi done if $short || $testReg ; then if [ "$exitFail" = true ] ; then exit 1 else exit 0 fi fi "$src/bin/mmake" clean >/dev/null cd "$src/benchmark/tests" for f in *.sml; do f=`basename "$f" .sml` tmpf="/tmp/$f.$$" case "$f" in fxp) echo "skipping $f" ;; *) echo "testing $f" echo "val _ = Main.doit 0" | cat "$f.sml" - > "$tmpf.sml" $mlton -output "$tmpf" "${flags[@]}" \ -default-ann 'nonexhaustiveBind ignore'\ -default-ann 'nonexhaustiveMatch ignore'\ -default-ann 'redundantBind ignore' \ -default-ann 'redundantMatch ignore' \ "$tmpf.sml" if [ $? -ne 0 ]; then compFail "$f" exitFail=true fi rm -f "$tmpf" "$tmpf.sml" ;; esac done "$src/bin/mmake" clean >/dev/null cd "$src" for f in mllex mlyacc mlprof; do tmpf="/tmp/$f.$$" cd "$src/$f" echo "testing $f" "$src/bin/mmake" -W "$f" >/dev/null "$mlton" "${flags[@]}" -output "$tmpf" "$f.mlb" if [ $? -ne 0 ]; then compFail "$f" exitFail=true fi rm -f "$tmpf" done rm -f "$tmp" if [ "$exitFail" = true ] ; then exit 1 else exit 0 fi