Expect-Lite   Tips and Techniques

Simplifying the Debugging of Expect-lite scripts



Introduction

Over the years of using and improving expect-lite, a few debugging techniques have proven quite useful. The purpose of the document is to provide some additional information to assist the user of expect-lite in debugging scripts, and tips to make expect-lite script writing even easier. Familiarity with expect-lite is assumed, if not, please refer to the expect-lite documentation.

Contents

Some Tips and Techniques for expect-lite:

Interact

Since expect-lite is actually a wrapper for expect, and since it also supports embedded expect commands, the following may be the quickest, easiest, and overall best debugging aid: 
!interact +++ return
>
Expect-lite will pause at this point in the script, and connect the keyboard to the remote session (which may be at a prompt). Any command may be entered and responses observed. Typing '+++' (3 pluses) will return control to the script, and it will continue.

Fail then Interact

There is a secret back door to expect-lite, which reverses a script failure. Instead of halting and failing, the script can use the fail script (a special include script) mechanism to include a debugging aid.

Add the following debugging script near the beginning of the script which is being debugged:
*~debug.inc

The actual debugging script is as follows:
#
# debug.inc
#

; Press '+++' to end interactive session
>
!interact +++ return
>
# allow script to continue
!set _el(continue) 1
>
; === Continuing Script
>

When a script fails, it will print the usual command failed, and what it was expecting, then expect-lite will call the fail script (debug.inc). Once debug.inc is run, it drops the user into interact mode. This provides the opportunity to fix the error (perhaps there was a missing command). Once the fix is done, typing '+++' will return from the interact session and the script will continue (in this case, still debug.inc).

Now this is where the secret backdoor part comes in. There is a line of embedded expect in debug.inc:
!set _el(continue) 1
This tells expect-lite to not halt the test, but in fact, to continue the test as if no failure had occurred (very sneaky). Lastly, debug.inc prints into the log that it is continuing the script, and at the end of debug.inc, control is returned to the buggy script right after the failure point and continues.

This little script is such a great tool for debugging, that we found it invaluable and put it into all our scripts. Note: be sure to remove the reference to debug.inc before putting the now-bug-free script into production.

Finding In... Verbose

Since most expect-lite scripts are composed of > and < lines, it can be difficult to understand why expect-lite isn't finding the desired text. Using the -v or --verbose option (in version 3.1.3 or later) will display the string that is to be matched (find) and the entire string that is being searched (in).

For example, for the given expect-lite code:
>cat $tmp_file
<Proto \[LAN\]Addr:Port => Addr:Port \[WAN\]Addr:Port <= Addr:Port
<6[ \t]+[0-9a-f:]{11,14}[ \t]+[0-9a-f]{8}:22
With the --show_forest option, the output will appear with the additional lines:
cat /proj/regression/tmp/junk
Dec 31 1969 19:43:12:025952:INFO :CLI :cli.c:2945:_cli_handle_short_cmd:
Execute command: "fwdstat".
Proto [LAN]Addr:Port => Addr:Port [WAN]Addr:Port <= Addr:Port
6 c0a85001:41696 c0a81401:22 c0a81401:22 c0a81402:32770

find<<Proto \[LAN\]Addr:Port => Addr:Port \[WAN\]Addr:Port <= Addr:Port>>
in<<cat /proj/regression/tmp/junk
Dec 31 1969 19:43:12:025952:INFO :CLI :cli.c:2945:_cli_handle_short_cmd:
Execute command: "fwdstat".
Proto [LAN]Addr:Port => Addr:Port [WAN]Addr:Port <= Addr:Port>>

find<<6[ \t]+[0-9a-f:]{11,14}[ \t]+[0-9a-f]{8}:22>>
in<<
6 c0a85001:41696 c0a81401:22>>
Both the 'find' and 'in' text are wrapped in << >> to show any line feeds. The 'find', if successful, will almost always be at the bottom of the 'in' text. Often when there is a unexpected failure, the  '<' is defined too broadly, and expect-lite has matched an unexpected piece of 'in' text. (see Define '<' narrowly)

Showing Variables & Values

Sometimes when troubleshooting a script, it is really useful to display the value of an expect-lite variable. The easiest method to display a variable is to use the printable comment ';'  For example, there is a variable named '$max', by adding the following line to the script, $max will be dereferenced and displayed:
; The value of max is:$max
The above method works well for a few variables, but it may be neccessary to view all the expect-lite variables. Using the following include script, show_vars.inc, in the expect-lite script will display all the assigned variables:
# Shows all defined expect-lite Vars
; === Show all Vars Defined
!set var_list [array names user_namespace]
!set var_list_sorted [lsort $var_list]
!foreach i $var_list_sorted {
! puts "Var:$i \t\t\Value:$user_namespace($i)"
!}
>
>sleep 1
>

Including the show_vars script with the following line in the script to be debugged:
~show_vars.inc
The include script is written in embedded expect and will walk the array of expect-lite variables, and print their respective values. The output will appear like the following:
 === Show all Vars Defined

Var:count Value:14
Var:first Value:this is a regression test line
Var:gen10 Value:test10
Var:gen11 Value:test11
Var:gen12 Value:test12
Var:gen13 Value:test13
...
Var:mac_da12 Value:38:8B:50:49:AE:0D
Var:mac_da13 Value:38:E4:EB:0C:DE:4B
The include script, show_vars.inc, is included in the expect-lite release (as of version 3.1.3)

Define '<' narrowly

Do not define '<' too broadly. For example, DO NOT use the following:
<\n.*
The above defines 0 or more of any character after a newline. This will match just about anything, and more than likely not what is intended.

Instead use a more specific '<'. If the expected string is only composed of numbers at the beginning of a line, use:
<\n[0-9]+
Use with the --verbose option to see what is being matched, and to assist in refining the '<' statements.

General Tips

Here are some simple tips when script writing:

Summary

By using these troubleshooting aids, it should be even easier to write and debug expect-lite scripts. Feel free to send me any tips. cvmiller at sourceforge dot net

Why Expect-lite

Expect-lite was written to create quick and easy automation of repetitive tasks.



8 July 2008
http://expect-lite.sourceforge.net/

this document for version 3.1.3 or later