1*96c8483aSYuri Pankov#
2*96c8483aSYuri Pankov# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3*96c8483aSYuri Pankov# Use is subject to license terms.
4*96c8483aSYuri Pankov#
5*96c8483aSYuri Pankov
6*96c8483aSYuri Pankov#
7*96c8483aSYuri Pankov# This is free software; you can redistribute it and/or modify it
8*96c8483aSYuri Pankov# under the terms of the "Artistic License" which is located in the
9*96c8483aSYuri Pankov# file named "LICENSE.Artistic" which is included with this software.
10*96c8483aSYuri Pankov#
11*96c8483aSYuri Pankov
12*96c8483aSYuri Pankov#
13*96c8483aSYuri Pankov# This file was originally part of the "contrib" portion of the
14*96c8483aSYuri Pankov# TET3 test harness from The OpenGroup, originally found here:
15*96c8483aSYuri Pankov# http://tetworks.opengroup.org/tet/ or ftp://ftp.xopen.org/pub/TET3/
16*96c8483aSYuri Pankov# and later published in hg.opensolaris.org/hg/test-dev/stcnv-gate
17*96c8483aSYuri Pankov#
18*96c8483aSYuri Pankov# A build of that repository delivers this file as part of the
19*96c8483aSYuri Pankov# SUNWstc-tetlite package, which carries the "Artistic" license
20*96c8483aSYuri Pankov# referred to above.
21*96c8483aSYuri Pankov#
22*96c8483aSYuri Pankov
23*96c8483aSYuri Pankov#
24*96c8483aSYuri Pankov# The "Artistic License" places some restrictions on the kinds of
25*96c8483aSYuri Pankov# changes that may be made to this file.  The changes made here
26*96c8483aSYuri Pankov# relative to the original are "portability fixes" to allow these
27*96c8483aSYuri Pankov# functions to operate in the "test-runner" environment.
28*96c8483aSYuri Pankov#
29*96c8483aSYuri Pankov# The original from which this was derived can be found here:
30*96c8483aSYuri Pankov#   https://bitbucket.org/illumos/illumos-stc/
31*96c8483aSYuri Pankov# under the path:
32*96c8483aSYuri Pankov#   usr/src/tools/tet/contrib/ctitools/src/lib/ksh/ctiutils.ksh
33*96c8483aSYuri Pankov
34*96c8483aSYuri Pankov########################################################################
35*96c8483aSYuri Pankov#
36*96c8483aSYuri Pankov# NAME:		ctiutils.shlib
37*96c8483aSYuri Pankov#
38*96c8483aSYuri Pankov# SYNOPSIS:
39*96c8483aSYuri Pankov#	cti_assert assertion_number assertion_msg
40*96c8483aSYuri Pankov#	cti_report arg ...
41*96c8483aSYuri Pankov#	cti_pass
42*96c8483aSYuri Pankov#	cti_fail [msg ...]
43*96c8483aSYuri Pankov#	cti_unresolved [msg ...]
44*96c8483aSYuri Pankov#	cti_untested [msg ...]
45*96c8483aSYuri Pankov#	cti_unsupported [msg ...]
46*96c8483aSYuri Pankov#	cti_notinuse [msg ...]
47*96c8483aSYuri Pankov#	cti_pathtrace
48*96c8483aSYuri Pankov#	cti_checkpath expected-path-count
49*96c8483aSYuri Pankov#	cti_deleteall reason
50*96c8483aSYuri Pankov#	cti_reportfile path [title]
51*96c8483aSYuri Pankov#	cti_rmf [files...]
52*96c8483aSYuri Pankov#	cti_writefile path mode lines...
53*96c8483aSYuri Pankov#	cti_appendfile path mode lines...
54*96c8483aSYuri Pankov#	cti_execute [-c out|err] [-i input] result cmd [args...]
55*96c8483aSYuri Pankov#	cti_runexpect failtext command pattern action [pattern action ...]
56*96c8483aSYuri Pankov#	cti_expecttest failtext command pattern action [pattern action ...]
57*96c8483aSYuri Pankov#	cti_cancel test_num [msg ...] [test result]
58*96c8483aSYuri Pankov#	cti_cancelall [msg ...] [test result]
59*96c8483aSYuri Pankov#
60*96c8483aSYuri Pankov# DESCRIPTION:
61*96c8483aSYuri Pankov#	Common korn shell functions for tests.
62*96c8483aSYuri Pankov#
63*96c8483aSYuri Pankov#	cti_report() writes an informational line to the journal.
64*96c8483aSYuri Pankov#
65*96c8483aSYuri Pankov#	The functions cti_pass(), cti_fail(), cti_unresolved(),
66*96c8483aSYuri Pankov#	cti_untested(), cti_unsupported() and cti_notinuse() each
67*96c8483aSYuri Pankov#	registers the corresponding result code against the current test,
68*96c8483aSYuri Pankov#	and write any arguments to the execution results file, as a
69*96c8483aSYuri Pankov#	single line.
70*96c8483aSYuri Pankov#
71*96c8483aSYuri Pankov#	The cti_pathtrace() and cti_checkpath() are used in path tracing.
72*96c8483aSYuri Pankov#	cti_pathtrace() increments the variable pathok. cti_checkpath()
73*96c8483aSYuri Pankov#	checks the path tracing and registers a PASS result if
74*96c8483aSYuri Pankov#	appropriate.
75*96c8483aSYuri Pankov#
76*96c8483aSYuri Pankov#	cti_deleteall() cancels all tests in the current test case.
77*96c8483aSYuri Pankov#
78*96c8483aSYuri Pankov#	cti_reportfile() writes the contents of a file to the journal.
79*96c8483aSYuri Pankov#
80*96c8483aSYuri Pankov#	cti_rmf() removes files.
81*96c8483aSYuri Pankov#
82*96c8483aSYuri Pankov#	cti_writefile() writes to the contents of a file;
83*96c8483aSYuri Pankov#	cti_appendfile() appends to contents of a file.
84*96c8483aSYuri Pankov#
85*96c8483aSYuri Pankov#	cti_execute() executes a command.
86*96c8483aSYuri Pankov#
87*96c8483aSYuri Pankov#	cti_runexpect() runs the expect utility. cti_expecttest() is
88*96c8483aSYuri Pankov#	like cti_runexpect() except that it is written with path tracing
89*96c8483aSYuri Pankov#	and is designed to do the complete work of a test purpose.
90*96c8483aSYuri Pankov#       cti_runexpect() runs the expect utility. cti_expecttest() is
91*96c8483aSYuri Pankov#       like cti_runexpect() except that it is written with path tracing
92*96c8483aSYuri Pankov#       and is designed to do the complete work of a test purpose.
93*96c8483aSYuri Pankov#
94*96c8483aSYuri Pankov#       cti_cancel() cancels the dedicated test purpose in the current test
95*96c8483aSYuri Pankov#       case from execution with the test result that user gives. It will work
96*96c8483aSYuri Pankov#       in startup function.
97*96c8483aSYuri Pankov#
98*96c8483aSYuri Pankov#       cti_cancelall() cancels all tests in the current test case. It could
99*96c8483aSYuri Pankov#       be used in startup function to cancel the execution of test cases
100*96c8483aSYuri Pankov#       with the test result that user gives.
101*96c8483aSYuri Pankov#
102*96c8483aSYuri Pankov########################################################################
103*96c8483aSYuri Pankov
104*96c8483aSYuri Pankov#
105*96c8483aSYuri Pankov# cti_lf_checkargs() - check number of arguments passed to a shell function.
106*96c8483aSYuri Pankov#
107*96c8483aSYuri Pankov# Usage: cti_lf_checkargs argc expected-argc operator funcname
108*96c8483aSYuri Pankov#
109*96c8483aSYuri Pankov# operator can be EQ or GE.
110*96c8483aSYuri Pankov#
111*96c8483aSYuri Pankov# Returns 0 if the expected number of arguments were passed, non-zero
112*96c8483aSYuri Pankov# otherwise.
113*96c8483aSYuri Pankov#
114*96c8483aSYuri Pankovfunction cti_lf_checkargs
115*96c8483aSYuri Pankov{
116*96c8483aSYuri Pankov	typeset -i cti_lv_argc=$1
117*96c8483aSYuri Pankov	typeset -i cti_lv_expargc=$2
118*96c8483aSYuri Pankov	typeset cti_lv_op="$3"
119*96c8483aSYuri Pankov	typeset cti_lv_funcname="$4"
120*96c8483aSYuri Pankov
121*96c8483aSYuri Pankov	case "$cti_lv_op" in
122*96c8483aSYuri Pankov	EQ)
123*96c8483aSYuri Pankov		if test $cti_lv_argc -ne $cti_lv_expargc
124*96c8483aSYuri Pankov		then
125*96c8483aSYuri Pankov			cti_unresolved "Test coding error:" \
126*96c8483aSYuri Pankov				"$cti_lv_funcname() called with $cti_lv_argc" \
127*96c8483aSYuri Pankov				"args, need $cti_lv_expargc"
128*96c8483aSYuri Pankov			return 1
129*96c8483aSYuri Pankov		fi
130*96c8483aSYuri Pankov		;;
131*96c8483aSYuri Pankov	GE)
132*96c8483aSYuri Pankov		if test $cti_lv_argc -lt $cti_lv_expargc
133*96c8483aSYuri Pankov		then
134*96c8483aSYuri Pankov			cti_unresolved "Test coding error:" \
135*96c8483aSYuri Pankov				"$cti_lv_funcname() called with $cti_lv_argc" \
136*96c8483aSYuri Pankov				"args, need >= $cti_lv_expargc"
137*96c8483aSYuri Pankov			return 1
138*96c8483aSYuri Pankov		fi
139*96c8483aSYuri Pankov		;;
140*96c8483aSYuri Pankov	*)
141*96c8483aSYuri Pankov		cti_unresolved "Internal error: cti_lf_checkargs()" \
142*96c8483aSYuri Pankov			"called for $funcname() with operator $cti_lv_op"
143*96c8483aSYuri Pankov		return 1
144*96c8483aSYuri Pankov		;;
145*96c8483aSYuri Pankov	esac
146*96c8483aSYuri Pankov
147*96c8483aSYuri Pankov	return 0
148*96c8483aSYuri Pankov}
149*96c8483aSYuri Pankov
150*96c8483aSYuri Pankov#
151*96c8483aSYuri Pankov# cti_result() - register a result and write informational line to journal.
152*96c8483aSYuri Pankov#
153*96c8483aSYuri Pankov# Usage: cti_result result [msg ...]
154*96c8483aSYuri Pankov#
155*96c8483aSYuri Pankov# If the current test function is not a startup or cleanup, this routine
156*96c8483aSYuri Pankov# registers the specified result code for the current test. The remaining
157*96c8483aSYuri Pankov# arguments, if any, are written to the execution results file as a single
158*96c8483aSYuri Pankov# line.
159*96c8483aSYuri Pankov#
160*96c8483aSYuri Pankov# Modifications for test-runner:
161*96c8483aSYuri Pankov# Print the result and test name (in place of tet_result)
162*96c8483aSYuri Pankov# On failure, return non-zero to tell test-runner our status.
163*96c8483aSYuri Pankov#
164*96c8483aSYuri Pankovfunction cti_result
165*96c8483aSYuri Pankov{
166*96c8483aSYuri Pankov	typeset res
167*96c8483aSYuri Pankov	typeset -i rv=0
168*96c8483aSYuri Pankov
169*96c8483aSYuri Pankov	test $# -eq 0 && return
170*96c8483aSYuri Pankov	res=$1
171*96c8483aSYuri Pankov	shift
172*96c8483aSYuri Pankov
173*96c8483aSYuri Pankov	my_host=`hostname`
174*96c8483aSYuri Pankov	my_timestamp=`date | awk '{print $4}'`
175*96c8483aSYuri Pankov
176*96c8483aSYuri Pankov	test $# -gt 0 && print "$my_host $my_timestamp $@"
177*96c8483aSYuri Pankov
178*96c8483aSYuri Pankov	# Print the result and test name (as tet_result would)
179*96c8483aSYuri Pankov	print "$res: ${tc_id:-$(basename $0)}"
180*96c8483aSYuri Pankov
181*96c8483aSYuri Pankov	# Return non-zero for failures.  See codes in:
182*96c8483aSYuri Pankov	# test-runner/stf/include/stf.shlib
183*96c8483aSYuri Pankov	case "$res" in
184*96c8483aSYuri Pankov	PASS)
185*96c8483aSYuri Pankov		;;
186*96c8483aSYuri Pankov	FAIL)
187*96c8483aSYuri Pankov		rv=1
188*96c8483aSYuri Pankov		;;
189*96c8483aSYuri Pankov	UNRESOLVED)
190*96c8483aSYuri Pankov		rv=2
191*96c8483aSYuri Pankov		;;
192*96c8483aSYuri Pankov	NOTINUSE)
193*96c8483aSYuri Pankov		rv=3
194*96c8483aSYuri Pankov		;;
195*96c8483aSYuri Pankov	UNSUPPORTED)
196*96c8483aSYuri Pankov		rv=4
197*96c8483aSYuri Pankov		;;
198*96c8483aSYuri Pankov	UNTESTED)
199*96c8483aSYuri Pankov		rv=5
200*96c8483aSYuri Pankov		;;
201*96c8483aSYuri Pankov	UNINITIATED)
202*96c8483aSYuri Pankov		rv=6
203*96c8483aSYuri Pankov		;;
204*96c8483aSYuri Pankov	NORESULT)
205*96c8483aSYuri Pankov		rv=7
206*96c8483aSYuri Pankov		;;
207*96c8483aSYuri Pankov	WARNING)
208*96c8483aSYuri Pankov		rv=8
209*96c8483aSYuri Pankov		;;
210*96c8483aSYuri Pankov	TIMED_OUT)
211*96c8483aSYuri Pankov		rv=9
212*96c8483aSYuri Pankov		;;
213*96c8483aSYuri Pankov	*)
214*96c8483aSYuri Pankov		echo "cti_result: $res: unknown result code"
215*96c8483aSYuri Pankov		rv=10
216*96c8483aSYuri Pankov		;;
217*96c8483aSYuri Pankov	esac
218*96c8483aSYuri Pankov	return $rv
219*96c8483aSYuri Pankov}
220*96c8483aSYuri Pankov
221*96c8483aSYuri Pankov#
222*96c8483aSYuri Pankov# cti_report() - write an informational line to the journal
223*96c8483aSYuri Pankov#
224*96c8483aSYuri Pankov# Usage: cti_report arg ...
225*96c8483aSYuri Pankov#
226*96c8483aSYuri Pankov# Writes the arguments to the execution results file, as a single line.
227*96c8483aSYuri Pankov#
228*96c8483aSYuri Pankovfunction cti_report
229*96c8483aSYuri Pankov{
230*96c8483aSYuri Pankov	my_host=`hostname`
231*96c8483aSYuri Pankov	my_timestamp=`date | awk '{print $4}'`
232*96c8483aSYuri Pankov
233*96c8483aSYuri Pankov	print "$my_host $my_timestamp $@"
234*96c8483aSYuri Pankov}
235*96c8483aSYuri Pankov
236*96c8483aSYuri Pankov#
237*96c8483aSYuri Pankov# cti_assert() - write an Assert line to the journal
238*96c8483aSYuri Pankov#
239*96c8483aSYuri Pankov# Usage: cti_assert assertion_number assertion_msg
240*96c8483aSYuri Pankov#
241*96c8483aSYuri Pankov# Writes the arguments to the execution results file, as a single line.
242*96c8483aSYuri Pankov#
243*96c8483aSYuri Pankovfunction cti_assert
244*96c8483aSYuri Pankov{
245*96c8483aSYuri Pankov	cti_lf_checkargs $# 2 GE cti_assert || return 1
246*96c8483aSYuri Pankov
247*96c8483aSYuri Pankov	cti_report "ASSERT $1: $2"
248*96c8483aSYuri Pankov}
249*96c8483aSYuri Pankov
250*96c8483aSYuri Pankov#
251*96c8483aSYuri Pankov# cti_pass() - register a PASS result.
252*96c8483aSYuri Pankov#
253*96c8483aSYuri Pankov# Usage: cti_pass [msg ...]
254*96c8483aSYuri Pankov#
255*96c8483aSYuri Pankovfunction cti_pass
256*96c8483aSYuri Pankov{
257*96c8483aSYuri Pankov	cti_result PASS "$@"
258*96c8483aSYuri Pankov}
259*96c8483aSYuri Pankov
260*96c8483aSYuri Pankov#
261*96c8483aSYuri Pankov# cti_fail() - register a FAIL result.
262*96c8483aSYuri Pankov#
263*96c8483aSYuri Pankov# Usage: cti_fail [msg ...]
264*96c8483aSYuri Pankov#
265*96c8483aSYuri Pankov# Registers a FAIL result for the current test, and writes any arguments to
266*96c8483aSYuri Pankov# the execution results file, as a single line.
267*96c8483aSYuri Pankov#
268*96c8483aSYuri Pankovfunction cti_fail
269*96c8483aSYuri Pankov{
270*96c8483aSYuri Pankov	cti_result FAIL "$@"
271*96c8483aSYuri Pankov}
272*96c8483aSYuri Pankov
273*96c8483aSYuri Pankov#
274*96c8483aSYuri Pankov# cti_unresolved() - register an UNRESOLVED result.
275*96c8483aSYuri Pankov#
276*96c8483aSYuri Pankov# Usage: cti_unresolved [msg ...]
277*96c8483aSYuri Pankov#
278*96c8483aSYuri Pankov# Registers an UNRESOLVED result for the current test, and writes any arguments
279*96c8483aSYuri Pankov# to the execution results file, as a single line.
280*96c8483aSYuri Pankov#
281*96c8483aSYuri Pankovfunction cti_unresolved
282*96c8483aSYuri Pankov{
283*96c8483aSYuri Pankov	cti_result UNRESOLVED "$@"
284*96c8483aSYuri Pankov}
285*96c8483aSYuri Pankov
286*96c8483aSYuri Pankov
287*96c8483aSYuri Pankov#
288*96c8483aSYuri Pankov# cti_uninitiated() - register an UNINITIATED result.
289*96c8483aSYuri Pankov#
290*96c8483aSYuri Pankov# Usage: cti_uninitiated [msg ...]
291*96c8483aSYuri Pankov#
292*96c8483aSYuri Pankov# Registers an UNINITIATED result for the current test, and writes any arguments
293*96c8483aSYuri Pankov# to the execution results file, as a single line.
294*96c8483aSYuri Pankov#
295*96c8483aSYuri Pankovfunction cti_uninitiated
296*96c8483aSYuri Pankov{
297*96c8483aSYuri Pankov	cti_result UNINITIATED "$@"
298*96c8483aSYuri Pankov}
299*96c8483aSYuri Pankov
300*96c8483aSYuri Pankov#
301*96c8483aSYuri Pankov# cti_untested() - register an UNTESTED result.
302*96c8483aSYuri Pankov#
303*96c8483aSYuri Pankov# Usage: cti_untested [msg ...]
304*96c8483aSYuri Pankov#
305*96c8483aSYuri Pankov# Registers an UNTESTED result for the current test, and writes any arguments
306*96c8483aSYuri Pankov# to the execution results file, as a single line.
307*96c8483aSYuri Pankov#
308*96c8483aSYuri Pankovfunction cti_untested
309*96c8483aSYuri Pankov{
310*96c8483aSYuri Pankov	cti_result UNTESTED "$@"
311*96c8483aSYuri Pankov}
312*96c8483aSYuri Pankov
313*96c8483aSYuri Pankov#
314*96c8483aSYuri Pankov# cti_unsupported() - register an UNSUPPORTED result.
315*96c8483aSYuri Pankov#
316*96c8483aSYuri Pankov# Usage: cti_unsupported [msg ...]
317*96c8483aSYuri Pankov#
318*96c8483aSYuri Pankov# Registers an UNSUPPORTED result for the current test, and writes any
319*96c8483aSYuri Pankov# arguments to the execution results file, as a single line.
320*96c8483aSYuri Pankov#
321*96c8483aSYuri Pankovfunction cti_unsupported
322*96c8483aSYuri Pankov{
323*96c8483aSYuri Pankov	cti_result UNSUPPORTED "$@"
324*96c8483aSYuri Pankov}
325*96c8483aSYuri Pankov
326*96c8483aSYuri Pankov#
327*96c8483aSYuri Pankov# cti_notinuse() - register a NOTINUSE result.
328*96c8483aSYuri Pankov#
329*96c8483aSYuri Pankov# Usage: cti_notinuse [msg ...]
330*96c8483aSYuri Pankov#
331*96c8483aSYuri Pankov# Registers a NOTINUSE result for the current test, and writes any arguments
332*96c8483aSYuri Pankov# to the execution results file, as a single line.
333*96c8483aSYuri Pankov#
334*96c8483aSYuri Pankovfunction cti_notinuse
335*96c8483aSYuri Pankov{
336*96c8483aSYuri Pankov	cti_result NOTINUSE "$@"
337*96c8483aSYuri Pankov}
338*96c8483aSYuri Pankov
339*96c8483aSYuri Pankov#
340*96c8483aSYuri Pankov# cti_pathtrace() - increment path counter.
341*96c8483aSYuri Pankov#
342*96c8483aSYuri Pankov# Usage: cti_pathtrace
343*96c8483aSYuri Pankov#
344*96c8483aSYuri Pankov# Increments variable pathok. Like C macro PATH_TRACE.
345*96c8483aSYuri Pankov#
346*96c8483aSYuri Pankovfunction cti_pathtrace
347*96c8483aSYuri Pankov{
348*96c8483aSYuri Pankov	: $((pathok += 1))
349*96c8483aSYuri Pankov}
350*96c8483aSYuri Pankov
351*96c8483aSYuri Pankov#
352*96c8483aSYuri Pankov# cti_checkpath() - check path tracing and register a PASS result.
353*96c8483aSYuri Pankov#
354*96c8483aSYuri Pankov# Usage: cti_checkpath expected-path-count
355*96c8483aSYuri Pankov#
356*96c8483aSYuri Pankov# Like C macro PATH_XS_RPT().
357*96c8483aSYuri Pankov#
358*96c8483aSYuri Pankovfunction cti_checkpath
359*96c8483aSYuri Pankov{
360*96c8483aSYuri Pankov	cti_lf_checkargs $# 1 EQ cti_checkpath || return
361*96c8483aSYuri Pankov
362*96c8483aSYuri Pankov	if test $pathok -eq $1
363*96c8483aSYuri Pankov	then
364*96c8483aSYuri Pankov		cti_pass
365*96c8483aSYuri Pankov	else
366*96c8483aSYuri Pankov		cti_unresolved "Path tracing error: path counter $pathok," \
367*96c8483aSYuri Pankov			"expecting $1"
368*96c8483aSYuri Pankov	fi
369*96c8483aSYuri Pankov}
370*96c8483aSYuri Pankov
371*96c8483aSYuri Pankov#
372*96c8483aSYuri Pankov# cti_deleteall() - cancel all tests.
373*96c8483aSYuri Pankov#
374*96c8483aSYuri Pankov# Usage: cti_deleteall reason
375*96c8483aSYuri Pankov#
376*96c8483aSYuri Pankov# Cancels all tests
377*96c8483aSYuri Pankov#
378*96c8483aSYuri Pankovfunction cti_deleteall
379*96c8483aSYuri Pankov{
380*96c8483aSYuri Pankov	typeset cti_lv_ic
381*96c8483aSYuri Pankov	typeset cti_lv_tp
382*96c8483aSYuri Pankov
383*96c8483aSYuri Pankov	test $# -eq 0 && return
384*96c8483aSYuri Pankov
385*96c8483aSYuri Pankov	for cti_lv_ic in $iclist
386*96c8483aSYuri Pankov	do
387*96c8483aSYuri Pankov		for cti_lv_tp in `eval echo \\$$cti_lv_ic`
388*96c8483aSYuri Pankov		do
389*96c8483aSYuri Pankov			if test -n "$cti_lv_tp"
390*96c8483aSYuri Pankov			then
391*96c8483aSYuri Pankov				echo "Deleted test: $cti_lv_tp" "$@"
392*96c8483aSYuri Pankov			fi
393*96c8483aSYuri Pankov		done
394*96c8483aSYuri Pankov	done
395*96c8483aSYuri Pankov}
396*96c8483aSYuri Pankov
397*96c8483aSYuri Pankov#
398*96c8483aSYuri Pankov# cti_reportfile() - write the contents of a file to the journal.
399*96c8483aSYuri Pankov#
400*96c8483aSYuri Pankov# Usage: cti_reportfile path [title]
401*96c8483aSYuri Pankov#
402*96c8483aSYuri Pankov# Writes the contents of the file specified by path to the execution results
403*96c8483aSYuri Pankov# file, line by line.
404*96c8483aSYuri Pankov#
405*96c8483aSYuri Pankovfunction cti_reportfile
406*96c8483aSYuri Pankov{
407*96c8483aSYuri Pankov	typeset cti_lv_path=$1
408*96c8483aSYuri Pankov	typeset cti_lv_title="${2:-$cti_lv_path}"
409*96c8483aSYuri Pankov	typeset cti_lv_line
410*96c8483aSYuri Pankov
411*96c8483aSYuri Pankov	cti_lf_checkargs $# 1 GE cti_reportfile || return
412*96c8483aSYuri Pankov
413*96c8483aSYuri Pankov	cti_report "+++ $cti_lv_title +++"
414*96c8483aSYuri Pankov
415*96c8483aSYuri Pankov	/usr/bin/cat $cti_lv_path
416*96c8483aSYuri Pankov
417*96c8483aSYuri Pankov	cti_report "+++ end +++"
418*96c8483aSYuri Pankov	cti_report " "
419*96c8483aSYuri Pankov}
420*96c8483aSYuri Pankov
421*96c8483aSYuri Pankov#
422*96c8483aSYuri Pankov# cti_rmf() - remove files.
423*96c8483aSYuri Pankov#
424*96c8483aSYuri Pankov# Usage: cti_rmf [files...]
425*96c8483aSYuri Pankov#
426*96c8483aSYuri Pankov# Calls "rm -f" to remove the files, and verifies that they have been removed.
427*96c8483aSYuri Pankov#
428*96c8483aSYuri Pankov# Returns 0 on success, non-zero if any of the files could not be removed.
429*96c8483aSYuri Pankov#
430*96c8483aSYuri Pankovfunction cti_rmf
431*96c8483aSYuri Pankov{
432*96c8483aSYuri Pankov	typeset cti_lv_file
433*96c8483aSYuri Pankov
434*96c8483aSYuri Pankov	for cti_lv_file in "$@"
435*96c8483aSYuri Pankov	do
436*96c8483aSYuri Pankov		rm -f "$cti_lv_file"
437*96c8483aSYuri Pankov
438*96c8483aSYuri Pankov		if test -f "$cti_lv_file"
439*96c8483aSYuri Pankov		then
440*96c8483aSYuri Pankov			cti_unresolved "Error removing file \"$cti_lv_file\""
441*96c8483aSYuri Pankov			return 1
442*96c8483aSYuri Pankov		fi
443*96c8483aSYuri Pankov	done
444*96c8483aSYuri Pankov
445*96c8483aSYuri Pankov	return 0
446*96c8483aSYuri Pankov}
447*96c8483aSYuri Pankov
448*96c8483aSYuri Pankov#
449*96c8483aSYuri Pankov# cti_writefile() - write contents of a file.
450*96c8483aSYuri Pankov#
451*96c8483aSYuri Pankov# Usage: cti_writefile path mode lines...
452*96c8483aSYuri Pankov#
453*96c8483aSYuri Pankov# Truncates the file specified by path and then writes the third and
454*96c8483aSYuri Pankov# subsequent arguments to the specified file as separate lines.
455*96c8483aSYuri Pankov#
456*96c8483aSYuri Pankov# Returns 0 on success, non-zero if any of the files could not be removed.
457*96c8483aSYuri Pankov#
458*96c8483aSYuri Pankovfunction cti_writefile
459*96c8483aSYuri Pankov{
460*96c8483aSYuri Pankov	cti_lf_checkargs $# 3 GE cti_writefile || return 1
461*96c8483aSYuri Pankov
462*96c8483aSYuri Pankov	cti_rmf "$1" || return 1
463*96c8483aSYuri Pankov	cti_appendfile "$@"
464*96c8483aSYuri Pankov}
465*96c8483aSYuri Pankov
466*96c8483aSYuri Pankov#
467*96c8483aSYuri Pankov# cti_appendfile() - append to contents of a file.
468*96c8483aSYuri Pankov#
469*96c8483aSYuri Pankov# Usage: cti_appendfile path mode lines...
470*96c8483aSYuri Pankov#
471*96c8483aSYuri Pankov# Appends the third and subsequent arguments to the specified file as separate
472*96c8483aSYuri Pankov# lines.
473*96c8483aSYuri Pankov#
474*96c8483aSYuri Pankov# Returns 0 on success, non-zero if any of the files could not be removed.
475*96c8483aSYuri Pankov#
476*96c8483aSYuri Pankovfunction cti_appendfile
477*96c8483aSYuri Pankov{
478*96c8483aSYuri Pankov	typeset cti_lv_path="$1"
479*96c8483aSYuri Pankov	typeset cti_lv_mode="$2"
480*96c8483aSYuri Pankov	typeset cti_lv_line
481*96c8483aSYuri Pankov
482*96c8483aSYuri Pankov	cti_lf_checkargs $# 3 GE cti_appendfile || return 1
483*96c8483aSYuri Pankov	shift 2
484*96c8483aSYuri Pankov
485*96c8483aSYuri Pankov	for cti_lv_line in "$@"
486*96c8483aSYuri Pankov	do
487*96c8483aSYuri Pankov		echo "$cti_lv_line" >> "$cti_lv_path"
488*96c8483aSYuri Pankov
489*96c8483aSYuri Pankov		if [[ $? -ne 0 ]]
490*96c8483aSYuri Pankov		then
491*96c8483aSYuri Pankov			cti_unresolved \
492*96c8483aSYuri Pankov				"Error writing to file \"$cti_lv_path\""
493*96c8483aSYuri Pankov			return 1
494*96c8483aSYuri Pankov		fi
495*96c8483aSYuri Pankov	done
496*96c8483aSYuri Pankov
497*96c8483aSYuri Pankov	cti_execute UNRESOLVED chmod "$cti_lv_mode" "$cti_lv_path"
498*96c8483aSYuri Pankov	return $?
499*96c8483aSYuri Pankov}
500*96c8483aSYuri Pankov
501*96c8483aSYuri Pankov#
502*96c8483aSYuri Pankov# cti_execute() - execute a command
503*96c8483aSYuri Pankov#
504*96c8483aSYuri Pankov# Usage: cti_execute [-c out|err] [-i input] result cmd [args...]
505*96c8483aSYuri Pankov#
506*96c8483aSYuri Pankov# Executes a command. The standard output is redirected to the file cti_stdout
507*96c8483aSYuri Pankov# and the standard error is redirected to the file cti_stderr.
508*96c8483aSYuri Pankov#
509*96c8483aSYuri Pankov# If the command has a non-zero exit status, cti_execute() registers a result
510*96c8483aSYuri Pankov# code of `result'.
511*96c8483aSYuri Pankov#
512*96c8483aSYuri Pankov# Options:
513*96c8483aSYuri Pankov#	-c out|err	Check standard output/error. If anything is written to
514*96c8483aSYuri Pankov#			the specified output channel, a result code of `result'
515*96c8483aSYuri Pankov#			is registered and the output written to the journal.
516*96c8483aSYuri Pankov#			May have multiple -c options.
517*96c8483aSYuri Pankov#	-i input	Use -i as an input line to the command.
518*96c8483aSYuri Pankov#			May have multiple -i options.
519*96c8483aSYuri Pankov#
520*96c8483aSYuri Pankov# Returns 0 on success, non-zero on failure (returning the
521*96c8483aSYuri Pankov#  exit status from the command when possible).
522*96c8483aSYuri Pankov#
523*96c8483aSYuri Pankovfunction cti_execute
524*96c8483aSYuri Pankov{
525*96c8483aSYuri Pankov	typeset cti_lv_opt
526*96c8483aSYuri Pankov	typeset -i cti_lv_checkstdout=0
527*96c8483aSYuri Pankov	typeset -i cti_lv_checkstderr=0
528*96c8483aSYuri Pankov	typeset cti_lv_result
529*96c8483aSYuri Pankov	typeset -i cti_lv_status
530*96c8483aSYuri Pankov	typeset -i cti_lv_rv=0
531*96c8483aSYuri Pankov
532*96c8483aSYuri Pankov	# Remove files used for redirecting standard I/O.
533*96c8483aSYuri Pankov	cti_rmf cti_stdin cti_stdout cti_stderr || return 1
534*96c8483aSYuri Pankov
535*96c8483aSYuri Pankov	# Create (empty) files to take standard output and error so there are
536*96c8483aSYuri Pankov	# no problems later when we come to run the command.
537*96c8483aSYuri Pankov	touch cti_stdout cti_stderr
538*96c8483aSYuri Pankov
539*96c8483aSYuri Pankov	if [[ $? -ne 0 ]]
540*96c8483aSYuri Pankov	then
541*96c8483aSYuri Pankov		cti_unresolved "Error creating files cti_stdout and cti_stderr"
542*96c8483aSYuri Pankov		return 1
543*96c8483aSYuri Pankov	fi
544*96c8483aSYuri Pankov
545*96c8483aSYuri Pankov	# Parse command line options
546*96c8483aSYuri Pankov	while getopts "c:i:l:s:" cti_lv_opt
547*96c8483aSYuri Pankov	do
548*96c8483aSYuri Pankov		case $cti_lv_opt in
549*96c8483aSYuri Pankov		c)
550*96c8483aSYuri Pankov			case "$OPTARG" in
551*96c8483aSYuri Pankov			out|err)
552*96c8483aSYuri Pankov				eval cti_lv_checkstd$OPTARG=1
553*96c8483aSYuri Pankov				;;
554*96c8483aSYuri Pankov			*)
555*96c8483aSYuri Pankov				cti_unresolved "cti_execute() called with" \
556*96c8483aSYuri Pankov					"bad option argument -c $OPTARG"
557*96c8483aSYuri Pankov				return 1
558*96c8483aSYuri Pankov				;;
559*96c8483aSYuri Pankov			esac
560*96c8483aSYuri Pankov			;;
561*96c8483aSYuri Pankov		i)
562*96c8483aSYuri Pankov			echo "$OPTARG" >> cti_stdin
563*96c8483aSYuri Pankov			if [[ $? -ne 0 ]]
564*96c8483aSYuri Pankov			then
565*96c8483aSYuri Pankov				cti_unresolved "Error writing to cti_stdin"
566*96c8483aSYuri Pankov				return 1
567*96c8483aSYuri Pankov			fi
568*96c8483aSYuri Pankov			;;
569*96c8483aSYuri Pankov		*)
570*96c8483aSYuri Pankov			cti_unresolved "cti_execute() called with illegal" \
571*96c8483aSYuri Pankov				"option $cti_lv_opt"
572*96c8483aSYuri Pankov			return 1
573*96c8483aSYuri Pankov			;;
574*96c8483aSYuri Pankov		esac
575*96c8483aSYuri Pankov	done
576*96c8483aSYuri Pankov
577*96c8483aSYuri Pankov	shift $((OPTIND-1))
578*96c8483aSYuri Pankov
579*96c8483aSYuri Pankov	# Verify the correct number of arguments were passed.
580*96c8483aSYuri Pankov	cti_lf_checkargs $# 2 GE cti_execute || return 1
581*96c8483aSYuri Pankov
582*96c8483aSYuri Pankov	# First (non-option) argument is the result code to use if the command
583*96c8483aSYuri Pankov	# fails.
584*96c8483aSYuri Pankov	cti_lv_result="${1:-UNRESOLVED}"
585*96c8483aSYuri Pankov	shift
586*96c8483aSYuri Pankov
587*96c8483aSYuri Pankov	# Execute the command, redirecting standard input if required.
588*96c8483aSYuri Pankov	if test -f cti_stdin
589*96c8483aSYuri Pankov	then
590*96c8483aSYuri Pankov		eval "$@" < cti_stdin > cti_stdout 2> cti_stderr
591*96c8483aSYuri Pankov	else
592*96c8483aSYuri Pankov		eval "$@" > cti_stdout 2> cti_stderr
593*96c8483aSYuri Pankov	fi
594*96c8483aSYuri Pankov
595*96c8483aSYuri Pankov	cti_lv_status=$?
596*96c8483aSYuri Pankov
597*96c8483aSYuri Pankov	# Check the exit status of the command
598*96c8483aSYuri Pankov	if test $cti_lv_status -ne 0
599*96c8483aSYuri Pankov	then
600*96c8483aSYuri Pankov		if [[ "$cti_lv_result" = "CTI" ]]
601*96c8483aSYuri Pankov		then
602*96c8483aSYuri Pankov			cti_report CTI "Command \"$*\" failed "\
603*96c8483aSYuri Pankov				"with status $cti_lv_status"
604*96c8483aSYuri Pankov		else
605*96c8483aSYuri Pankov			cti_result "$cti_lv_result"\
606*96c8483aSYuri Pankov				"Command \"$*\" failed "\
607*96c8483aSYuri Pankov				"with status $cti_lv_status"
608*96c8483aSYuri Pankov			cti_lv_rv=$cti_lv_status
609*96c8483aSYuri Pankov		fi
610*96c8483aSYuri Pankov	fi
611*96c8483aSYuri Pankov
612*96c8483aSYuri Pankov	# Always log output of cti_execute_cmd
613*96c8483aSYuri Pankov	if [[ "$cti_lv_result" = "CTI" ]]
614*96c8483aSYuri Pankov	then
615*96c8483aSYuri Pankov
616*96c8483aSYuri Pankov		if test -s cti_stdout
617*96c8483aSYuri Pankov		then
618*96c8483aSYuri Pankov			cti_reportfile cti_stdout "Standard output from command \"$*\""
619*96c8483aSYuri Pankov		fi
620*96c8483aSYuri Pankov		if test -s cti_stderr
621*96c8483aSYuri Pankov		then
622*96c8483aSYuri Pankov			cti_reportfile cti_stderr "Standard error from command \"$*\""
623*96c8483aSYuri Pankov		fi
624*96c8483aSYuri Pankov		return $cti_lv_status
625*96c8483aSYuri Pankov	fi
626*96c8483aSYuri Pankov
627*96c8483aSYuri Pankov	# If cmd failed, or if "-c err", check standard error.
628*96c8483aSYuri Pankov	if test \( $cti_lv_rv -ne 0 -o $cti_lv_checkstderr -eq 1 \) \
629*96c8483aSYuri Pankov		-a -s cti_stderr
630*96c8483aSYuri Pankov	then
631*96c8483aSYuri Pankov		cti_result "$cti_lv_result" \
632*96c8483aSYuri Pankov			"Command \"$*\" produced standard error"
633*96c8483aSYuri Pankov		cti_reportfile cti_stderr "Standard error from command \"$*\""
634*96c8483aSYuri Pankov		[[ $cti_lv_rv = 0 ]] && cti_lv_rv=1
635*96c8483aSYuri Pankov	fi
636*96c8483aSYuri Pankov
637*96c8483aSYuri Pankov	#  If cmd failed, or if "-c out", check standard output.
638*96c8483aSYuri Pankov	if test \( $cti_lv_rv -ne 0 -o $cti_lv_checkstdout -eq 1 \) \
639*96c8483aSYuri Pankov		-a -s cti_stdout
640*96c8483aSYuri Pankov	then
641*96c8483aSYuri Pankov		cti_result "$cti_lv_result" \
642*96c8483aSYuri Pankov			"Command \"$*\" produced standard output"
643*96c8483aSYuri Pankov		cti_reportfile cti_stdout "Standard output from command \"$*\""
644*96c8483aSYuri Pankov		[[ $cti_lv_rv = 0 ]] && cti_lv_rv=1
645*96c8483aSYuri Pankov	fi
646*96c8483aSYuri Pankov
647*96c8483aSYuri Pankov	return $cti_lv_rv
648*96c8483aSYuri Pankov}
649*96c8483aSYuri Pankov
650*96c8483aSYuri Pankov#
651*96c8483aSYuri Pankov# Exit values for expect scripts.
652*96c8483aSYuri Pankov# N.B. Do not use 0, as expect uses this for e.g. syntax errors.
653*96c8483aSYuri Pankov#
654*96c8483aSYuri Pankovtypeset -ri CTI_EXP_RV_TIMEDOUT=1
655*96c8483aSYuri Pankovtypeset -ri CTI_EXP_RV_TESTFAIL=2
656*96c8483aSYuri Pankovtypeset -ri CTI_EXP_RV_OK=3
657*96c8483aSYuri Pankov
658*96c8483aSYuri Pankov#
659*96c8483aSYuri Pankov# cti_runexpect() - run the expect utility.
660*96c8483aSYuri Pankov#
661*96c8483aSYuri Pankov# Usage: cti_runexpect failtext command pattern action [pattern action ...]
662*96c8483aSYuri Pankov#
663*96c8483aSYuri Pankov# Executes the expect utility using the command line specified in the second
664*96c8483aSYuri Pankov# argument. Generates a temporary expect script which is removed at the end of
665*96c8483aSYuri Pankov# the call. The arguments following the second are pattern-action pairs. The
666*96c8483aSYuri Pankov# pattern can be a regular expression or "CALL", which indicates the action is
667*96c8483aSYuri Pankov# simply a function call which is unconditionally executed at that point.
668*96c8483aSYuri Pankov#
669*96c8483aSYuri Pankov# The following expect functions are available:
670*96c8483aSYuri Pankov#
671*96c8483aSYuri Pankov#	startcritical	Indicates that failures from this point onwards
672*96c8483aSYuri Pankov#			constitute a test failure. In that case the
673*96c8483aSYuri Pankov#			``failtext'' argument is used to report the error
674*96c8483aSYuri Pankov#			message.
675*96c8483aSYuri Pankov#	endcritical	Indicates the end of the test failure section begun by
676*96c8483aSYuri Pankov#			startcritical.
677*96c8483aSYuri Pankov#	finish		Exit the expect script here - the test has passed.
678*96c8483aSYuri Pankov#
679*96c8483aSYuri Pankov# Returns 0 on success, non-zero on failure.
680*96c8483aSYuri Pankov#
681*96c8483aSYuri Pankovfunction cti_runexpect
682*96c8483aSYuri Pankov{
683*96c8483aSYuri Pankov	typeset -ri CTI_EXP_TIMEOUT=5
684*96c8483aSYuri Pankov	typeset -r cti_lv_expfile="./cti_$tc_id-$$.exp"
685*96c8483aSYuri Pankov	typeset cti_lv_failtext="$1"
686*96c8483aSYuri Pankov	typeset cti_lv_command="$2"
687*96c8483aSYuri Pankov	typeset -i cti_lv_rv=0
688*96c8483aSYuri Pankov	typeset cti_lv_dopt
689*96c8483aSYuri Pankov
690*96c8483aSYuri Pankov	# Verify the correct number of arguments were passed.
691*96c8483aSYuri Pankov	cti_lf_checkargs $# 4 GE cti_runexpect || return 1
692*96c8483aSYuri Pankov
693*96c8483aSYuri Pankov	shift 2
694*96c8483aSYuri Pankov
695*96c8483aSYuri Pankov	# Generate expect script.
696*96c8483aSYuri Pankov	{
697*96c8483aSYuri Pankov	echo "set STATUS_OK       $CTI_EXP_RV_OK"
698*96c8483aSYuri Pankov	echo "set STATUS_FAIL     $CTI_EXP_RV_TESTFAIL"
699*96c8483aSYuri Pankov	echo "set STATUS_TIMEDOUT $CTI_EXP_RV_TIMEDOUT"
700*96c8483aSYuri Pankov	echo ''
701*96c8483aSYuri Pankov        echo "set timeout $CTI_EXP_TIMEOUT"
702*96c8483aSYuri Pankov        echo 'set retval $STATUS_TIMEDOUT'
703*96c8483aSYuri Pankov	echo ''
704*96c8483aSYuri Pankov	echo 'eval spawn [lrange $argv 0 end]'
705*96c8483aSYuri Pankov	echo ''
706*96c8483aSYuri Pankov	echo 'proc startcritical {} {'
707*96c8483aSYuri Pankov	echo '	global retval'
708*96c8483aSYuri Pankov	echo '	global STATUS_FAIL'
709*96c8483aSYuri Pankov	echo '	set retval $STATUS_FAIL'
710*96c8483aSYuri Pankov	echo '}'
711*96c8483aSYuri Pankov	echo ''
712*96c8483aSYuri Pankov	echo 'proc endcritical {} {'
713*96c8483aSYuri Pankov	echo '	global retval'
714*96c8483aSYuri Pankov	echo '	global STATUS_TIMEDOUT'
715*96c8483aSYuri Pankov	echo '	set retval $STATUS_TIMEDOUT'
716*96c8483aSYuri Pankov	echo '}'
717*96c8483aSYuri Pankov	echo ''
718*96c8483aSYuri Pankov	echo 'proc finish {} {'
719*96c8483aSYuri Pankov	echo '	global STATUS_OK'
720*96c8483aSYuri Pankov	echo '	exit $STATUS_OK'
721*96c8483aSYuri Pankov	echo '}'
722*96c8483aSYuri Pankov
723*96c8483aSYuri Pankov	while test $# -gt 1
724*96c8483aSYuri Pankov	do
725*96c8483aSYuri Pankov		echo ''
726*96c8483aSYuri Pankov
727*96c8483aSYuri Pankov		if test "$1" = "CALL"
728*96c8483aSYuri Pankov		then
729*96c8483aSYuri Pankov			echo "$2"
730*96c8483aSYuri Pankov		else
731*96c8483aSYuri Pankov			echo 'expect {'
732*96c8483aSYuri Pankov			echo "	-re \"$1\" {"
733*96c8483aSYuri Pankov			echo "		$2 "
734*96c8483aSYuri Pankov			echo '	}'
735*96c8483aSYuri Pankov			echo '	timeout {'
736*96c8483aSYuri Pankov			echo '		exit $retval'
737*96c8483aSYuri Pankov			echo '	}'
738*96c8483aSYuri Pankov			echo '}'
739*96c8483aSYuri Pankov		fi
740*96c8483aSYuri Pankov
741*96c8483aSYuri Pankov		shift 2
742*96c8483aSYuri Pankov	done
743*96c8483aSYuri Pankov	} > $cti_lv_expfile
744*96c8483aSYuri Pankov
745*96c8483aSYuri Pankov	# Check that there were no errors writing to the script file.
746*96c8483aSYuri Pankov	if test $? -ne 0
747*96c8483aSYuri Pankov	then
748*96c8483aSYuri Pankov		cti_unresolved "Error writing expect script to file" \
749*96c8483aSYuri Pankov			"\"$cti_lv_expfile\""
750*96c8483aSYuri Pankov		return 1
751*96c8483aSYuri Pankov	fi
752*96c8483aSYuri Pankov
753*96c8483aSYuri Pankov	# If debug is on, turn on expect debug flag.
754*96c8483aSYuri Pankov	case "$CTI_SHELL_DEBUG" in
755*96c8483aSYuri Pankov	y*|Y*)
756*96c8483aSYuri Pankov		cti_lv_dopt='-d'
757*96c8483aSYuri Pankov		;;
758*96c8483aSYuri Pankov	esac
759*96c8483aSYuri Pankov
760*96c8483aSYuri Pankov	# Execute expect using generated script.
761*96c8483aSYuri Pankov	expect $cti_lv_dopt -f $cti_lv_expfile $cti_lv_command > cti_expout 2>&1
762*96c8483aSYuri Pankov	cti_lv_rv=$?
763*96c8483aSYuri Pankov
764*96c8483aSYuri Pankov	# If debug is on, save expect script and output, otherwise remove
765*96c8483aSYuri Pankov	# script.
766*96c8483aSYuri Pankov	case "$CTI_SHELL_DEBUG" in
767*96c8483aSYuri Pankov	y*|Y*)
768*96c8483aSYuri Pankov		cp cti_expout ${cti_lv_expfile%.exp}.out
769*96c8483aSYuri Pankov		cti_report "DEBUG: expect script is $PWD/$cti_lv_expfile," \
770*96c8483aSYuri Pankov			"expect output is in $PWD/${cti_lv_expfile%.exp}.out"
771*96c8483aSYuri Pankov		;;
772*96c8483aSYuri Pankov	*)
773*96c8483aSYuri Pankov		rm -f $cti_lv_expfile
774*96c8483aSYuri Pankov	esac
775*96c8483aSYuri Pankov
776*96c8483aSYuri Pankov	# Deal with return value from expect.
777*96c8483aSYuri Pankov	case $cti_lv_rv in
778*96c8483aSYuri Pankov	$CTI_EXP_RV_OK)
779*96c8483aSYuri Pankov		return 0
780*96c8483aSYuri Pankov		;;
781*96c8483aSYuri Pankov	$CTI_EXP_RV_TIMEDOUT)
782*96c8483aSYuri Pankov		cti_unresolved "Expect script timed-out during test setup"
783*96c8483aSYuri Pankov		;;
784*96c8483aSYuri Pankov	$CTI_EXP_RV_TESTFAIL)
785*96c8483aSYuri Pankov		cti_fail "$cti_lv_failtext"
786*96c8483aSYuri Pankov		;;
787*96c8483aSYuri Pankov	*)
788*96c8483aSYuri Pankov		cti_unresolved "Test coding error or expect bug:" \
789*96c8483aSYuri Pankov			"unexpected exit status $cti_lv_rv from expect script"
790*96c8483aSYuri Pankov		cti_reportfile cti_expout "Output from expect"
791*96c8483aSYuri Pankov		;;
792*96c8483aSYuri Pankov	esac
793*96c8483aSYuri Pankov
794*96c8483aSYuri Pankov	return 1
795*96c8483aSYuri Pankov}
796*96c8483aSYuri Pankov
797*96c8483aSYuri Pankov#
798*96c8483aSYuri Pankov# cti_expecttest() - run the expect utility.
799*96c8483aSYuri Pankov#
800*96c8483aSYuri Pankov# Usage: cti_expecttest failtext command pattern action [pattern action ...]
801*96c8483aSYuri Pankov#
802*96c8483aSYuri Pankov# Common test function for test purposes which use expect. Like cti_runexpect()
803*96c8483aSYuri Pankov# except that this is written with path tracing and is designed to do the
804*96c8483aSYuri Pankov# complete work of a test purpose.
805*96c8483aSYuri Pankov#
806*96c8483aSYuri Pankovfunction cti_expecttest
807*96c8483aSYuri Pankov{
808*96c8483aSYuri Pankov	# Verify the correct number of arguments were passed.
809*96c8483aSYuri Pankov	cti_lf_checkargs $# 4 GE cti_expecttest || return
810*96c8483aSYuri Pankov
811*96c8483aSYuri Pankov	# Use cti_runexpect() to execute expect utililty.
812*96c8483aSYuri Pankov	if cti_runexpect "$@"
813*96c8483aSYuri Pankov	then
814*96c8483aSYuri Pankov		cti_pathtrace
815*96c8483aSYuri Pankov	else
816*96c8483aSYuri Pankov		return
817*96c8483aSYuri Pankov	fi
818*96c8483aSYuri Pankov
819*96c8483aSYuri Pankov	cti_checkpath 1
820*96c8483aSYuri Pankov}
821*96c8483aSYuri Pankov
822*96c8483aSYuri Pankovfunction cti_execute_cmd
823*96c8483aSYuri Pankov{
824*96c8483aSYuri Pankov	cti_execute CTI "$@"
825*96c8483aSYuri Pankov}
826*96c8483aSYuri Pankov
827*96c8483aSYuri Pankov#
828*96c8483aSYuri Pankov# "private" functions for internal use by cti_cancel function
829*96c8483aSYuri Pankov# used to replace test purpose functions which will be canceled.
830*96c8483aSYuri Pankov#
831*96c8483aSYuri Pankovfunction cancel_ic {
832*96c8483aSYuri Pankov	cti_result $cticancel_result "$cticancel_msg"
833*96c8483aSYuri Pankov}
834*96c8483aSYuri Pankov
835*96c8483aSYuri Pankov#
836*96c8483aSYuri Pankov# cti_cancel() - cancel an individual test purpose.
837*96c8483aSYuri Pankov#
838*96c8483aSYuri Pankov# Usage: cti_cancel tp reason [test result]
839*96c8483aSYuri Pankov#
840*96c8483aSYuri Pankov# Cancels an individual test by replace the tp function with
841*96c8483aSYuri Pankov# cancel_ic function
842*96c8483aSYuri Pankov#
843*96c8483aSYuri Pankovfunction cti_cancel {
844*96c8483aSYuri Pankov	test $# -gt 3 && return
845*96c8483aSYuri Pankov	test_num=$1
846*96c8483aSYuri Pankov	cticancel_msg="$2"
847*96c8483aSYuri Pankov	cticancel_result=${3:-"UNSUPPORTED"}
848*96c8483aSYuri Pankov	typeset cti_lv_ic cti_lv_ic_mod
849*96c8483aSYuri Pankov	typeset cti_lv_tp
850*96c8483aSYuri Pankov
851*96c8483aSYuri Pankov	cti_report "Canceling test $test_num: $cticancel_msg"
852*96c8483aSYuri Pankov	#
853*96c8483aSYuri Pankov	# translate the ic and point the test purpose ic to
854*96c8483aSYuri Pankov	# cancel_ic function
855*96c8483aSYuri Pankov	#
856*96c8483aSYuri Pankov	for cti_lv_ic in $iclist
857*96c8483aSYuri Pankov	do
858*96c8483aSYuri Pankov		cti_lv_ic_mod=""
859*96c8483aSYuri Pankov		for cti_lv_tp in `eval echo \\$$cti_lv_ic`
860*96c8483aSYuri Pankov		do
861*96c8483aSYuri Pankov			if [ X"$cti_lv_tp" == X"$test_num" ]; then
862*96c8483aSYuri Pankov				cti_lv_ic_mod=$cti_lv_ic_mod" cancel_ic"
863*96c8483aSYuri Pankov			else
864*96c8483aSYuri Pankov				cti_lv_ic_mod=$cti_lv_ic_mod" $cti_lv_tp"
865*96c8483aSYuri Pankov			fi
866*96c8483aSYuri Pankov		done
867*96c8483aSYuri Pankov		eval "$cti_lv_ic=\"$cti_lv_ic_mod\""
868*96c8483aSYuri Pankov	done
869*96c8483aSYuri Pankov}
870*96c8483aSYuri Pankov
871*96c8483aSYuri Pankov#
872*96c8483aSYuri Pankov# cti_cancelall() - cancel all tests.
873*96c8483aSYuri Pankov#
874*96c8483aSYuri Pankov# Usage: cti_cancelall reason [test result]
875*96c8483aSYuri Pankov#
876*96c8483aSYuri Pankov# Cancels all tests by replace the tests functions with cancel_ic function
877*96c8483aSYuri Pankov#
878*96c8483aSYuri Pankovfunction cti_cancelall {
879*96c8483aSYuri Pankov	typeset cti_lv_ic
880*96c8483aSYuri Pankov	typeset cti_lv_tp
881*96c8483aSYuri Pankov	cticancel_msg=$1
882*96c8483aSYuri Pankov	cticancel_result=${2:-"UNSUPPORTED"}
883*96c8483aSYuri Pankov
884*96c8483aSYuri Pankov	test $# -eq 0 && return
885*96c8483aSYuri Pankov
886*96c8483aSYuri Pankov	for cti_lv_ic in $iclist
887*96c8483aSYuri Pankov	do
888*96c8483aSYuri Pankov		for cti_lv_tp in `eval echo \\$$cti_lv_ic`
889*96c8483aSYuri Pankov		do
890*96c8483aSYuri Pankov			cti_cancel $cti_lv_tp "$cticancel_msg" \
891*96c8483aSYuri Pankov			    $cticancel_result
892*96c8483aSYuri Pankov		done
893*96c8483aSYuri Pankov	done
894*96c8483aSYuri Pankov}
895