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
|
set test "Server Argument Test"
# Each test will take 3 seconds or more due to the use of avahi to browse for
# servers, so limit iterations to some small but reasonable number.
set iterations 10
# Allow seeding the random number generator using an environment variable in
# order to facilitate reproducing a given series of tests. Otherwise seed it
# using the current time.
if [info exists env(STAP_RANDOM_SEED)] {
set random_seed $env(STAP_RANDOM_SEED)
} else {
set random_seed [clock seconds]
}
verbose -log "Random seed is $random_seed"
expr srand($random_seed)
proc stap_direct_and_with_client {stap stap_client options} {
# tcl's 'eval' creates a string containing the arguments and
# recursively passes it to the tcl interpreter. Special
# characters need to be quoted.
regsub -all "\[\"\\\\;\]" $options {\\\0} options
regsub -all "\[\n\]" $options {\\n} options
verbose -log "eval exec $stap $options"
catch {eval exec $stap $options} res_stap
verbose -log $res_stap
# Now run it against stap-client
verbose -log "eval exec $stap_client $options"
catch {eval exec $stap_client $options} res_stap_client
verbose -log $res_stap_client
# Now check the output
set n 0
set expected [split $res_stap "\n"]
set received [split $res_stap_client "\n"]
foreach line $received {
set expected_line [lindex $expected $n]
# Some messages contain the names of files or directories
# and will be prefixed for the client.
if {[regexp "^ (.*)" $expected_line match data]} {
# Special characters in the regexp need to be quoted.
regsub -all "\[\"\\\\;\*\]" $data {\\\0} data
if {[regexp "^ tapsets.*/$data" $line]} {
incr n
continue
}
if {[regexp "^ runtime.*/$data" $line]} {
incr n
continue
}
# Some messages contain the name of the module based on the
# process id.
if {[regexp "^ stap_\[0-9\]*" $expected_line] &&
[regexp "^ stap_\[0-9\]*" $line]} {
incr n
continue
}
} elseif {[regexp "^Input file '(.*)' is empty or missing." $expected_line match data]} {
# Special characters in the regexp need to be quoted.
regsub -all "\[\"\\\\;\*\]" $data {\\\0} data
if {[regexp "^Input file 'script.*/$data' is empty or missing." $line]} {
incr n
continue
}
} elseif {[regexp "^(.*/stap): (.*)" $line match data1 data2]} {
# Special characters in the regexp need to be quoted.
regsub -all "\[\"\\\\;\*\]" $data2 {\\\0} data2
if {[regexp "^$stap: $data2" $expected_line]} {
incr n
continue
}
}
# Otherwise the output must be identical.
if {! [string equal $line $expected_line]} {
break
}
incr n
}
if {$n == [llength $expected] && [llength $expected] == [llength $received]} {
# Test passes
return 1
}
# Test fails
send_log "line [expr $n + 1]:\n"
send_log "Expected: \"[lindex $expected $n]\"\n"
send_log "Got : \"$line\"\n"
return 0
}
# ************ Start of mainline *************
# Don't attempt these tests if the client/server are not available
# Start a systemtap server, if one is not already started.
if {! [use_server_p]} then {
if {! [setup_server]} then {
untested "$test"
return
}
}
# Make sure we call the correct instances of stap and stap-client.
# There is a copy of 'stap-client' on the PATH as 'stap'.
if {[installtest_p]} then {
# For 'make installcheck', use both from the location of the actual
# stap-client on the PATH.
set stap_client [exec which stap-client]
set stap [exec dirname $stap_client]/stap
} else {
# For 'make check' use stap-client from the source tree and use stap from
# the build tree.
set stap_client $srcdir/../stap-client
set stap [exec pwd]/../stap
}
# Test some argument strings which have failed in the past. This is useful
# for debugging a currently failing case and helps to ensure that previously
# fixed cases do not regress.
set previously_fixed [list \
"-p1 -I=\\w94\nbh -e -Dhfuo0iu7 -c" \
"-p1 -I8o\\2ie -e'1\\ -D\n\" -c" \
"-p1 -Ira\\3;c g -e0fle'qq -Dr/316k\\o8 -cjyoc\n3" \
"-p1 -I6p3 -elc -Dqgsgv' -c" \
"-p1 -I\"vyv;z -ej\"/3 -D/ 01qck\n -c3u55zut" \
"-p1 -I1 -eo9e\nx047q -D9xyefk0a -cvl98/x1'i" \
"-p1 -c; test.stp" \
"-p1 -I4hgy96 -e5oo39p -Ddx8v -c4;" \
"-p1 -I -esq3wors -Dz -c*eibz8h2e" \
"-p1 -I a -em339db5 -Du2;c0ps -ch9o\\" \
"-p1 -Ipfjps4 -ebug4dc -Du8vd fvkl -c" \
"-p1 -I0\"nspzjyf -e5r3up8h -Dmi;ojp9m -cx;a2fat" \
"-p1 -Iu -ek7;r -Dcu\"; -c\"hc" \
"-p1 -Icd4fidq m40mv -edn -D;8ha\\cjr -c1*vnq" \
"-p1 -I;3 -er8e -D -cb6k29z" \
"-p1 -Ircj -e -D -c\\vmww" \
"-p1 -Illc5 -e65wof9 qr*=x7x5 -D -cgx;" \
"-p1 -Iyaj420=3 -e\" -D -cd'5mi" \
"-p1 -Ir -e -D29\\ -cj2szt;4" \
"-p1 -Ibno3=b4sk -e' -Dg2-j;e -c2ijx'" \
"-p1 -I285v7pl -eo5\\0 -D86s -c-c*v" \
]
set i 0
foreach options $previously_fixed {
if {[stap_direct_and_with_client $stap $stap_client $options]} {
pass "$test $i"
} else {
fail "$test $i"
}
incr i
}
# Generate semi-random arguments containing with potential problem characters.
# Check that running systemtap with the client/server generates output
# comparable to running stap directly.
set dangerous_options [list "-I" "-e" "-D" "-c" "-S"]
# NB: Other options could be candidates here, like -r and -B, but
# there stap-server imposes more restrictions than local stap, so
# this simple error-matching test cannot use them.
set argchars "0123456789/;*'=-\\\"\n abcdefghijklmnopqrstuvwxyz"
for {set i 0} {$i < $iterations} {incr i} {
verbose -log "Iteration $i"
# First generate an argument string
set options "-p1"
foreach option $dangerous_options {
set options "$options $option"
set limit [expr int(rand() * 10)]
for {set c 0} {$c < $limit} {incr c} {
set options "$options[string index $argchars [expr int(rand() * [string length $argchars])]]"
}
}
# Now test it against stap and stap-client
if {[stap_direct_and_with_client $stap $stap_client $options]} {
pass "Fuzzing $test $i"
} else {
fail "Fuzzing $test $i"
}
}
# Shudown the server, if we started it.
if {! [use_server_p]} then {
shutdown_server
}
|