In SLES15 SP6 on x86_64 I'm using a bash script and expect-5.45.4 to do automated program testing.
Basically I'm checking whether the program to test (./pwg.pl
) outputs a specific string.
Starting to write my test script, the first invocations all worked as expected, but one case fails to match the output, even if it is there!
(This may look like a needlessly complicated, but that's just one trivial test case for the program)
./pwg.pl --show-entropy --verbose=1 '{!/SG:25}ABCDEfghijKLMOP{T/S:R=1}'
parse_cookie({!/SG:25}ABCDEfghijKLMOP{T/S:R=1})
ABCDEfghijKLMOP
1 states, 0.0 bits
The string to check for is ABCDEfghijKLMOP
, and it is output using print
with a trailing "\n"
in Perl, and all output is writing to STDOUT
.
However when tracing my expect
script I see:
spawn ./pwg.pl --show-entropy --verbose=1 ./pwg.pl --show-entropy --verbose=1 {!/SG:25}ABCDEfghijKLMOP{T/S:R=1}
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {829}
expect: does "" (spawn_id exp6) match glob pattern "\r\nABCDEfghijKLMOP\r\n"? no
parse_cookie(./pwg.pl --show-entropy --verbose=1 {!/SG:25}ABCDEfghijKLMOP{T/S:R=1})
expect: does "parse_cookie(./pwg.pl --show-entropy --verbose=1 {!/SG:25}ABCDEfghijKLMOP{T/S:R=1})\r\n" (spawn_id exp6) match glob pattern "\r\nABCDEfghijKLMOP\r\n"? no
./pwg.pl --show-entropy --verbose=1 ABCDEfghijKLMOP
expect: does "parse_cookie(./pwg.pl --show-entropy --verbose=1 {!/SG:25}ABCDEfghijKLMOP{T/S:R=1})\r\n./pwg.pl --show-entropy --verbose=1 ABCDEfghijKLMOP\r\n" (spawn_id exp6) match glob pattern "\r\nABCDEfghijKLMOP\r\n"? no
1 states, 0.0 bits
expect: does "parse_cookie(./pwg.pl --show-entropy --verbose=1 {!/SG:25}ABCDEfghijKLMOP{T/S:R=1})\r\n./pwg.pl --show-entropy --verbose=1 ABCDEfghijKLMOP\r\n1 states, 0.0 bits\r\n" (spawn_id exp6) match glob pattern "\r\nABCDEfghijKLMOP\r\n"? no
expect: read eof
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "parse_cookie(./pwg.pl --show-entropy --verbose=1 {!/SG:25}ABCDEfghijKLMOP{T/S:R=1})\r\n./pwg.pl --show-entropy --verbose=1 ABCDEfghijKLMOP\r\n1 states, 0.0 bits\r\n"
FAILED
### FAILED
So the point is that expect
seems to repeat the command invocation string in the output while dropping the essential new-line (\n\r
).
The test script goes like this:
PWG='./pwg.pl --show-entropy --verbose=1'
# run command under expect
expect_output()
{
typeset -r expected="$1"; shift
expect <<EOI
log_user 1
exp_internal 1
spawn $PWG "$@"
expect {
"$expected" {
#puts "OK"
exit 0
}
timeout {
puts "No response"
exit 1
}
eof {
puts "FAILED"
exit 1
}
}
EOI
local EC=$?
[ $EC -eq 0 ] && echo '### OK' || echo '### FAILED'
return $EC
}
expect_output '\r\nABCDEfghijKLMOP\r\n' \
$PWG '{!/SG:25}ABCDEfghijKLMOP{T/S:R=1}'
exit
Just in case:
./pwg.pl --show-entropy --verbose=1 '{!/SG:25}ABCDEfghijKLMOP{T/S:R=1}' | hexdump -C
00000000 70 61 72 73 65 5f 63 6f 6f 6b 69 65 28 7b 21 2f |parse_cookie({!/|
00000010 53 47 3a 32 35 7d 41 42 43 44 45 66 67 68 69 6a |SG:25}ABCDEfghij|
00000020 4b 4c 4d 4f 50 7b 54 2f 53 3a 52 3d 31 7d 29 0a |KLMOP{T/S:R=1}).|
00000030 41 42 43 44 45 66 67 68 69 6a 4b 4c 4d 4f 50 0a |ABCDEfghijKLMOP.|
00000040 31 20 73 74 61 74 65 73 2c 20 30 2e 30 20 62 69 |1 states, 0.0 bi|
00000050 74 73 0a |ts.|
00000053
So I wonder whether it's a bug in expect causing that effect, or did I use expect incorrectly?
I feel stupid (thanks to @ikegami for helping me):
The bug is in the script building the expect
command:
when writing expect_output()
I had realized that each invocation will use $PWG
(that's why I had put it into a variable) , so I thought I could implicitly use it inside expect_output()
when converting my commands not using expect to those using it.
Doing that I forgot that I don't have to (and actually I should not) pass $PWG
as argument to expect_output()
.
So what spawn $PWG "$@"
actually executes is spawn $PWG "$PWG" ...
when calling expect_output something $PWG ...
.
And one of the features of $PWG
is to output anything from the command-line it does not understand.
Thus the strange-looking context for ...
(actually "ABCDEfghijKLMOP").