# 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" # 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 -x 12345 $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 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 -INT -$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]] set stap_files "" foreach file $env(CHECK_ONLY) { if {[lsearch $all_files $testdir/$file.stp] >= 0} { set stap_files "$stap_files $testdir/$file.stp" } } } else { set stap_files [lsort [glob -nocomplain $testdir/*.stp]] } foreach file $stap_files { global mypid set mypid 0 set test [file tail $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 "" } } 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 } }