Merge remote-tracking branch 'upstream/master' into HEAD
[stockfish] / tests / instrumented.sh
1 #!/bin/bash
2 # check for errors under valgrind or sanitizers.
3
4 error()
5 {
6   echo "instrumented testing failed on line $1"
7   exit 1
8 }
9 trap 'error ${LINENO}' ERR
10
11 # define suitable post and prefixes for testing options
12 case $1 in
13   --valgrind)
14     echo "valgrind testing started"
15     prefix=''
16     exeprefix='valgrind --error-exitcode=42'
17     postfix='1>/dev/null'
18     threads="1"
19   ;;
20   --valgrind-thread)
21     echo "valgrind-thread testing started"
22     prefix=''
23     exeprefix='valgrind --error-exitcode=42'
24     postfix='1>/dev/null'
25     threads="2"
26   ;;
27   --sanitizer-undefined)
28     echo "sanitizer-undefined testing started"
29     prefix='!'
30     exeprefix=''
31     postfix='2>&1 | grep -A50 "runtime error:"'
32     threads="1"
33   ;;
34   --sanitizer-thread)
35     echo "sanitizer-thread testing started"
36     prefix='!'
37     exeprefix=''
38     postfix='2>&1 | grep -A50 "WARNING: ThreadSanitizer:"'
39     threads="2"
40
41 cat << EOF > tsan.supp
42 race:TTEntry::move
43 race:TTEntry::depth
44 race:TTEntry::bound
45 race:TTEntry::save
46 race:TTEntry::value
47 race:TTEntry::eval
48 race:TTEntry::is_pv
49
50 race:TranspositionTable::probe
51 race:TranspositionTable::hashfull
52
53 EOF
54
55     export TSAN_OPTIONS="suppressions=./tsan.supp"
56
57   ;;
58   *)
59     echo "unknown testing started"
60     prefix=''
61     exeprefix=''
62     postfix=''
63     threads="1"
64   ;;
65 esac
66
67 # simple command line testing
68 for args in "eval" \
69             "go nodes 1000" \
70             "go depth 10" \
71             "go movetime 1000" \
72             "go wtime 8000 btime 8000 winc 500 binc 500" \
73             "bench 128 $threads 8 default depth"
74 do
75
76    echo "$prefix $exeprefix ./stockfish $args $postfix"
77    eval "$prefix $exeprefix ./stockfish $args $postfix"
78
79 done
80
81 # more general testing, following an uci protocol exchange
82 cat << EOF > game.exp
83  set timeout 240
84  spawn $exeprefix ./stockfish
85
86  send "uci\n"
87  expect "uciok"
88
89  send "setoption name Threads value $threads\n"
90
91  send "ucinewgame\n"
92  send "position startpos\n"
93  send "go nodes 1000\n"
94  expect "bestmove"
95
96  send "position startpos moves e2e4 e7e6\n"
97  send "go nodes 1000\n"
98  expect "bestmove"
99
100  send "position fen 5rk1/1K4p1/8/8/3B4/8/8/8 b - - 0 1\n"
101  send "go depth 20\n"
102  expect "bestmove"
103
104  send "quit\n"
105  expect eof
106
107  # return error code of the spawned program, useful for valgrind
108  lassign [wait] pid spawnid os_error_flag value
109  exit \$value
110 EOF
111
112 #download TB as needed
113 if [ ! -d ../tests/syzygy ]; then
114    curl -sL https://api.github.com/repos/niklasf/python-chess/tarball/9b9aa13f9f36d08aadfabff872882f4ab1494e95 | tar -xzf -
115    mv niklasf-python-chess-9b9aa13 ../tests/syzygy
116 fi
117
118 cat << EOF > syzygy.exp
119  set timeout 240
120  spawn $exeprefix ./stockfish
121  send "uci\n"
122  send "setoption name SyzygyPath value ../tests/syzygy/\n"
123  expect "info string Found 35 tablebases" {} timeout {exit 1}
124  send "bench 128 1 8 default depth\n"
125  send "quit\n"
126  expect eof
127
128  # return error code of the spawned program, useful for valgrind
129  lassign [wait] pid spawnid os_error_flag value
130  exit \$value
131 EOF
132
133 for exp in game.exp syzygy.exp
134 do
135
136   echo "$prefix expect $exp $postfix"
137   eval "$prefix expect $exp $postfix"
138
139   rm $exp
140
141 done
142
143 rm -f tsan.supp
144
145 echo "instrumented testing OK"