set self parse-semok set test_suffix "parse-semok" # This test is somewhat similar to # testsuite/parseok/unparser.stp. Here we're going to: # # 1) See if a systemtap script passes -p2, so we know the script is # semantically correct. # 2) If so, try running the output of -p1 (parsed output) through # -p2. If this passes, we know the parsed output is also semantically # correct. # # If we get any failures here, then we know the parsed output isn't # semantically corect. # Create a temporary directory we can use. if {[catch {exec mktemp -d -t staptestXXXXXX} tmpdir]} { verbose -log "Failed to create temporary directory: $tmpdir" return } # Notice that by default we're just testing the scripts in the # 'buildok' (pass 4) directory. If "verbose" is on, we also test the # scripts in the 'semok' (pass 2) and 'transok' (pass 3) directories. # # Notice we never test the scripts in the 'parseok' directory, since # those tests are designed to be parsed (-p1), but aren't necessarily # semantically correct (i.e. they might not pass -p2). if { $verbose } { set dirlist [list semok transok buildok] } else { set dirlist [list buildok] } foreach dir $dirlist { foreach file [lsort [glob -nocomplain $srcdir/$dir/*.stp]] { set test "${dir}/[file tail $file]" set full_test "${test} ${test_suffix}" set extra_args "" # Most of the "ok" test cases use '#! stap ...'. Try to read # this information. set f [open $file r] set firstbits [gets $f] close $f if [regexp -line {\#! stap (.*)} $firstbits -> stap_args] { # Parse arguments. set arg_fail 0 foreach arg $stap_args { if {[ string index $arg 0 ] != "-" } { break } set ch_idx 1 while {1} { set opt_ch [ string index $arg $ch_idx ] if { $opt_ch == "" } { break } incr ch_idx switch $opt_ch { p { # Ignore "pass" options. incr ch_idx; continue } g { append extra_args " -g"; continue } t { append extra_args " -t"; continue } w { append extra_args " -w"; continue } v { append extra_args " -v"; continue } W { append extra_args " -W"; continue } u { append extra_args " -u"; continue } - { # Handle long arguments ("--FOO") by just # adding them. append extra_args " $arg"; break } default { verbose -log "unknown argument '${opt_ch}'" set arg_fail 1 break } } } } if {$arg_fail == 0} { pass "${full_test} - arg parsing" } else { fail "${full_test} - arg parsing" continue } } else { # If "stap" wasn't on the first line of the script, this isn't # a systemtap script, but a shell script that will run # systemtap. We'll have to skip these. untested "$full_test - shell script" continue } # 1) See if the script is semantically correct. set cmd [concat stap -p2 ${extra_args} ${file}] verbose -log "Running $cmd" if {[catch {eval exec ${cmd}} res]} { verbose -log "$res" untested "${full_test} - not semok" continue } pass "${full_test} - semok" # 2) The test is semantically correct. Now let's see if the parsed # output is semantically correct. # 2a) First, get the parsed output. This should work since it # passed -p2 above (so -p1 should work). set tmpfile "${tmpdir}/[file rootname [file tail $file]].p1" set cmd [concat stap -p1 ${extra_args} ${file} > ${tmpfile}] verbose -log "Running $cmd" if {[catch {eval exec ${cmd}} res]} { verbose -log "$res" fail "${full_test} - parsing?" continue } pass "${full_test} - parsing" # 2b) See if the -p1 output is semantically correct. set cmd [concat stap -p2 ${extra_args} ${tmpfile}] verbose -log "Running $cmd" if {[catch {eval exec ${cmd}} res]} { verbose -log "$res" fail "${full_test} - parsed output is not semok" continue } pass "${full_test} - parsed output is semok" } } # Cleanup if { $verbose == 0 } { catch {exec /bin/rm -rf $tmpdir} }