-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrunme.expect
213 lines (185 loc) · 5.16 KB
/
runme.expect
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#!/usr/bin/env expect
package require Tclx 8.0
set e_ok 0
set e_intr 3
set e_earlypanic 4
set e_earlyout 5
set e_loadfail 6
set e_loadprompt 7
set e_loadpanic 8
set e_loadout 9
set e_loadeof 10
set e_fail 11
set e_bail 12
set e_tooshort 13
set e_panic 14
set e_timeout 15
set e_eof 16
set e_toolong 17
set e_lasthang 18
set e_lasteof 19
# You can vary the prefix emitted by the test harness by building the entire
# source tree with make CPPFLAGS='-DTEST_PREFIX_PREFIX=\"TAPISH: \"' for
# example. The various layers of quotation are to protect against the
# outermost shell and the shell spawned by make.
if {[info exists env(RUNME_PFX)]} {
set pfx "(?p)^\n$env(RUNME_PFX)"
} else {
set pfx "(?p)^\nTAPME: "
}
# By default, we want to invoke some sane way of getting qemu spun up. But
# when testing, we probably don't want to invoke 'make qemu' since the
# students may have their own feelings on that.
if {[info exists env(RUNME_CMD)]} {
set spawncmd $env(RUNME_CMD)
} else {
set spawncmd {make "QEMUEXTRA=-snapshot -enable-kvm" "CPUS=2" qemu-nox}
}
# We can try to run a particular test over and over, though by default we
# will do so only once.
if {[info exists env(RUNME_ITERS)]} {
set iters $env(RUNME_ITERS)
} else {
set iters 1
}
set eol ".*(?=\n)"
set panicre "(?p)cpu.: panic:${eol}"
set tname "[lindex $argv 0]";
proc bail { exitwith } {
exec kill "[exp_pid]"
close
send_user "\n"
exit $exitwith
}
proc paniced { where with } {
# See if we get a little bit more detail
set timeout 4
expect -regex "\n\( \[\^ \]*\){10}"
send_user "\nFailure: panic ${where}\n"
bail $with
}
proc bailsig {} {
global e_intr
bail $e_intr
}
signal trap SIGINT bailsig
log_file "runme.log"
spawn {*}$spawncmd
# Wait for the system to boot
set timeout 10
expect {
-ex "\n$ " {}
-regex "${panicre}" { paniced "booting" $e_earlypanic }
timeout { send_user "Failure: time out booting\n"
bail $e_earlyout
}
}
set cmdline "[join $argv]"
for {set iter 0} {$iter < $iters} {incr iter} {
# send_user "===> Harness iteration $iter\n"
send "$cmdline\n"
set timeout 2
expect {
-re "(?p)${cmdline}\r(?=\n)"
{ # send_user "===> shell OK "
}
timeout
{ # send_user "Failure: timeout waiting for shell echo"
bail $e_loadout
}
}
# Wait for the test to start and tell us how many
# success lines we should expect
set timeout 10
while {! [info exists ntests]} {
expect {
-regex "${pfx}${tname} 1\\.\\.(\\d*)\r"
{ global ntests
set ntests "$expect_out(1,string)"
}
-regex "${pfx}${tname} Bail out!${eol}"
{ send_user "Bail out before start\n"
bail $e_loadfail
}
-ex "^\n$ "
{ send_user "Fail: prompt while waiting to start up (did exec fail?)\n"
bail $e_loadprompt
}
# unanchored!
-regex "${panicre}" { paniced "while loading" $e_loadpanic }
# Consume other outputs and discard as if they were comments
# This must come as the last pattern that looks at input
-regex "(?p).${eol}" { }
timeout
{ send_user "Failure: time out getting started\n"
bail $e_loadout
}
eof
{ send_user "Failure: EOF on TAP stream\n"
bail $e_loadeof
}
}
}
# Wait for that many tests to pass
set timeout 60
set exitwith $e_ok
for {set this 0} {$this < $ntests} {incr this} {
expect {
-regex "${pfx}${tname} #${eol}"
{ incr this -1
# '$expect_out(buffer)'
# send_user "===> Harness got comment\n"
}
-regex "${pfx}${tname} ok ${eol}"
{ # send_user "===> Harness acknowledge OK! ${this}\n"
}
-regex "${pfx}${tname} not ok ${eol}"
{ send_user "Failure in simulation\n"
set exitwith $e_fail
}
-regex "${pfx}${tname} Bail out!${eol}"
{ send_user "Bail out in simulation\n"
bail $e_bail
}
-ex "^\n$ "
{ send_user "Failure: prompt after ${this} tests\n"
bail $e_tooshort
}
-regex "${panicre}" { paniced "while testing" $e_panic }
# Consume other outputs and discard as if they were comments
# This must come as the last pattern that looks at input
-regex "(?p).${eol}"
{ # send_user "===> Some other line\n"
incr this -1
}
timeout
{ send_user "Failure: time out\n"
send \020
sleep 5
bail $e_timeout
}
eof
{ send_user "Failure: EOF on TAP stream\n"
bail $e_eof
}
}
}
# Hang around for a prompt
set timeout 10
while {1} {
expect {
-regex "${pfx}${tname} \[^#\].*${eol}"
{ set exitwith $e_toolong
send_user "Warning! Unexpected test line\n"
}
-ex "\n$ " { break }
timeout { send_user "Failure: prompt time out (program hung?)\n"
bail $e_lasthang
}
eof { send_user "Failure: EOF on TAP stream\n"
bail $e_lasteof
}
}
}
}
bail $exitwith