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 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
|
# bpf.exp
#
# To restrict scripts to test, set the CHECK_ONLY environment variable.
# For example, to only test the printf and uprobes scripts, run:
#
# make installcheck RUNTESTFLAGS="bpf.exp" CHECK_ONLY="printf uprobes"
set testdir "$srcdir/$subdir/bpf_tests"
set targettestdir "$srcdir/$subdir/bpf_target_tests"
# Skip irrelevant environment.
if {![bpf_p]} {
untested "bpf.exp"
return
}
# This testcase takes long time on s390x and fails after that. Skip it.
if { "$::tcl_platform(machine)" == "s390x" } {
untested "bpf.exp"
return
}
# All tests should start by printing "BEGIN". If OUTPUT_STR is "", then
# the test passes if "END PASS" is read and fails if "END FAIL" is read. Otherwise
# the test passes when "${OUTPUT_STR}END" is read and fails if END is read without
# OUTPUT_STR preceeding it.
proc stapbpf_run { TEST_NAME OUTPUT_STR options args } {
global rc
set rc -1
set begin_str "BEGIN"
set pass_str [expr { $OUTPUT_STR == "" ? "END PASS" : "${OUTPUT_STR}END" }]
set fail_str [expr { $OUTPUT_STR == "" ? "END FAIL" : "END" }]
# return codes
set pass 0
set fail 1
set bad_output 2
set eof_start 3
set eof_end 4
set timeout_start 5
set timeout_end 6
set invalid_prog 7
set comp_err 8
set cmd [concat stap -v --runtime=bpf $options $args]
# don't the following: ... $test_file_name could be some transient or leftover file
# if [file readable $test_file_name] { lappend cmd $test_file_name }
# child process, only for some commands not using -c
set mypid2 0
send_log "executing: $cmd\n"
eval spawn $cmd
set mypid [exp_pid -i $spawn_id]
expect {
# increased timeout due to slow uncached query for bpf tracepoints
-timeout 300
-re {^WARNING: cannot find module [^\r]*DWARF[^\r]*\r\n} {exp_continue}
-re {^WARNING: No unwind data for /.+\r\n} {exp_continue}
-re {^Pass\ ([1234]):[^\r]*\ in\ ([0-9]+)usr/([0-9]+)sys/([0-9]+)real\ ms\.\r\n}
{set pass$expect_out(1,string) "\t$expect_out(2,string)\t$expect_out(3,string)\t$expect_out(4,string)"; exp_continue}
-re {^Pass\ ([34]): using cached [^\r]+\r\n}
{set pass$expect_out(1,string) "\t0\t0\t0"; exp_continue}
-re {^Passes: via server [^\r]* using [^\r]* in [0-9]+usr/[0-9]+sys/[0-9]+real ms\.\r\n} {exp_continue}
-re {^Pass 5: starting run.\r\n} {exp_continue}
-re $begin_str {
# By default, "expect -re" will match up to 2000 chars.
# Increase this to 8K worth of data.
exp_match_max 8192
# create a child process for the tests that require one
switch $TEST_NAME {
user_string.stp {
eval exec /usr/bin/sleep 2
}
}
# Avoid PR17274 to propagate
set origexpinternal 1
if {"[exp_internal -info]" == "0"} {set origexpinternal 0}
#exp_internal 0
expect {
-timeout 20
-re "stack smashing detected" {
set rc $bad_output
}
-re $pass_str {
set rc $pass
}
-re $fail_str {
set rc $fail
}
default {
set rc $bad_output
}
timeout {
set rc $timeout_end
kill -INT -$mypid
}
eof { set rc $eof_end }
}
exp_internal $origexpinternal
}
-re "semantic error:" { set rc $comp_err }
-re "bpf program load failed:" { set rc $invalid_prog }
timeout {
set rc $timeout_start
kill -INT -$mypid
}
eof { set rc $eof_start }
}
# again for good measure with KILL after 3s
kill -KILL -$mypid 3
catch close
wait
return $rc
}
proc get_output_str { test } {
global res
switch -glob $test {
printf.stp { set res [string repeat "abcd123456" 3] }
sprintf.stp { set res [string repeat "0123456789" 2] }
string1.stp { set res {begin\[str0str1str2str3\]probe\[str0str1str2str3\]end\[str0str1str2str3\]} }
string*.stp { set res {probe0\[str0str1str2str3\]probe1\[str0str1str2str3\]end\[str0str1str2str3\]} }
target.stp { set res {[12345]} }
default { set res "" }
}
return $res
}
if {[info exists env(CHECK_ONLY)]} {
set all_files [lsort [glob -nocomplain $testdir/*.stp $targettestdir/*.stp]]
set stap_files ""
foreach file $env(CHECK_ONLY) {
if {[lsearch $all_files $testdir/$file.stp] >= 0} {
set stap_files "$stap_files $testdir/$file.stp"
}
if {[lsearch $all_files $targettestdir/$file.stp] >= 0} {
set stap_files "$stap_files $targettestdir/$file.stp"
}
}
} else {
set stap_files [lsort [glob -nocomplain $testdir/*.stp $targettestdir/*.stp]]
}
# Compile helper program; XXX skip -O flag to avoid inlining functions
set res [target_compile $srcdir/$subdir/bpf-target.c ./a.out executable \
"additional_flags=-g"]
if {$res ne ""} {
verbose "target_compile failed: $res" 2
fail "bpf.exp: unable to compile bpf-target.c"
}
foreach file $stap_files {
global mypid
set mypid 0
set test [file tail $file]
# bpf_tests or bpf_target_tests:
set testtype [file tail [file dirname $file]]
if {! [installtest_p]} { untested $test; continue }
if {! [bpf_p]} { untested $test; continue }
# create a process for the tests that require one
switch $test {
uprobes.stp {
eval spawn /usr/bin/sleep 20
set mypid [exp_pid -i $spawn_id]
}
}
# Add compatible option for some tests that require them
switch $test {
cast_op_tracepoint.stp { set options "--compatible=4.1" }
reg_alloc3.stp { set options "--compatible=4.1" }
tracepoint1.stp { set options "--compatible=4.1" }
default { set options "" }
}
# Add -c/-x option for some tests that require them
if {"$testtype" == "bpf_target_tests"} {
set options "-c ./a.out $options"
} else {
set options "-x 12345 $options"
}
set output_str [get_output_str $test]
verbose -log "Running $file"
set rc [stapbpf_run $test $output_str $options $file]
if {$rc != 0} {
if { "$::tcl_platform(machine)" == "s390x" } {
# The s390x part seems broken at the moment:
_setup_kfail BPF s390x rhel
} else {
# Known failures in other environments:
switch $test {
array.stp {
_setup_kfail BPF ppc64le rhel
_setup_kfail BPF x86_64 fedora
}
array_preinit.stp { _setup_kfail BPF ppc64le rhel }
bigmap1.stp {
_setup_kfail BPF x86_64,aarch64 rhel
_setup_kfail BPF x86_64 fedora
}
cast_op_tracepoint.stp { _setup_kfail BPF x86_64 rhel,fedora }
context_vars1.stp -
context_vars2.stp -
context_vars3.stp { _setup_kfail BPF ppc64le rhel }
globals2.stp {
_setup_kfail BPF ppc64le rhel
_setup_kfail BPF x86_64 fedora
}
globals3.stp { _setup_kfail BPF ppc64le rhel }
kprobes.stp { _setup_kfail BPF ppc64le rhel }
logging1.stp { _setup_kfail BPF x86_64,aarch64,ppc64le rhel }
no_begin_no_end.stp { _setup_kfail BPF x86_64 fedora }
no_end.stp { _setup_kfail BPF x86_64 fedora }
perf1.stp { _setup_kfail BPF x86_64,aarch64,ppc64le rhel }
perf2.stp { _setup_kfail BPF aarch64,ppc64le rhel }
printf.stp { _setup_kfail BPF x86_64 fedora }
reg_alloc3.stp {
_setup_kfail BPF x86_64,aarch64,ppc64le rhel
_setup_kfail BPF x86_64 fedora
}
timer1.stp { _setup_kfail BPF x86_64 rhel }
timer2.stp { _setup_kfail BPF aarch64,ppc64le rhel }
tracepoint1.stp {
_setup_kfail BPF x86_64,aarch64,ppc64le rhel
_setup_kfail BPF x86_64 fedora
}
}
}
}
switch $rc {
0 { pass $test }
1 { fail "$test incorrect result" }
2 { fail "$test unexpected output" }
3 { fail "$test eof (startup)" }
4 { fail "$test eof (shutdown)" }
5 { fail "$test timeout (startup)" }
6 { fail "$test timeout (startup)" }
7 { fail "$test invalid bpf program" }
8 { fail "$test compilation" }
default { fail "$test unknown return value" }
}
if { $mypid > 0 } {
kill -INT -$mypid 3
catch close
wait
}
}
|