tools.exp fixes and additions
- handle_timeout: Added code to tolerate non-existence of expect_out.
- handle_eof: Added code to tolerate non-existence of expect_out.
- expect_wrap: New function.
- send_wrap: New function.
Change-Id: I268c210962a41c6997a8f899e86d5b40be100a34
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/lib/tools.exp b/lib/tools.exp
index a298172..7d0f8f2 100755
--- a/lib/tools.exp
+++ b/lib/tools.exp
@@ -14,6 +14,9 @@
# description A description of what was being expected
# (e.g. "an SOL login prompt").
+ global spawn_id
+ global expect_out
+
set timeout [get_stack_var timeout {} 2]
if { $timeout == 1 } {
@@ -21,11 +24,13 @@
} else {
set seconds "seconds"
}
+
puts stderr ""
print_error "Did not get ${description} after $timeout ${seconds}.\n"
- puts stderr "The data returned by the spawned process is:\n"
- # Using uplevel to be able to access expect_out(buffer).
- uplevel { puts stderr "$expect_out(buffer)" }
+ # Using uplevel to be able to access expect_out.
+ if { [ catch {uplevel { puts stderr [sprint_var expect_out]}} result ] } {
+ puts stderr [sprint_varx expect_out "<not set>"]
+ }
# If caller has exit_proc defined, call it. Otherwise, just call exit.
if { [info procs "exit_proc"] != "" } {
exit_proc 1
@@ -43,12 +48,14 @@
# description A description of what was being expected
# (e.g. "an SOL login prompt").
- # Using uplevel to be able to access expect_out(buffer).
+ global spawn_id
+
puts stderr ""
print_error "Reached end of file before getting $description.\n"
- puts stderr "The data returned by the spawned process is:\n"
- # Using uplevel to be able to access expect_out(buffer).
- uplevel { puts stderr "$expect_out(buffer)" }
+ # Using uplevel to be able to access expect_out.
+ if { [ catch {uplevel { puts stderr [sprint_var expect_out]}} result ] } {
+ puts stderr [sprint_varx expect_out "<not set>"]
+ }
# If caller has exit_proc defined, call it. Otherwise, just call exit.
if { [info procs "exit_proc"] != "" } {
exit_proc 1
@@ -56,3 +63,127 @@
exit 1
}
+
+
+proc expect_wrap {pattern_list message {timeout 15}} {
+
+ # Run the expect command for the caller and return the list index of the
+ # matching pattern.
+
+ # This function offers the following benefits over calling the expect
+ # command directly:
+ # - It makes program debug easier. When the program is run with --debug=1,
+ # this function prints useful debug output.
+ # - It will do standardized timeout and eof handling.
+
+ # Description of argument(s):
+ # pattern_list A list of patterns to be matched. If one
+ # of the patterns matches, the list index of
+ # the matching item will be returned. By
+ # default, each pattern is presumed to be a
+ # regex. If the caller wishes to, they may
+ # precede each pattern with either of the
+ # following: "-re ", "-gl " or "-ex " in
+ # order to explicitly choose the kind of
+ # match to be done..
+ # message A message explaining what is being
+ # expected (e.g. "an SOL login prompt").
+ # This will be included in output messages.
+ # timeout The expect timeout value.
+
+ # Example usage:
+ # set result [expect_wrap\
+ # [list $bad_user_pw_regex "sh: xauth: command not found"]\
+ # "an SOL prompt" 10]
+ #
+ # switch $result {
+ # 0 {
+ # puts stderr "" ; print_error "Invalid username or password.\n"
+ # exit_proc 1
+ # }
+ # 1 {
+ # dict set state ssh_logged_in 1
+ # }
+ # }
+
+ global spawn_id
+ global expect_out
+
+ # Recognized flags.
+ set flags [list "-re" "-ex" "-gl"]
+
+ # This helps debug efforts by removing leftover, stale entries.
+ array unset expect_out \[1-9\],string
+
+ # Prepare the expect statement.
+ append cmd_buf "global spawn_id\n"
+ append cmd_buf "global expect_out\n"
+ append cmd_buf "expect {\n"
+ set ix 0
+ foreach pattern $pattern_list {
+ # Check to see whether the caller has specified a flag (e.g. "-re",
+ # "-ex", etc.) at the beginning of the pattern.
+ set tokens [split $pattern " "]
+ if { [lsearch $flags [lindex $tokens 0]] != -1 } {
+ # Caller specified a flag.
+ set flag [lindex $tokens 0]
+ # Strip the flag from the pattern.
+ set pattern [string range $pattern 4 end]
+ } else {
+ set flag "-re"
+ }
+ append cmd_buf " ${flag} {$pattern} {set expect_result $ix}\n"
+ incr ix
+ }
+ append cmd_buf " timeout {handle_timeout \$message}\n"
+ append cmd_buf " eof {handle_eof \$message}\n"
+ append cmd_buf "}\n"
+
+ dprint_timen "Expecting $message."
+ dprint_issuing "\n${cmd_buf}"
+ eval ${cmd_buf}
+
+ dprintn ; dprint_vars expect_out expect_result
+
+ return $expect_result
+
+}
+
+
+proc send_wrap {buffer {add_lf 1}} {
+
+ # Send the buffer to the spawned process.
+
+ # This function offers the following benefits over calling the send command
+ # directly:
+ # - It makes program debug easier. When the program is run with --debug=1,
+ # this function prints useful debug output.
+
+ # Description of argument(s):
+ # buffer The string to be sent to the spawned
+ # process.
+ # add_lf Send a line feed after sending the buffer.
+
+ # Example usage.
+ # Close the ssh session.
+ # send_wrap "~."
+ #
+ # set expect_result [expect_wrap\
+ # [list "Connection to $host closed"]\
+ # "a connection closed message" 5]
+
+ global spawn_id
+ global expect_out
+
+ set cmd_buf "send -- {${buffer}}"
+ dprint_issuing
+ eval ${cmd_buf}
+
+ if { $add_lf } {
+ send -- "\n"
+ set cmd_buf "send -- \"\\n\""
+ dprint_issuing
+ eval ${cmd_buf}
+ }
+
+}