blob: 6264b24b18b9d066d908875f14345b95bc019682 [file] [log] [blame]
package require Expect
source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/common.tcl" : "../common.tcl"}]
# set the timeout to 1 second
set timeout 1
# prompt of yanglint
set prompt "> "
# turn off dialog between expect and yanglint
log_user 0
# setting some large terminal width
stty columns 720
variable ly_setup {
spawn $::env(YANGLINT)
ly_skip_warnings
# Searchpath is set, so modules can be loaded via the 'load' command.
ly_cmd "searchpath $::env(YANG_MODULES_DIR)"
}
variable ly_cleanup {
ly_exit
}
# detection on eof and timeout will be on every expect command
expect_after {
eof {
global error_head
error "$error_head unexpected termination"
} timeout {
global error_head
error "$error_head timeout"
}
}
# Run commands from command line
tcltest::loadTestedCommands
# namespace of internal functions
namespace eval ly::private {}
# Skip no dir and/or no history warnings and prompt.
proc ly_skip_warnings {} {
global prompt
expect -re "(YANGLINT.*)*$prompt" {}
}
# Send command 'cmd' to the process, then check output string by 'pattern'.
# Parameter cmd is a string of arguments.
# Parameter pattern is a regex or an exact string to match. If is not specified, only prompt assumed afterwards.
# It must not contain a prompt. There can be an '$' character at the end of the pattern, in which case the regex
# matches the characters before the prompt.
# Parameter 'opt' can contain:
# -ex has a similar meaning to the expect command. The 'pattern' parameter is used as a simple string
# for exact matching of the output. So 'pattern' is not a regular expression but some characters
# must still be escaped, eg ][.
proc ly_cmd {cmd {pattern ""} {opt ""}} {
global prompt
send -- "${cmd}\r"
expect -- "${cmd}\r\n"
if { $pattern eq "" } {
# command without output
expect ^$prompt
return
}
# definition of an expression that matches failure
set failure_pattern "\r\n${prompt}$"
if { $opt eq "" && [string index $pattern end] eq "$"} {
# check output by regular expression
# It was explicitly specified how the expression should end.
set pattern [string replace $pattern end end]
expect {
-re "${pattern}\r\n${prompt}$" {}
-re $failure_pattern {
error "unexpected output:\n$expect_out(buffer)"
}
}
} elseif { $opt eq "" } {
# check output by regular expression
expect {
-re "${pattern}.*\r\n${prompt}$" {}
-re $failure_pattern {
error "unexpected output:\n$expect_out(buffer)"
}
}
} elseif { $opt eq "-ex" } {
# check output by exact matching
expect {
-ex "${pattern}\r\n${prompt}" {}
-re $failure_pattern {
error "unexpected output:\n$expect_out(buffer)"
}
}
} else {
global error_head
error "$error_head unrecognized value of parameter 'opt'"
}
}
# Send command 'cmd' to the process, expect error header and then check output string by 'pattern'.
# Parameter cmd is a string of arguments.
# Parameter pattern is a regex. It must not contain a prompt.
proc ly_cmd_err {cmd pattern} {
global prompt
send -- "${cmd}\r"
expect -- "${cmd}\r\n"
expect {
-re "YANGLINT\\\[E\\\]: .*${pattern}.*\r\n${prompt}$" {}
-re "libyang\\\[\[0-9]+\\\]: .*${pattern}.*\r\n${prompt}$" {}
-re "\r\n${prompt}$" {
error "unexpected output:\n$expect_out(buffer)"
}
}
}
# Send command 'cmd' to the process, expect warning header and then check output string by 'pattern'.
# Parameter cmd is a string of arguments.
# Parameter pattern is a regex. It must not contain a prompt.
proc ly_cmd_wrn {cmd pattern} {
global prompt
send -- "${cmd}\r"
expect -- "${cmd}\r\n"
expect {
-re "YANGLINT\\\[W\\\]: .*${pattern}.*\r\n${prompt}$" {}
-re "\r\n${prompt}$" {
error "unexpected output:\n$expect_out(buffer)"
}
}
}
# Whatever is written is sent, output is ignored and then another prompt is expected.
# Parameter cmd is optional and any output is ignored.
proc ly_ignore {{cmd ""}} {
global prompt
send "${cmd}\r"
expect -re "$prompt$"
}
# Send a completion request and check if the anchored regex output matches.
proc ly_completion {input output} {
global prompt
send -- "${input}\t"
# expecting echoing input, output and 10 terminal control characters
expect -re "^${input}\r> ${output}.*\r.*$"
}
# Send a completion request and check if the anchored regex hint options match.
proc ly_hint {input prev_input hints} {
set output {}
foreach i $hints {
# each element might have some number of spaces and CRLF around it
append output "${i} *(?:\\r\\n)?"
}
send -- "${input}\t"
# expecting the hints, previous input from which the hints were generated
# and some number of terminal control characters
expect -re "${output}\r> ${prev_input}.*\r.*$"
}
# Send 'exit' and wait for eof.
proc ly_exit {} {
send "exit\r"
expect eof
}
# Check if yanglint supports the specified command.
# Parameter cmd is a command to be found.
# Return true if command is found otherwise false.
proc ly_cmd_exists {cmd} {
global prompt
set rc true
spawn $::env(YANGLINT)
ly_skip_warnings
send -- "help\r"
expect -- "help\r\n"
set failure_pattern "\r\n${prompt}$"
expect {
-re "${cmd}.*\r\n${prompt}$" {}
-re $failure_pattern {
set rc false
}
}
ly_exit
return $rc
}