blob: d0f3d4b1fdb10c4883ebbaadd48d4ff96e94f77b [file] [log] [blame]
aPiecek0ebc35b2023-06-22 14:11:58 +02001# @brief Common functions and variables for Tool Under Test (TUT).
2#
3# The script requires variables:
4# TUT_PATH - Assumed absolute path to the directory in which the TUT is located.
5# TUT_NAME - TUT name (without path).
6#
7# The script sets the variables:
8# TUT - The path (including the name) of the executable TUT.
9# error_prompt - Delimiter on error.
10# error_head - Header on error.
11
aPiecek266ca762023-03-22 15:04:59 +010012package require Expect
13
aPiecek0ebc35b2023-06-22 14:11:58 +020014# Complete the path for Tool Under Test (TUT). For example, on Windows, TUT can be located in the Debug or Release
15# subdirectory. Note that Release build takes precedence over Debug.
16set conftypes {{} Release Debug}
17foreach i $conftypes {
18 if { [file executable "$TUT_PATH/$i/$TUT_NAME"] || [file executable "$TUT_PATH/$i/$TUT_NAME.exe"] } {
19 set TUT "$TUT_PATH/$i/$TUT_NAME"
20 break
21 }
22}
23if {![info exists TUT]} {
24 error "$TUT_NAME executable not found"
aPiecek266ca762023-03-22 15:04:59 +010025}
26
aPiecek0ebc35b2023-06-22 14:11:58 +020027# prompt of error message
28set error_prompt ">>>"
29# the beginning of error message
30set error_head "$error_prompt Check-failed"
aPiecek266ca762023-03-22 15:04:59 +010031
32# detection on eof and timeout will be on every expect command
33expect_after {
34 eof {
35 global error_head
36 error "$error_head unexpected termination"
37 } timeout {
38 global error_head
39 error "$error_head timeout"
40 }
41}
42
43# Run commands from command line
44tcltest::loadTestedCommands
45
46# namespace of internal functions
47namespace eval ly::private {}
48
aPiecek266ca762023-03-22 15:04:59 +010049# Send command 'cmd' to the process, then check output string by 'pattern'.
50# Parameter cmd is a string of arguments.
51# Parameter pattern is a regex or an exact string to match. If is not specified, only prompt assumed afterwards.
52# It must not contain a prompt. There can be an '$' character at the end of the pattern, in which case the regex
53# matches the characters before the prompt.
54# Parameter 'opt' can contain:
55# -ex has a similar meaning to the expect command. The 'pattern' parameter is used as a simple string
56# for exact matching of the output. So 'pattern' is not a regular expression but some characters
57# must still be escaped, eg ][.
58proc ly_cmd {cmd {pattern ""} {opt ""}} {
59 global prompt
60
61 send -- "${cmd}\r"
62 expect -- "${cmd}\r\n"
63
64 if { $pattern eq "" } {
65 # command without output
66 expect ^$prompt
67 return
68 }
69
70 # definition of an expression that matches failure
71 set failure_pattern "\r\n${prompt}$"
72
73 if { $opt eq "" && [string index $pattern end] eq "$"} {
74 # check output by regular expression
75 # It was explicitly specified how the expression should end.
76 set pattern [string replace $pattern end end]
77 expect {
78 -re "${pattern}\r\n${prompt}$" {}
79 -re $failure_pattern {
80 error "unexpected output:\n$expect_out(buffer)"
81 }
82 }
83 } elseif { $opt eq "" } {
84 # check output by regular expression
85 expect {
86 -re "${pattern}.*\r\n${prompt}$" {}
87 -re $failure_pattern {
88 error "unexpected output:\n$expect_out(buffer)"
89 }
90 }
91 } elseif { $opt eq "-ex" } {
92 # check output by exact matching
93 expect {
94 -ex "${pattern}\r\n${prompt}" {}
95 -re $failure_pattern {
96 error "unexpected output:\n$expect_out(buffer)"
97 }
98 }
99 } else {
100 global error_head
101 error "$error_head unrecognized value of parameter 'opt'"
102 }
103}
104
aPiecek0ebc35b2023-06-22 14:11:58 +0200105# Send command 'cmd' to the process, expect some header and then check output string by 'pattern'.
106# This function is useful for checking an error that appears in the form of a header.
107# Parameter header is the expected header on the output.
aPiecek266ca762023-03-22 15:04:59 +0100108# Parameter cmd is a string of arguments.
109# Parameter pattern is a regex. It must not contain a prompt.
aPiecek0ebc35b2023-06-22 14:11:58 +0200110proc ly_cmd_header {cmd header pattern} {
aPiecek266ca762023-03-22 15:04:59 +0100111 global prompt
112
113 send -- "${cmd}\r"
114 expect -- "${cmd}\r\n"
115
116 expect {
aPiecek0ebc35b2023-06-22 14:11:58 +0200117 -re "$header .*${pattern}.*\r\n${prompt}$" {}
aPiecek266ca762023-03-22 15:04:59 +0100118 -re "\r\n${prompt}$" {
119 error "unexpected output:\n$expect_out(buffer)"
120 }
121 }
122}
123
124# Whatever is written is sent, output is ignored and then another prompt is expected.
125# Parameter cmd is optional and any output is ignored.
126proc ly_ignore {{cmd ""}} {
127 global prompt
128
129 send "${cmd}\r"
130 expect -re "$prompt$"
131}
132
133# Send a completion request and check if the anchored regex output matches.
134proc ly_completion {input output} {
135 global prompt
136
137 send -- "${input}\t"
138 # expecting echoing input, output and 10 terminal control characters
aPiecek0ebc35b2023-06-22 14:11:58 +0200139 expect -re "^${input}\r${prompt}${output}.*\r.*$"
aPiecek266ca762023-03-22 15:04:59 +0100140}
141
142# Send a completion request and check if the anchored regex hint options match.
143proc ly_hint {input prev_input hints} {
aPiecek0ebc35b2023-06-22 14:11:58 +0200144 global prompt
145
aPiecek266ca762023-03-22 15:04:59 +0100146 set output {}
147 foreach i $hints {
148 # each element might have some number of spaces and CRLF around it
149 append output "${i} *(?:\\r\\n)?"
150 }
151
152 send -- "${input}\t"
153 # expecting the hints, previous input from which the hints were generated
154 # and some number of terminal control characters
aPiecek0ebc35b2023-06-22 14:11:58 +0200155 expect -re "${output}\r${prompt}${prev_input}.*\r.*$"
aPiecek6e5844c2023-05-22 11:42:09 +0200156}