• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /freebsd-13-stable/sys/contrib/openzfs/tests/zfs-tests/tests/functional/channel_program/
1#
2# This file and its contents are supplied under the terms of the
3# Common Development and Distribution License ("CDDL"), version 1.0.
4# You may only use this file in accordance with the terms of version
5# 1.0 of the CDDL.
6#
7# A full copy of the text of the CDDL should have accompanied this
8# source.  A copy of the CDDL is also available via the Internet at
9# http://www.illumos.org/license/CDDL.
10#
11
12#
13# Copyright (c) 2016, 2017 by Delphix. All rights reserved.
14#
15
16. $STF_SUITE/include/libtest.shlib
17
18ZCP_ROOT=$STF_SUITE/tests/functional/channel_program
19
20#
21# Note: In case of failure (log_fail) in this function
22# we delete the file passed as <input file> so the
23# test suite doesn't leak temp files on failures. So it
24# is expected that <input file> is a temp file and not
25# an installed file.
26#
27# <exitcode> <expected error string> <input file> <zfs program args>
28# e.g. log_program 0 "" tmp.7a12V $POOL foo.zcp arg1 arg2
29function log_program
30{
31	typeset expectexit=$1
32	shift
33	typeset expecterror=$1
34	shift
35	typeset tmpin=$1
36	shift
37	typeset cmdargs=$@ tmpout=$(mktemp) tmperr=$(mktemp)
38
39	# Expected output/error filename is the same as the .zcp name
40	typeset basename
41	if [[ $2 != "-" ]]; then
42		basename=${2%.*}
43	fi
44
45	log_note "running: zfs program $cmdargs:"
46
47	zfs program $cmdargs >$tmpout 2>$tmperr
48	typeset ret=$?
49
50	log_note "input:\n$(cat $tmpin)"
51	log_note "output:\n$(cat $tmpout)"
52	log_note "error:\n$(cat $tmperr)"
53
54	#
55	# Verify correct return value
56	#
57	if [[ $ret -ne $expectexit ]]; then
58		rm $tmpout $tmperr $tmpin
59		log_fail "return mismatch: expected $expectexit, got $ret"
60	fi
61
62	#
63	# Check the output or reported error for successful or error returns,
64	# respectively.
65	#
66	if [[ -f "$basename.out" ]] && [[ $expectexit -eq 0 ]]; then
67
68		outdiff=$(diff "$basename.out" "$tmpout")
69		if [[ $? -ne 0 ]]; then
70			output=$(<$tmpout)
71			rm $tmpout $tmperr $tmpin
72			log_fail "Output mismatch. Expected:\n" \
73				"$(<$basename.out)\nBut got:\n$output\n" \
74				"Diff:\n$outdiff"
75		fi
76
77	elif [[ -f "$basename.err" ]] && [[ $expectexit -ne 0 ]]; then
78
79		outdiff=$(diff "$basename.err" "$tmperr")
80		if [[ $? -ne 0 ]]; then
81			outputerror=$(<$tmperr)
82			rm $tmpout $tmperr $tmpin
83			log_fail "Error mismatch. Expected:\n" \
84				"$(<$basename.err)\nBut got:\n$outputerror\n" \
85				"Diff:\n$outdiff"
86		fi
87
88	elif [[ -n $expecterror ]] && [[ $expectexit -ne 0 ]]; then
89
90		grep -q "$expecterror" $tmperr
91		if [[ $? -ne 0 ]]; then
92			outputerror=$(<$tmperr)
93			rm $tmpout $tmperr $tmpin
94			log_fail "Error mismatch. Expected to contain:\n" \
95				"$expecterror\nBut got:\n$outputerror\n"
96		fi
97
98	elif [[ $expectexit -ne 0 ]]; then
99		#
100		# If there's no expected output, error reporting is allowed to
101		# vary, but ensure that we didn't fail silently.
102		#
103		if [[ -z "$(<$tmperr)" ]]; then
104			rm $tmpout $tmperr $tmpin
105			log_fail "error with no stderr output"
106		fi
107	fi
108
109	#
110	# Clean up all temp files except $tmpin which is
111	# reused for the second invocation of log_program.
112	#
113	rm $tmpout $tmperr
114}
115
116#
117# Even though the command's arguments are passed correctly
118# to the log_must_program family of wrappers the majority
119# of the time, zcp scripts passed as HERE documents can
120# make things trickier (see comment within the function
121# below) in the ordering of the commands arguments and how
122# they are passed. Thus, with this function we reconstruct
123# them to ensure that they are passed properly.
124#
125function log_program_construct_args
126{
127	typeset tmpin=$1
128	shift
129
130	args=""
131	i=0
132	while getopts "nt:m:" opt; do
133		case $opt in
134			t) args="$args -t $OPTARG"; i=$(($i + 2)) ;;
135			m) args="$args -m $OPTARG"; i=$(($i + 2)) ;;
136			n) args="$args -n"; i=$(($i + 1)) ;;
137		esac
138	done
139	shift $i
140
141	pool=$1
142	shift
143
144	infile=$1
145	shift
146
147	#
148	# Copy the contents of the original channel program to $tmpin.
149	#
150	# If $infile currently holds "-" (a dash) it means that we consume a
151	# HERE doc from stdin, otherwise $infile is a file path.
152	#
153	cat $infile > $tmpin
154
155	lua_args=$@
156
157	echo "$args $pool $tmpin $lua_args"
158}
159
160#
161# Program should complete successfully
162# when run in either context.
163#
164function log_must_program
165{
166	typeset tmpin=$(mktemp)
167
168	program_args=$(log_program_construct_args $tmpin $@)
169
170	log_program 0 "" $tmpin "-n $program_args"
171	log_program 0 "" $tmpin "$program_args"
172
173	rm $tmpin
174}
175#
176# Program should error as expected in
177# the same way in both contexts.
178#
179function log_mustnot_checkerror_program
180{
181	typeset expecterror=$1
182	shift
183	typeset tmpin=$(mktemp)
184
185	program_args=$(log_program_construct_args $tmpin $@)
186
187	log_program 1 "$expecterror" $tmpin "-n $program_args"
188	log_program 1 "$expecterror" $tmpin "$program_args"
189
190	rm $tmpin
191}
192
193#
194# Program should fail when run in either
195# context.
196#
197function log_mustnot_program
198{
199	log_mustnot_checkerror_program "" $@
200}
201
202
203#
204# Program should error as expected in
205# open context but complete successfully
206# in syncing context.
207#
208function log_mustnot_checkerror_program_open
209{
210	typeset expecterror=$1
211	shift
212	typeset tmpin=$(mktemp)
213
214	program_args=$(log_program_construct_args $tmpin $@)
215
216	log_program 1 "$expecterror" $tmpin "-n $program_args"
217	log_program 0 "" $tmpin "$program_args"
218
219	rm $tmpin
220}
221
222#
223# Program should complete successfully
224# when run in syncing context but fail
225# when attempted to run in open context.
226#
227function log_must_program_sync
228{
229	log_mustnot_checkerror_program_open "requires passing sync=TRUE" $@
230}
231