| 1 | #!/usr/bin/env bash |
| 2 | |
| 3 | # This script runs the regression tests in src/regression. |
| 4 | # It also compiles the tests in benchmark/tests |
| 5 | |
| 6 | # set -e |
| 7 | |
| 8 | name=`basename "$0"` |
| 9 | |
| 10 | usage () { |
| 11 | echo >&2 "usage: $name [-fail] [-short] [-test-reg reg] [mlton flags ...]" |
| 12 | exit 1 |
| 13 | } |
| 14 | |
| 15 | fail='false' |
| 16 | short='false' |
| 17 | testReg='false' |
| 18 | exitFail=false |
| 19 | declare -a testRegs |
| 20 | declare -a flags |
| 21 | declare -a extraFlags |
| 22 | flags[${#flags[@]}]="-type-check" |
| 23 | flags[${#flags[@]}]="true" |
| 24 | while [ "$#" -gt 0 ]; do |
| 25 | case "$1" in |
| 26 | -fail) |
| 27 | fail='true' |
| 28 | shift |
| 29 | ;; |
| 30 | -short) |
| 31 | short='true' |
| 32 | shift |
| 33 | ;; |
| 34 | -test-reg) |
| 35 | testReg='true' |
| 36 | shift |
| 37 | if [ "$#" = 0 ]; then |
| 38 | usage |
| 39 | fi |
| 40 | testRegs[${#testRegs[@]}]="$1" |
| 41 | shift |
| 42 | ;; |
| 43 | *) |
| 44 | flags[${#flags[@]}]="$1" |
| 45 | shift |
| 46 | ;; |
| 47 | esac |
| 48 | done |
| 49 | |
| 50 | |
| 51 | dir=`dirname "$0"` |
| 52 | src=`cd "$dir/.." && pwd` |
| 53 | bin="$src/build/bin" |
| 54 | lib="$src/build/lib/mlton" |
| 55 | mlton="$bin/mlton" |
| 56 | cont='callcc.sml callcc2.sml callcc3.sml once.sml' |
| 57 | flatArray='finalize.sml flat-array.sml flat-array.2.sml' |
| 58 | intInf='conv.sml conv2.sml fixed-integer.sml harmonic.sml int-inf.*.sml slow.sml slower.sml smith-normal-form.sml' |
| 59 | signal='finalize.sml signals.sml signals2.sml signals3.sml signals4.sml suspend.sml weak.sml' |
| 60 | thread='thread0.sml thread1.sml thread2.sml mutex.sml prodcons.sml same-fringe.sml timeout.sml' |
| 61 | world='world1.sml world2.sml world3.sml world4.sml world5.sml world6.sml' |
| 62 | tmp=/tmp/z.regression.$$ |
| 63 | PATH="$bin:$PATH" |
| 64 | |
| 65 | # whitelist tests that are known to fail (will still run but exit cleanly) |
| 66 | declare -A whitelisted |
| 67 | if [ -a $src/regression/whitelist ] ; then |
| 68 | while read f ; do |
| 69 | echo "whitelisting $f..." |
| 70 | whitelisted["$f"]=1 |
| 71 | done <$src/regression/whitelist |
| 72 | fi |
| 73 | |
| 74 | isWhitelisted () { |
| 75 | local f=$1 |
| 76 | if [[ ${whitelisted["$f"]} ]] ; then |
| 77 | echo 1 |
| 78 | else |
| 79 | echo 0 |
| 80 | fi |
| 81 | } |
| 82 | |
| 83 | eval `"$src/bin/platform"` |
| 84 | |
| 85 | compFail () { |
| 86 | echo "compilation of $f failed with ${flags[*]}" |
| 87 | } |
| 88 | |
| 89 | "$mlton" -verbose 1 || (echo 'no mlton present' && exitFail=true) |
| 90 | echo "flags = ${flags[*]}" |
| 91 | |
| 92 | cd "$src/regression" |
| 93 | |
| 94 | if $fail; then |
| 95 | for f in fail/*.sml; do |
| 96 | echo "testing $f" |
| 97 | ( "$mlton" "${flags[@]}" -stop tc "$f" >/dev/null 2>&1 && |
| 98 | echo "compilation of $f should have failed but did not" && ignore=$(isWhitelisted $f) && if [ "$ignore" -eq 0 ] ; then exitFail=true ; fi ) || |
| 99 | true |
| 100 | done |
| 101 | |
| 102 | if [ "$exitFail" = true ] ; then |
| 103 | exit 1 |
| 104 | else |
| 105 | exit 0 |
| 106 | fi |
| 107 | fi |
| 108 | |
| 109 | forMinGW='false' |
| 110 | if [ $HOST_OS = mingw ]; then |
| 111 | forMinGW='true' |
| 112 | fi |
| 113 | |
| 114 | for f in *.sml; do |
| 115 | f=`basename "$f" .sml` |
| 116 | if ($testReg); then |
| 117 | skip='true' |
| 118 | for (( i = 0 ; $i < ${#testRegs[@]} ; i++ )); do |
| 119 | if [ "$f" = "${testRegs[$i]}" ]; then |
| 120 | skip='false' |
| 121 | fi |
| 122 | done |
| 123 | if ($skip); then |
| 124 | continue |
| 125 | fi |
| 126 | fi |
| 127 | case $HOST_OS in |
| 128 | cygwin) |
| 129 | case "$f" in |
| 130 | textio.2) |
| 131 | continue |
| 132 | ;; |
| 133 | esac |
| 134 | ;; |
| 135 | hurd) |
| 136 | # Work-around hurd bug (http://bugs.debian.org/551470) |
| 137 | case "$f" in |
| 138 | mutex|prodcons|signals|signals2|signals3|signals4|suspend|thread2|timeout|world5) |
| 139 | continue |
| 140 | ;; |
| 141 | esac |
| 142 | ;; |
| 143 | mingw) |
| 144 | case "$f" in |
| 145 | cmdline|command-line|echo|filesys|posix-exit|signals|signals2|signals3|signals4|socket|suspend|textio.2|unixpath|world*) |
| 146 | continue |
| 147 | ;; |
| 148 | esac |
| 149 | ;; |
| 150 | esac |
| 151 | case "$f" in |
| 152 | serialize) |
| 153 | continue |
| 154 | ;; |
| 155 | esac |
| 156 | echo "testing $f" |
| 157 | unset extraFlags |
| 158 | case "$f" in |
| 159 | exn-history*) |
| 160 | extraFlags[${#extraFlags[@]}]="-const" |
| 161 | extraFlags[${#extraFlags[@]}]="Exn.keepHistory true" |
| 162 | ;; |
| 163 | esac |
| 164 | |
| 165 | mlb="$f.mlb" |
| 166 | echo "\$(SML_LIB)/basis/basis.mlb |
| 167 | \$(SML_LIB)/basis/mlton.mlb |
| 168 | \$(SML_LIB)/basis/sml-nj.mlb |
| 169 | ann |
| 170 | \"allowFFI true\" |
| 171 | \"allowOverload true\" |
| 172 | \"allowExtendedTextConsts true\" |
| 173 | \"nonexhaustiveBind ignore\" |
| 174 | \"nonexhaustiveMatch ignore\" |
| 175 | \"redundantBind ignore\" |
| 176 | \"redundantMatch ignore\" |
| 177 | in $f.sml |
| 178 | end" >"$mlb" |
| 179 | "$mlton" "${flags[@]}" "${extraFlags[@]}" -output "$f" "$mlb" |
| 180 | if [ "$?" -ne '0' ] || [ ! -x "$f" ]; then |
| 181 | compFail "$f" |
| 182 | exitFail=true |
| 183 | fi |
| 184 | rm "$mlb" |
| 185 | |
| 186 | if [ ! -r "$f".nonterm -a -x "$f" ]; then |
| 187 | nonZeroMsg='Nonzero exit status.' |
| 188 | if $forMinGW; then |
| 189 | nonZeroMsg="$nonZeroMsg"'\r' |
| 190 | fi |
| 191 | ( "./$f" || echo -e "$nonZeroMsg" ) >$tmp 2>&1 |
| 192 | if [ -r "$f.ok" ]; then |
| 193 | compare="$f.$HOST_ARCH-$HOST_OS.ok" |
| 194 | if [ ! -r $compare ]; then |
| 195 | compare="$f.ok" |
| 196 | fi |
| 197 | if $forMinGW; then |
| 198 | newcompare="$f.sed.ok" |
| 199 | sed $'s/$/\r/' <"$compare" > "$newcompare" |
| 200 | compare="$newcompare" |
| 201 | fi |
| 202 | if ! diff "$compare" "$tmp"; then |
| 203 | echo "$f: difference with ${flags[*]} ${extraFlags[*]}" |
| 204 | ignore=$(isWhitelisted $f) |
| 205 | if [ "$ignore" -eq 0 ] ; then |
| 206 | exitFail=true |
| 207 | fi |
| 208 | fi |
| 209 | fi |
| 210 | fi |
| 211 | done |
| 212 | |
| 213 | if $short || $testReg ; then |
| 214 | if [ "$exitFail" = true ] ; then |
| 215 | exit 1 |
| 216 | else |
| 217 | exit 0 |
| 218 | fi |
| 219 | fi |
| 220 | |
| 221 | "$src/bin/mmake" clean >/dev/null |
| 222 | cd "$src/benchmark/tests" |
| 223 | for f in *.sml; do |
| 224 | f=`basename "$f" .sml` |
| 225 | tmpf="/tmp/$f.$$" |
| 226 | case "$f" in |
| 227 | fxp) |
| 228 | echo "skipping $f" |
| 229 | ;; |
| 230 | *) |
| 231 | echo "testing $f" |
| 232 | echo "val _ = Main.doit 0" | cat "$f.sml" - > "$tmpf.sml" |
| 233 | $mlton -output "$tmpf" "${flags[@]}" \ |
| 234 | -default-ann 'nonexhaustiveBind ignore'\ |
| 235 | -default-ann 'nonexhaustiveMatch ignore'\ |
| 236 | -default-ann 'redundantBind ignore' \ |
| 237 | -default-ann 'redundantMatch ignore' \ |
| 238 | "$tmpf.sml" |
| 239 | if [ $? -ne 0 ]; then |
| 240 | compFail "$f" |
| 241 | exitFail=true |
| 242 | fi |
| 243 | rm -f "$tmpf" "$tmpf.sml" |
| 244 | ;; |
| 245 | esac |
| 246 | done |
| 247 | "$src/bin/mmake" clean >/dev/null |
| 248 | cd "$src" |
| 249 | for f in mllex mlyacc mlprof; do |
| 250 | tmpf="/tmp/$f.$$" |
| 251 | cd "$src/$f" |
| 252 | echo "testing $f" |
| 253 | "$src/bin/mmake" -W "$f" >/dev/null |
| 254 | "$mlton" "${flags[@]}" -output "$tmpf" "$f.mlb" |
| 255 | if [ $? -ne 0 ]; then |
| 256 | compFail "$f" |
| 257 | exitFail=true |
| 258 | fi |
| 259 | rm -f "$tmpf" |
| 260 | done |
| 261 | |
| 262 | rm -f "$tmp" |
| 263 | |
| 264 | if [ "$exitFail" = true ] ; then |
| 265 | exit 1 |
| 266 | else |
| 267 | exit 0 |
| 268 | fi |