blob: 7282d3530200c65c079d7a6043f03a54decef18b [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
12# Complete the path for Tool Under Test (TUT). For example, on Windows, TUT can be located in the Debug or Release
13# subdirectory. Note that Release build takes precedence over Debug.
14set conftypes {{} Release Debug}
15foreach i $conftypes {
16 if { [file executable "$TUT_PATH/$i/$TUT_NAME"] || [file executable "$TUT_PATH/$i/$TUT_NAME.exe"] } {
17 set TUT "$TUT_PATH/$i/$TUT_NAME"
18 break
19 }
20}
21if {![info exists TUT]} {
22 error "$TUT_NAME executable not found"
23}
24
25# prompt of error message
26set error_prompt ">>>"
27# the beginning of error message
28set error_head "$error_prompt Check-failed"
29
30# Run commands from command line
31tcltest::loadTestedCommands
aPiecek266ca762023-03-22 15:04:59 +010032
33# namespace of internal functions
34namespace eval ly::private {
35 namespace export *
36}
37
38# Run the process with arguments.
39# Parameter cmd is a string with arguments.
40# Parameter wrn is a flag. Set to 1 if stderr should be ignored.
41# Returns a pair where the first is the return code and the second is the output.
42proc ly::private::ly_exec {cmd {wrn ""}} {
aPiecek0ebc35b2023-06-22 14:11:58 +020043 global TUT
aPiecek266ca762023-03-22 15:04:59 +010044 try {
aPiecek0ebc35b2023-06-22 14:11:58 +020045 set results [exec -- $TUT {*}$cmd]
aPiecek266ca762023-03-22 15:04:59 +010046 set status 0
47 } trap CHILDSTATUS {results options} {
48 # return code is not 0
49 set status [lindex [dict get $options -errorcode] 2]
50 } trap NONE results {
51 if { $wrn == 1 } {
52 set status 0
53 } else {
54 error "return code is 0 but something was written to stderr:\n$results\n"
55 }
56 } trap CHILDKILLED {results options} {
57 set status [lindex [dict get $options -errorcode] 2]
58 error "process was killed: $status"
59 }
60 list $status $results
61}
62
63# Internal function.
64# Check the output with pattern.
65# Parameter pattern is a regex or an exact string to match.
66# Parameter msg is the output to check.
67# Parameter 'opt' is optional. If contains '-ex', then the 'pattern' parameter is
68# used as a simple string for exact matching of the output.
69proc ly::private::output_check {pattern msg {opt ""}} {
70 if { $opt eq "" } {
71 expr {![regexp -- $pattern $msg]}
72 } elseif { $opt eq "-ex" } {
73 expr {![string equal "$pattern" $msg]}
74 } else {
75 global error_head
76 error "$error_head unrecognized value of parameter 'opt'"
77 }
78}
79
80# Execute yanglint with arguments and expect success.
81# Parameter cmd is a string of arguments.
82# Parameter pattern is a regex or an exact string to match.
83# Parameter 'opt' is optional. If contains '-ex', then the 'pattern' parameter is
84# used as a simple string for exact matching of the output.
85proc ly_cmd {cmd {pattern ""} {opt ""}} {
86 namespace import ly::private::*
87 lassign [ly_exec $cmd] rc msg
88 if { $rc != 0 } {
89 error "unexpected return code $rc:\n$msg\n"
90 }
91 if { $pattern ne "" && [output_check $pattern $msg $opt] } {
92 error "unexpected output:\n$msg\n"
93 }
94 return
95}
96
97# Execute yanglint with arguments and expect error.
98# Parameter cmd is a string of arguments.
99# Parameter pattern is a regex.
100proc ly_cmd_err {cmd pattern} {
101 namespace import ly::private::*
102 lassign [ly_exec $cmd] rc msg
103 if { $rc == 0 } {
104 error "unexpected return code $rc"
105 }
106 if { [output_check $pattern $msg] } {
107 error "unexpected output:\n$msg\n"
108 }
109 return
110}
111
112# Execute yanglint with arguments, expect warning in stderr but success.
113# Parameter cmd is a string of arguments.
114# Parameter pattern is a regex.
115proc ly_cmd_wrn {cmd pattern} {
116 namespace import ly::private::*
117 lassign [ly_exec $cmd 1] rc msg
118 if { $rc != 0 } {
119 error "unexpected return code $rc:\n$msg\n"
120 }
121 if { [output_check $pattern $msg] } {
122 error "unexpected output:\n$msg\n"
123 }
124 return
125}
aPiecek6e5844c2023-05-22 11:42:09 +0200126
127# Check if yanglint supports the specified option.
128# Parameter opt is a option to be found.
129# Return true if option is found otherwise false.
130proc ly_opt_exists {opt} {
131 namespace import ly::private::*
132 lassign [ly_exec "--help"] rc msg
133 if { $rc != 0 } {
134 error "unexpected return code $rc:\n$msg\n"
135 }
136 if { [output_check $opt $msg] } {
137 return false
138 } else {
139 return true
140 }
141}