]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/bectl/tests/bectl_test.sh
Add 'contrib/unifdef/' from commit '0da44885831dc0a43c4ca6ff04a2430993cc0a80'
[FreeBSD/FreeBSD.git] / sbin / bectl / tests / bectl_test.sh
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
28 ZPOOL_NAME_FILE=zpool_name
29 get_zpool_name()
30 {
31         cat $ZPOOL_NAME_FILE
32 }
33 make_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.
41 bectl_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 }
65 bectl_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
83 bectl_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
93 atf_test_case bectl_create cleanup
94 bectl_create_head()
95 {
96
97         atf_set "descr" "Check the various forms of bectl create"
98         atf_set "require.user" root
99 }
100 bectl_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 }
152 bectl_create_cleanup()
153 {
154         bectl_cleanup $(get_zpool_name)
155 }
156
157 atf_test_case bectl_destroy cleanup
158 bectl_destroy_head()
159 {
160
161         atf_set "descr" "Check bectl destroy"
162         atf_set "require.user" root
163 }
164 bectl_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 }
241 bectl_destroy_cleanup()
242 {
243
244         bectl_cleanup $(get_zpool_name)
245 }
246
247 atf_test_case bectl_export_import cleanup
248 bectl_export_import_head()
249 {
250
251         atf_set "descr" "Check bectl export and import"
252         atf_set "require.user" root
253 }
254 bectl_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 }
279 bectl_export_import_cleanup()
280 {
281
282         bectl_cleanup $(get_zpool_name)
283 }
284
285 atf_test_case bectl_list cleanup
286 bectl_list_head()
287 {
288
289         atf_set "descr" "Check bectl list"
290         atf_set "require.user" root
291 }
292 bectl_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 }
324 bectl_list_cleanup()
325 {
326
327         bectl_cleanup $(get_zpool_name)
328 }
329
330 atf_test_case bectl_mount cleanup
331 bectl_mount_head()
332 {
333
334         atf_set "descr" "Check bectl mount/unmount"
335         atf_set "require.user" root
336 }
337 bectl_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 }
368 bectl_mount_cleanup()
369 {
370
371         bectl_cleanup $(get_zpool_name)
372 }
373
374 atf_test_case bectl_rename cleanup
375 bectl_rename_head()
376 {
377
378         atf_set "descr" "Check bectl rename"
379         atf_set "require.user" root
380 }
381 bectl_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 }
404 bectl_rename_cleanup()
405 {
406
407         bectl_cleanup $(get_zpool_name)
408 }
409
410 atf_test_case bectl_jail cleanup
411 bectl_jail_head()
412 {
413
414         atf_set "descr" "Check bectl rename"
415         atf_set "require.user" root
416         atf_set "require.progs" jail
417 }
418 bectl_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.
498 bectl_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
527 atf_test_case bectl_promotion cleanup
528 bectl_promotion_head()
529 {
530         atf_set "descr" "Check bectl promotion upon activation"
531         atf_set "require.user" root
532 }
533 bectl_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 }
575 bectl_promotion_cleanup()
576 {
577         bectl_cleanup $(get_zpool_name)
578 }
579
580 atf_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 }