xref: /freebsd/sbin/bectl/tests/bectl_test.sh (revision 78cd75393ec79565c63927bf200f06f839a1dc05)
1#
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright (c) 2018 Kyle Evans <kevans@FreeBSD.org>
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27
28ZPOOL_NAME_FILE=zpool_name
29get_zpool_name()
30{
31	cat $ZPOOL_NAME_FILE
32}
33make_zpool_name()
34{
35	mktemp -u bectl_test_XXXXXX > $ZPOOL_NAME_FILE
36	get_zpool_name
37}
38
39# Establishes a bectl_create zpool that can be used for some light testing; contains
40# a 'default' BE and not much else.
41bectl_create_setup()
42{
43	zpool=$1
44	disk=$2
45	mnt=$3
46
47	# Sanity check to make sure `make_zpool_name` succeeded
48	atf_check test -n "$zpool"
49
50	kldload -n -q zfs || atf_skip "ZFS module not loaded on the current system"
51	if ! getconf MIN_HOLE_SIZE "$(pwd)"; then
52		echo "getconf MIN_HOLE_SIZE $(pwd) failed; sparse files " \
53		    "probably not supported by file system"
54		mount
55		atf_skip "Test's work directory does not support sparse files;" \
56		    "try with a different TMPDIR?"
57	fi
58	atf_check mkdir -p ${mnt}
59	atf_check truncate -s 1G ${disk}
60	atf_check zpool create -R ${mnt} ${zpool} ${disk}
61	atf_check zfs create -o mountpoint=none ${zpool}/ROOT
62	atf_check zfs create -o mountpoint=/ -o canmount=noauto \
63	    ${zpool}/ROOT/default
64}
65bectl_create_deep_setup()
66{
67	zpool=$1
68	disk=$2
69	mnt=$3
70
71	# Sanity check to make sure `make_zpool_name` succeeded
72	atf_check test -n "$zpool"
73
74	bectl_create_setup ${zpool} ${disk} ${mnt}
75	atf_check mkdir -p ${root}
76	atf_check -o ignore bectl -r ${zpool}/ROOT mount default ${root}
77	atf_check mkdir -p ${root}/usr
78	atf_check zfs create -o mountpoint=/usr -o canmount=noauto \
79	    ${zpool}/ROOT/default/usr
80	atf_check -o ignore bectl -r ${zpool}/ROOT umount default
81}
82
83bectl_cleanup()
84{
85	zpool=$1
86	if [ -z "$zpool" ]; then
87		echo "Skipping cleanup; zpool not set up"
88	elif zpool get health ${zpool} >/dev/null 2>&1; then
89		zpool destroy -f ${zpool}
90	fi
91}
92
93atf_test_case bectl_create cleanup
94bectl_create_head()
95{
96
97	atf_set "descr" "Check the various forms of bectl create"
98	atf_set "require.user" root
99}
100bectl_create_body()
101{
102	if [ "$(atf_config_get ci false)" = "true" ] && \
103		[ "$(uname -p)" = "i386" ]; then
104		atf_skip "https://bugs.freebsd.org/249055"
105	fi
106
107	if [ "$(atf_config_get ci false)" = "true" ] && \
108		[ "$(uname -p)" = "armv7" ]; then
109		atf_skip "https://bugs.freebsd.org/249229"
110	fi
111
112	cwd=$(realpath .)
113	zpool=$(make_zpool_name)
114	disk=${cwd}/disk.img
115	mount=${cwd}/mnt
116
117	bectl_create_setup ${zpool} ${disk} ${mount}
118
119	# Create a child dataset that will be used to test creation
120	# of recursive and non-recursive boot environments.
121	atf_check zfs create -o mountpoint=/usr -o canmount=noauto \
122	    ${zpool}/ROOT/default/usr
123
124	# BE datasets with spaces are not bootable, PR 254441.
125	atf_check -e not-empty -s not-exit:0 \
126		bectl -r ${zpool}/ROOT create "foo bar"
127
128	# Test standard creation, creation of a snapshot, and creation from a
129	# snapshot.
130	atf_check bectl -r ${zpool}/ROOT create -e default default2
131	atf_check bectl -r ${zpool}/ROOT create default2@test_snap
132	atf_check bectl -r ${zpool}/ROOT create -e default2@test_snap default3
133
134	# Test standard creation, creation of a snapshot, and creation from a
135	# snapshot for recursive boot environments.
136	atf_check bectl -r ${zpool}/ROOT create -r -e default recursive
137	atf_check bectl -r ${zpool}/ROOT create -r recursive@test_snap
138	atf_check bectl -r ${zpool}/ROOT create -r -e recursive@test_snap recursive-snap
139
140	# Test that non-recursive boot environments have no child datasets.
141	atf_check -e not-empty -s not-exit:0 \
142		zfs list "${zpool}/ROOT/default2/usr"
143	atf_check -e not-empty -s not-exit:0 \
144		zfs list "${zpool}/ROOT/default3/usr"
145
146	# Test that recursive boot environments have child datasets.
147	atf_check -o not-empty \
148		zfs list "${zpool}/ROOT/recursive/usr"
149	atf_check -o not-empty \
150		zfs list "${zpool}/ROOT/recursive-snap/usr"
151}
152bectl_create_cleanup()
153{
154	bectl_cleanup $(get_zpool_name)
155}
156
157atf_test_case bectl_destroy cleanup
158bectl_destroy_head()
159{
160
161	atf_set "descr" "Check bectl destroy"
162	atf_set "require.user" root
163}
164bectl_destroy_body()
165{
166	if [ "$(atf_config_get ci false)" = "true" ] && \
167		[ "$(uname -p)" = "i386" ]; then
168		atf_skip "https://bugs.freebsd.org/249055"
169	fi
170
171	if [ "$(atf_config_get ci false)" = "true" ] && \
172		[ "$(uname -p)" = "armv7" ]; then
173		atf_skip "https://bugs.freebsd.org/249229"
174	fi
175
176	cwd=$(realpath .)
177	zpool=$(make_zpool_name)
178	disk=${cwd}/disk.img
179	mount=${cwd}/mnt
180	root=${mount}/root
181
182	bectl_create_setup ${zpool} ${disk} ${mount}
183	atf_check bectl -r ${zpool}/ROOT create -e default default2
184	atf_check -o not-empty zfs get mountpoint ${zpool}/ROOT/default2
185	atf_check -e ignore bectl -r ${zpool}/ROOT destroy default2
186	atf_check -e not-empty -s not-exit:0 zfs get mountpoint ${zpool}/ROOT/default2
187
188	# Test origin snapshot deletion when the snapshot to be destroyed
189	# belongs to a mounted dataset, see PR 236043.
190	atf_check mkdir -p ${root}
191	atf_check -o not-empty bectl -r ${zpool}/ROOT mount default ${root}
192	atf_check bectl -r ${zpool}/ROOT create -e default default3
193	atf_check bectl -r ${zpool}/ROOT destroy -o default3
194	atf_check bectl -r ${zpool}/ROOT unmount default
195
196	# create two be from the same parent and destroy the parent
197	atf_check bectl -r ${zpool}/ROOT create -e default default2
198	atf_check bectl -r ${zpool}/ROOT create -e default default3
199	atf_check bectl -r ${zpool}/ROOT destroy default
200	atf_check bectl -r ${zpool}/ROOT destroy default2
201	atf_check bectl -r ${zpool}/ROOT rename default3 default
202
203	# Create a BE, have it be the parent for another and repeat, then start
204	# deleting environments.  Arbitrarily chose default3 as the first.
205	# Sleeps are required to prevent conflicting snapshots- libbe will
206	# use the time with a serial at the end as needed to prevent collisions,
207	# but as BEs get promoted the snapshot names will convert and conflict
208	# anyways.  libbe should perhaps consider adding something extra to the
209	# default name to prevent collisions like this, but the default name
210	# includes down to the second and creating BEs this rapidly is perhaps
211	# uncommon enough.
212	atf_check bectl -r ${zpool}/ROOT create -e default default2
213	sleep 1
214	atf_check bectl -r ${zpool}/ROOT create -e default2 default3
215	sleep 1
216	atf_check bectl -r ${zpool}/ROOT create -e default3 default4
217	atf_check bectl -r ${zpool}/ROOT destroy default3
218	atf_check bectl -r ${zpool}/ROOT destroy default2
219	atf_check bectl -r ${zpool}/ROOT destroy default4
220
221	# Create two BEs, then create an unrelated snapshot on the originating
222	# BE and destroy it.  We shouldn't have promoted the second BE, and it's
223	# only possible to tell if we promoted it by making sure we didn't
224	# demote the first BE at some point -- if we did, it's origin will no
225	# longer be empty.
226	atf_check bectl -r ${zpool}/ROOT create -e default default2
227	atf_check bectl -r ${zpool}/ROOT create default@test
228
229	atf_check bectl -r ${zpool}/ROOT destroy default@test
230	atf_check -o inline:"-\n" zfs get -Ho value origin ${zpool}/ROOT/default
231	atf_check bectl -r ${zpool}/ROOT destroy default2
232
233	# As observed by beadm, if we explicitly try to destroy a snapshot that
234	# leads to clones, we shouldn't have allowed it.
235	atf_check bectl -r ${zpool}/ROOT create default@test
236	atf_check bectl -r ${zpool}/ROOT create -e default@test default2
237
238	atf_check -e  not-empty -s not-exit:0 bectl -r ${zpool}/ROOT destroy \
239	    default@test
240}
241bectl_destroy_cleanup()
242{
243
244	bectl_cleanup $(get_zpool_name)
245}
246
247atf_test_case bectl_export_import cleanup
248bectl_export_import_head()
249{
250
251	atf_set "descr" "Check bectl export and import"
252	atf_set "require.user" root
253}
254bectl_export_import_body()
255{
256	if [ "$(atf_config_get ci false)" = "true" ] && \
257		[ "$(uname -p)" = "i386" ]; then
258		atf_skip "https://bugs.freebsd.org/249055"
259	fi
260
261	if [ "$(atf_config_get ci false)" = "true" ] && \
262		[ "$(uname -p)" = "armv7" ]; then
263		atf_skip "https://bugs.freebsd.org/249229"
264	fi
265
266	cwd=$(realpath .)
267	zpool=$(make_zpool_name)
268	disk=${cwd}/disk.img
269	mount=${cwd}/mnt
270
271	bectl_create_setup ${zpool} ${disk} ${mount}
272	atf_check -o save:exported bectl -r ${zpool}/ROOT export default
273	atf_check -x "bectl -r ${zpool}/ROOT import default2 < exported"
274	atf_check -o not-empty zfs get mountpoint ${zpool}/ROOT/default2
275	atf_check -e ignore bectl -r ${zpool}/ROOT destroy default2
276	atf_check -e not-empty -s not-exit:0 zfs get mountpoint \
277	    ${zpool}/ROOT/default2
278}
279bectl_export_import_cleanup()
280{
281
282	bectl_cleanup $(get_zpool_name)
283}
284
285atf_test_case bectl_list cleanup
286bectl_list_head()
287{
288
289	atf_set "descr" "Check bectl list"
290	atf_set "require.user" root
291}
292bectl_list_body()
293{
294	if [ "$(atf_config_get ci false)" = "true" ] && \
295		[ "$(uname -p)" = "i386" ]; then
296		atf_skip "https://bugs.freebsd.org/249055"
297	fi
298
299	if [ "$(atf_config_get ci false)" = "true" ] && \
300		[ "$(uname -p)" = "armv7" ]; then
301		atf_skip "https://bugs.freebsd.org/249229"
302	fi
303
304	cwd=$(realpath .)
305	zpool=$(make_zpool_name)
306	disk=${cwd}/disk.img
307	mount=${cwd}/mnt
308
309	bectl_create_setup ${zpool} ${disk} ${mount}
310	# Test the list functionality, including that BEs come and go away
311	# as they're created and destroyed.  Creation and destruction tests
312	# use the 'zfs' utility to verify that they're actually created, so
313	# these are just light tests that 'list' is picking them up.
314	atf_check -o save:list.out bectl -r ${zpool}/ROOT list
315	atf_check -o not-empty grep 'default' list.out
316	atf_check bectl -r ${zpool}/ROOT create -e default default2
317	atf_check -o save:list.out bectl -r ${zpool}/ROOT list
318	atf_check -o not-empty grep 'default2' list.out
319	atf_check -e ignore bectl -r ${zpool}/ROOT destroy default2
320	atf_check -o save:list.out bectl -r ${zpool}/ROOT list
321	atf_check -s not-exit:0 grep 'default2' list.out
322	# XXX TODO: Formatting checks
323}
324bectl_list_cleanup()
325{
326
327	bectl_cleanup $(get_zpool_name)
328}
329
330atf_test_case bectl_mount cleanup
331bectl_mount_head()
332{
333
334	atf_set "descr" "Check bectl mount/unmount"
335	atf_set "require.user" root
336}
337bectl_mount_body()
338{
339	if [ "$(atf_config_get ci false)" = "true" ] && \
340		[ "$(uname -p)" = "i386" ]; then
341		atf_skip "https://bugs.freebsd.org/249055"
342	fi
343
344	if [ "$(atf_config_get ci false)" = "true" ] && \
345		[ "$(uname -p)" = "armv7" ]; then
346		atf_skip "https://bugs.freebsd.org/249229"
347	fi
348
349	cwd=$(realpath .)
350	zpool=$(make_zpool_name)
351	disk=${cwd}/disk.img
352	mount=${cwd}/mnt
353	root=${mount}/root
354
355	bectl_create_deep_setup ${zpool} ${disk} ${mount}
356	atf_check mkdir -p ${root}
357	# Test unmount first...
358	atf_check -o not-empty bectl -r ${zpool}/ROOT mount default ${root}
359	atf_check -o not-empty -x "mount | grep '^${zpool}/ROOT/default'"
360	atf_check bectl -r ${zpool}/ROOT unmount default
361	atf_check -s not-exit:0 -x "mount | grep '^${zpool}/ROOT/default'"
362	# Then umount!
363	atf_check -o not-empty bectl -r ${zpool}/ROOT mount default ${root}
364	atf_check -o not-empty -x "mount | grep '^${zpool}/ROOT/default'"
365	atf_check bectl -r ${zpool}/ROOT umount default
366	atf_check -s not-exit:0 -x "mount | grep '^${zpool}/ROOT/default'"
367}
368bectl_mount_cleanup()
369{
370
371	bectl_cleanup $(get_zpool_name)
372}
373
374atf_test_case bectl_rename cleanup
375bectl_rename_head()
376{
377
378	atf_set "descr" "Check bectl rename"
379	atf_set "require.user" root
380}
381bectl_rename_body()
382{
383	if [ "$(atf_config_get ci false)" = "true" ] && \
384		[ "$(uname -p)" = "i386" ]; then
385		atf_skip "https://bugs.freebsd.org/249055"
386	fi
387
388	if [ "$(atf_config_get ci false)" = "true" ] && \
389		[ "$(uname -p)" = "armv7" ]; then
390		atf_skip "https://bugs.freebsd.org/249229"
391	fi
392
393	cwd=$(realpath .)
394	zpool=$(make_zpool_name)
395	disk=${cwd}/disk.img
396	mount=${cwd}/mnt
397
398	bectl_create_setup ${zpool} ${disk} ${mount}
399	atf_check bectl -r ${zpool}/ROOT rename default default2
400	atf_check -o not-empty zfs get mountpoint ${zpool}/ROOT/default2
401	atf_check -e not-empty -s not-exit:0 zfs get mountpoint \
402	    ${zpool}/ROOT/default
403}
404bectl_rename_cleanup()
405{
406
407	bectl_cleanup $(get_zpool_name)
408}
409
410atf_test_case bectl_jail cleanup
411bectl_jail_head()
412{
413
414	atf_set "descr" "Check bectl rename"
415	atf_set "require.user" root
416	atf_set "require.progs" jail
417}
418bectl_jail_body()
419{
420	if [ "$(atf_config_get ci false)" = "true" ] && \
421		[ "$(uname -p)" = "i386" ]; then
422		atf_skip "https://bugs.freebsd.org/249055"
423	fi
424
425	if [ "$(atf_config_get ci false)" = "true" ] && \
426		[ "$(uname -p)" = "armv7" ]; then
427		atf_skip "https://bugs.freebsd.org/249229"
428	fi
429
430	cwd=$(realpath .)
431	zpool=$(make_zpool_name)
432	disk=${cwd}/disk.img
433	mount=${cwd}/mnt
434	root=${mount}/root
435
436	if [ ! -f /rescue/rescue ]; then
437		atf_skip "This test requires a rescue binary"
438	fi
439	bectl_create_deep_setup ${zpool} ${disk} ${mount}
440	# Prepare our minimal BE... plop a rescue binary into it
441	atf_check mkdir -p ${root}
442	atf_check -o ignore bectl -r ${zpool}/ROOT mount default ${root}
443	atf_check mkdir -p ${root}/rescue
444	atf_check cp /rescue/rescue ${root}/rescue/rescue
445	atf_check bectl -r ${zpool}/ROOT umount default
446
447	# Prepare some more boot environments
448	atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT create -e default target
449	atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT create -e default 1234
450
451	# Attempt to unjail a BE with numeric name; jail_getid at one point
452	# did not validate that the input was a valid jid before returning the
453	# jid.
454	atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b 1234
455	atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail 1234
456
457	# When a jail name is not explicit, it should match the jail id.
458	atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b -o jid=233637 default
459	atf_check -o inline:"233637\n" -s exit:0 -x "jls -j 233637 name"
460	atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail default
461
462	# Basic command-mode tests, with and without jail cleanup
463	atf_check -o inline:"rescue\nusr\n" bectl -r ${zpool}/ROOT \
464	    jail default /rescue/rescue ls -1
465	atf_check -o inline:"rescue\nusr\n" bectl -r ${zpool}/ROOT \
466	    jail -Uo path=${root} default /rescue/rescue ls -1
467	atf_check [ -f ${root}/rescue/rescue ]
468	atf_check bectl -r ${zpool}/ROOT ujail default
469
470	# Batch mode tests
471	atf_check bectl -r ${zpool}/ROOT jail -bo path=${root} default
472	atf_check -o not-empty -x "jls | grep -F \"${root}\""
473	atf_check bectl -r ${zpool}/ROOT ujail default
474	atf_check -s not-exit:0 -x "jls | grep -F \"${root}\""
475	# 'unjail' naming
476	atf_check bectl -r ${zpool}/ROOT jail -b default
477	atf_check bectl -r ${zpool}/ROOT unjail default
478	atf_check -s not-exit:0 -x "jls | grep -F \"${root}\""
479	# 'unjail' by BE name. Force bectl to lookup jail id by the BE name.
480	atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b default
481	atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b -o name=bectl_test target
482	atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail target
483	atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail default
484	# cannot unjail an unjailed BE (by either command name)
485	atf_check -e ignore -s not-exit:0 bectl -r ${zpool}/ROOT ujail default
486	atf_check -e ignore -s not-exit:0 bectl -r ${zpool}/ROOT unjail default
487
488	# set+unset
489	atf_check bectl -r ${zpool}/ROOT jail -b -o path=${root} -u path default
490	# Ensure that it didn't mount at ${root}
491	atf_check -s not-exit:0 -x "mount | grep -F '${root}'"
492	atf_check bectl -r ${zpool}/ROOT ujail default
493}
494
495# If a test has failed, it's possible that the boot environment hasn't
496# been 'unjail'ed. We want to remove the jail before 'bectl_cleanup'
497# attempts to destroy the zpool.
498bectl_jail_cleanup()
499{
500	if [ "$(atf_config_get ci false)" = "true" ] && \
501		[ "$(uname -p)" = "i386" ]; then
502		atf_skip "https://bugs.freebsd.org/249055"
503	fi
504
505	if [ "$(atf_config_get ci false)" = "true" ] && \
506		[ "$(uname -p)" = "armv7" ]; then
507		atf_skip "https://bugs.freebsd.org/249229"
508	fi
509
510	zpool=$(get_zpool_name)
511	for bootenv in "default" "target" "1234"; do
512		# mountpoint of the boot environment
513		mountpoint="$(bectl -r ${zpool}/ROOT list -H | grep ${bootenv} | awk '{print $3}')"
514
515		# see if any jail paths match the boot environment mountpoint
516		jailid="$(jls | grep ${mountpoint} | awk '{print $1}')"
517
518		if [ -z "$jailid" ]; then
519		       continue;
520		fi
521		jail -r ${jailid}
522	done;
523
524	bectl_cleanup ${zpool}
525}
526
527atf_test_case bectl_promotion cleanup
528bectl_promotion_head()
529{
530	atf_set "descr" "Check bectl promotion upon activation"
531	atf_set "require.user" root
532}
533bectl_promotion_body()
534{
535	if [ "$(atf_config_get ci false)" = "true" ] && \
536		[ "$(uname -p)" = "i386" ]; then
537		atf_skip "https://bugs.freebsd.org/249055"
538	fi
539
540	if [ "$(atf_config_get ci false)" = "true" ] && \
541		[ "$(uname -p)" = "armv7" ]; then
542		atf_skip "https://bugs.freebsd.org/249229"
543	fi
544
545	cwd=$(realpath .)
546	zpool=$(make_zpool_name)
547	disk=${cwd}/disk.img
548	mount=${cwd}/mnt
549	root=${mount}/root
550
551	bectl_create_deep_setup ${zpool} ${disk} ${mount}
552	atf_check mkdir -p ${root}
553
554	# Sleeps interspersed to workaround some naming quirks; notably,
555	# bectl will append a serial if two snapshots were created within
556	# the same second, but it can only do that for the one root it's
557	# operating on.  It won't check that other roots don't have a snapshot
558	# with the same name, and the promotion will fail.
559	atf_check bectl -r ${zpool}/ROOT rename default A
560	sleep 1
561	atf_check bectl -r ${zpool}/ROOT create -r -e A B
562	sleep 1
563	atf_check bectl -r ${zpool}/ROOT create -r -e B C
564
565	# C should be a clone of B to start with
566	atf_check -o not-inline:"-" zfs list -Hr -o origin ${zpool}/ROOT/C
567
568	# Activating it should then promote it all the way out of clone-hood.
569	# This entails two promotes internally, as the first would promote it to
570	# a snapshot of A before finally promoting it the second time out of
571	# clone status.
572	atf_check -o not-empty bectl -r ${zpool}/ROOT activate C
573	atf_check -o inline:"-\n-\n" zfs list -Hr -o origin ${zpool}/ROOT/C
574}
575bectl_promotion_cleanup()
576{
577	bectl_cleanup $(get_zpool_name)
578}
579
580atf_init_test_cases()
581{
582	atf_add_test_case bectl_create
583	atf_add_test_case bectl_destroy
584	atf_add_test_case bectl_export_import
585	atf_add_test_case bectl_list
586	atf_add_test_case bectl_mount
587	atf_add_test_case bectl_rename
588	atf_add_test_case bectl_jail
589	atf_add_test_case bectl_promotion
590}
591