xref: /freebsd/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_common.kshlib (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1# SPDX-License-Identifier: CDDL-1.0
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or https://opensource.org/licenses/CDDL-1.0.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23#
24# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
25# Use is subject to license terms.
26#
27
28#
29# Copyright (c) 2014, 2016 by Delphix. All rights reserved.
30#
31
32. $STF_SUITE/include/libtest.shlib
33
34set -A VALID_NAME_CHAR a b c d e f g h i j k l m n o p q r s t u v w x y z \
35    0 1 2 3 4 5 6 7 8 9 ':' '-' '.' '_'
36set -A INVALID_NAME_CHAR A B C D E F G H I J K L M N O P Q R S T U V W X Y Z \
37    '`' '~' '!' '@' '#' '$' '%' '^' '&' '(' ')' '+' '=' '|' "\\" '{' '[' ']' \
38    '}' ';' '"' '<' ',' '>' '?' '/' ' '
39set -A ALL_CHAR ${VALID_NAME_CHAR[*]} ${INVALID_NAME_CHAR[*]}
40
41#
42# Firstly, set the property value to dataset. Then checking if the property
43# value is equal with the expected value, according to the expected result.
44#
45# $1 property value
46# $2 property name
47# $3 dataset
48# $4 expected result
49#
50function set_n_check_prop
51{
52	typeset expect_value=$1
53	typeset prop=$2
54	typeset dataset=$3
55	typeset expect_result=${4:-true}
56
57	typeset old_value=""
58	typeset cur_value=""
59
60	[[ -n $prop ]] && old_value=$(get_prop $prop $dataset)
61
62	if [[ $expect_result == true ]]; then
63		[[ -z $prop || -z $dataset ]] && \
64			log_fail "property or dataset isn't defined."
65
66		log_must zfs set $prop=$expect_value $dataset
67		if [[ $expect_value == "gzip-6" ]]; then
68			expect_value="gzip"
69		fi
70
71		[[ -n $prop ]] && cur_value=$(get_prop $prop $dataset)
72
73		case $prop in
74			reservation|reserv|quota )
75				if [[ $expect_value == "none" ]]; then
76					[[ $cur_value != "0" ]] && \
77						log_fail "The '$dataset' '$prop' value" \
78						"'$cur_value' is not expected."
79				elif [[ $cur_value != $expect_value ]]; then
80					log_fail "The '$dataset' '$prop' value '$cur_value'" \
81					"does not equal the expected value '$expect_value'."
82				fi
83				;;
84			* )
85				if [[ $cur_value != $expect_value ]]; then
86					log_fail "The '$dataset' '$prop' value '$cur_value'" \
87					"does not equal the expected value '$expect_value'."
88				fi
89				;;
90		esac
91
92	else
93		log_mustnot zfs set $prop=$expect_value $dataset
94
95		[[ -n $prop ]] && cur_value=$(get_prop $prop $dataset)
96
97		wait_freeing
98
99		if [[ "$expect_value" != "" && "$cur_value" != "$old_value" ]];
100		then
101			log_fail "The '$dataset' '$prop' value '$cur_value'" \
102				"should equal '$old_value'."
103		fi
104	fi
105}
106
107#
108# Cleanup all the user properties of the pool and the dataset reside it.
109#
110# $1 pool name
111#
112function cleanup_user_prop
113{
114	typeset pool=$1
115	typeset dtst=$(zfs list -H -r -o name -t filesystem,volume $pool)
116
117	typeset user_prop
118	for dt in $dtst; do
119		user_prop=$(zfs get -H -o property all $dtst | grep ":")
120
121		typeset prop
122		for prop in $user_prop; do
123			zfs inherit $prop $dt ||
124				log_must zfs inherit $prop $dt
125		done
126	done
127}
128
129#
130# Random select character from the specified character set and combine into a
131# random string
132#
133# $1 character set name
134# $2 String length
135#
136function random_string
137{
138	typeset char_set=${1:-VALID_NAME_CHAR}
139	typeset -i len=${2:-5}
140
141	eval typeset -i count=\${#$char_set[@]}
142
143	# No consumers want an empty string.
144	((len == 0)) && len=3
145
146	typeset str
147	typeset -i i=0
148	while ((i < len)); do
149		typeset -i ind
150		((ind = RANDOM % count))
151		eval str=\${str}\${$char_set[\$ind]}
152
153		((i += 1))
154	done
155
156	echo "$str"
157}
158
159#
160# Get valid user defined property name
161#
162# $1 user defined property name length
163#
164function valid_user_property
165{
166	typeset -i sumlen=${1:-10}
167	((sumlen < 2 )) && sumlen=2
168	typeset -i len
169	((len = RANDOM % sumlen))
170	typeset part1 part2
171
172	while true; do
173		part1="$(random_string VALID_NAME_CHAR $len)"
174		if [[ "$part1" == "-"* ]]; then
175			continue
176		fi
177		break
178	done
179	((len = sumlen - (len + 1)))
180
181	while true; do
182		part2="$(random_string VALID_NAME_CHAR $len)"
183		if [[ -z $part1 && -z $part2 ]]; then
184			continue
185		fi
186		break
187	done
188
189	echo "${part1}:${part2}"
190}
191
192#
193# Get invalid user defined property name
194#
195# $1 user defined property name length
196#
197function invalid_user_property
198{
199	typeset -i sumlen=${1:-10}
200	((sumlen == 0)) && sumlen=1
201	typeset -i len
202	((len = RANDOM % sumlen))
203
204	typeset part1 part2
205	while true; do
206		part1="$(random_string VALID_NAME_CHAR $len)"
207		((len = sumlen - len))
208		part2="$(random_string INVALID_NAME_CHAR $len)"
209
210		# Avoid $part1 is *:* and $part2 is "=*"
211		if [[ "$part1" == *":"* && "$part2" == "="* ]]; then
212			continue
213		fi
214		break
215	done
216
217	echo "${part1}${part2}"
218}
219
220#
221# Get user property value
222#
223# $1 user defined property name length
224#
225function user_property_value
226{
227	typeset -i len=${1:-100}
228
229	random_string ALL_CHAR $len
230}
231
232#
233# Check if the user property is identical to the expected value.
234#
235# $1 dataset
236# $2 user property
237# $3 expected value
238#
239function check_user_prop
240{
241	typeset dtst=$1
242	typeset user_prop="$2"
243	typeset expect_value="$3"
244	typeset value=$(zfs get -p -H -o value "$user_prop" $dtst 2>&1)
245
246	[ "$expect_value" = "$value" ]
247}
248
249#
250# Get source of the dataset
251#
252function get_source
253{
254	typeset prop=$1
255	typeset dataset=$2
256
257	zfs get -H -o source $prop $dataset ||
258                log_fail "Unable to get $prop source for dataset $dataset"
259}
260
261#
262# Verify property $2 is set from source $4 on dataset $1 and has value $3.
263#
264# $1 checked dataset
265# $2 user property
266# $3 property value
267# $4 source
268#
269# Returns: 0 if both expected source and value match, 1 otherwise
270#
271function check_prop_source
272{
273        typeset dataset="$1"
274        typeset prop="$2"
275        typeset value="$3"
276        typeset source="$4"
277        typeset chk_value=$(get_prop "$prop" "$dataset")
278        typeset chk_source=$(get_source "$prop" "$dataset")
279
280	if [[ "$chk_value" != "$value" || "$chk_source" != "$source" ]]
281	then
282		log_note "expected (value '$value', source '$source')," \
283			"got (value '$chk_value', source '$chk_source')"
284		return 1
285	else
286		return 0
287	fi
288}
289
290#
291# Verify target dataset $1 inherit property $2 from dataset $3.
292#
293# $1 checked dataset
294# $2 property
295# $3 inherited dataset
296#
297# Returns: 0 if property has expected value and is inherited, 1 otherwise
298#
299function check_prop_inherit
300{
301        typeset checked_dtst="$1"
302        typeset prop="$2"
303        typeset inherited_dtst="$3"
304        typeset inherited_value=$(get_prop "$prop" "$inherited_dtst")
305        typeset value=$(get_prop "$prop" "$checked_dtst")
306        typeset source=$(get_source "$prop" "$checked_dtst")
307
308        [ "$value" = "$inherited_value" ] &&
309            [ "$source" = "inherited from $inherited_dtst" ]
310}
311
312#
313# Verify property $2 received value on dataset $1 has value $3
314#
315# $1 checked dataset
316# $2 property name
317# $3 checked value
318#
319# Returns: 0 if property has expected value and is received, 1 otherwise
320#
321function check_prop_received
322{
323        typeset dataset="$1"
324        typeset prop="$2"
325        typeset value="$3"
326
327        received=$(zfs get -H -o received "$prop" "$dataset") ||
328                log_fail "Unable to get $prop received value for dataset $dataset"
329        [ "$received" = "$value" ]
330}
331
332#
333# Verify user property $2 is not set on dataset $1
334#
335# $1 checked dataset
336# $2 property name
337#
338# Returns: 0 if property is missing (not set), 1 otherwise
339#
340function check_prop_missing
341{
342        typeset dataset="$1"
343        typeset prop="$2"
344
345        value=$(zfs get -H -o value "$prop" "$dataset") ||
346                log_fail "Unable to get $prop value for dataset $dataset"
347        [ "$value" = "-" ]
348}
349