]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/bectl/tests/bectl_test.sh
Skip armv7 bectl tests on CI; they deadlock (""KSTACK_PAGES is 2").
[FreeBSD/FreeBSD.git] / sbin / bectl / tests / bectl_test.sh
1 #
2 # SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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 # $FreeBSD$
28
29 ZPOOL_NAME_FILE=zpool_name
30 get_zpool_name()
31 {
32         cat $ZPOOL_NAME_FILE
33 }
34 make_zpool_name()
35 {
36         mktemp -u bectl_test_XXXXXX > $ZPOOL_NAME_FILE
37         get_zpool_name
38 }
39
40 # Establishes a bectl_create zpool that can be used for some light testing; contains
41 # a 'default' BE and not much else.
42 bectl_create_setup()
43 {
44         zpool=$1
45         disk=$2
46         mnt=$3
47
48         # Sanity check to make sure `make_zpool_name` succeeded
49         atf_check test -n "$zpool"
50
51         kldload -n -q zfs || atf_skip "ZFS module not loaded on the current system"
52         atf_check mkdir -p ${mnt}
53         atf_check truncate -s 1G ${disk}
54         atf_check zpool create -o altroot=${mnt} ${zpool} ${disk}
55         atf_check zfs create -o mountpoint=none ${zpool}/ROOT
56         atf_check zfs create -o mountpoint=/ -o canmount=noauto \
57             ${zpool}/ROOT/default
58 }
59 bectl_create_deep_setup()
60 {
61         zpool=$1
62         disk=$2
63         mnt=$3
64
65         # Sanity check to make sure `make_zpool_name` succeeded
66         atf_check test -n "$zpool"
67
68         bectl_create_setup ${zpool} ${disk} ${mnt}
69         atf_check mkdir -p ${root}
70         atf_check -o ignore bectl -r ${zpool}/ROOT mount default ${root}
71         atf_check mkdir -p ${root}/usr
72         atf_check zfs create -o mountpoint=/usr -o canmount=noauto \
73             ${zpool}/ROOT/default/usr
74         atf_check -o ignore bectl -r ${zpool}/ROOT umount default
75 }
76
77 bectl_cleanup()
78 {
79         zpool=$1
80         if [ -z "$zpool" ]; then
81                 echo "Skipping cleanup; zpool not set up"
82         elif zpool get health ${zpool} >/dev/null 2>&1; then
83                 zpool destroy -f ${zpool}
84         fi
85 }
86
87 atf_test_case bectl_create cleanup
88 bectl_create_head()
89 {
90
91         atf_set "descr" "Check the various forms of bectl create"
92         atf_set "require.user" root
93 }
94 bectl_create_body()
95 {
96         if [ "$(atf_config_get ci false)" = "true" ] && \
97                 [ "$(uname -p)" = "i386" ]; then
98                 atf_skip "https://bugs.freebsd.org/249055"
99         fi
100
101         if [ "$(atf_config_get ci false)" = "true" ] && \
102                 [ "$(uname -p)" = "armv7" ]; then
103                 atf_skip "https://bugs.freebsd.org/249229"
104         fi
105
106         cwd=$(realpath .)
107         zpool=$(make_zpool_name)
108         disk=${cwd}/disk.img
109         mount=${cwd}/mnt
110
111         bectl_create_setup ${zpool} ${disk} ${mount}
112
113         # Create a child dataset that will be used to test creation
114         # of recursive and non-recursive boot environments.
115         atf_check zfs create -o mountpoint=/usr -o canmount=noauto \
116             ${zpool}/ROOT/default/usr
117
118         # Test standard creation, creation of a snapshot, and creation from a
119         # snapshot.
120         atf_check bectl -r ${zpool}/ROOT create -e default default2
121         atf_check bectl -r ${zpool}/ROOT create default2@test_snap
122         atf_check bectl -r ${zpool}/ROOT create -e default2@test_snap default3
123
124         # Test standard creation, creation of a snapshot, and creation from a
125         # snapshot for recursive boot environments.
126         atf_check bectl -r ${zpool}/ROOT create -r -e default recursive
127         atf_check bectl -r ${zpool}/ROOT create -r recursive@test_snap
128         atf_check bectl -r ${zpool}/ROOT create -r -e recursive@test_snap recursive-snap
129
130         # Test that non-recursive boot environments have no child datasets.
131         atf_check -e not-empty -s not-exit:0 \
132                 zfs list "${zpool}/ROOT/default2/usr"
133         atf_check -e not-empty -s not-exit:0 \
134                 zfs list "${zpool}/ROOT/default3/usr"
135
136         # Test that recursive boot environments have child datasets.
137         atf_check -o not-empty \
138                 zfs list "${zpool}/ROOT/recursive/usr"
139         atf_check -o not-empty \
140                 zfs list "${zpool}/ROOT/recursive-snap/usr"
141 }
142 bectl_create_cleanup()
143 {
144         bectl_cleanup $(get_zpool_name)
145 }
146
147 atf_test_case bectl_destroy cleanup
148 bectl_destroy_head()
149 {
150
151         atf_set "descr" "Check bectl destroy"
152         atf_set "require.user" root
153 }
154 bectl_destroy_body()
155 {
156         if [ "$(atf_config_get ci false)" = "true" ] && \
157                 [ "$(uname -p)" = "i386" ]; then
158                 atf_skip "https://bugs.freebsd.org/249055"
159         fi
160
161         if [ "$(atf_config_get ci false)" = "true" ] && \
162                 [ "$(uname -p)" = "armv7" ]; then
163                 atf_skip "https://bugs.freebsd.org/249229"
164         fi
165
166         cwd=$(realpath .)
167         zpool=$(make_zpool_name)
168         disk=${cwd}/disk.img
169         mount=${cwd}/mnt
170         root=${mount}/root
171
172         bectl_create_setup ${zpool} ${disk} ${mount}
173         atf_check bectl -r ${zpool}/ROOT create -e default default2
174         atf_check -o not-empty zfs get mountpoint ${zpool}/ROOT/default2
175         atf_check -e ignore bectl -r ${zpool}/ROOT destroy default2
176         atf_check -e not-empty -s not-exit:0 zfs get mountpoint ${zpool}/ROOT/default2
177
178         # Test origin snapshot deletion when the snapshot to be destroyed
179         # belongs to a mounted dataset, see PR 236043.
180         atf_check mkdir -p ${root}
181         atf_check -o not-empty bectl -r ${zpool}/ROOT mount default ${root}
182         atf_check bectl -r ${zpool}/ROOT create -e default default3
183         atf_check bectl -r ${zpool}/ROOT destroy -o default3
184         atf_check bectl -r ${zpool}/ROOT unmount default
185
186         # create two be from the same parent and destroy the parent
187         atf_check bectl -r ${zpool}/ROOT create -e default default2
188         atf_check bectl -r ${zpool}/ROOT create -e default default3
189         atf_check bectl -r ${zpool}/ROOT destroy default
190         atf_check bectl -r ${zpool}/ROOT destroy default2
191         atf_check bectl -r ${zpool}/ROOT rename default3 default
192
193         # Create a BE, have it be the parent for another and repeat, then start
194         # deleting environments.  Arbitrarily chose default3 as the first.
195         # Sleeps are required to prevent conflicting snapshots- libbe will
196         # use the time with a serial at the end as needed to prevent collisions,
197         # but as BEs get promoted the snapshot names will convert and conflict
198         # anyways.  libbe should perhaps consider adding something extra to the
199         # default name to prevent collisions like this, but the default name
200         # includes down to the second and creating BEs this rapidly is perhaps
201         # uncommon enough.
202         atf_check bectl -r ${zpool}/ROOT create -e default default2
203         sleep 1
204         atf_check bectl -r ${zpool}/ROOT create -e default2 default3
205         sleep 1
206         atf_check bectl -r ${zpool}/ROOT create -e default3 default4
207         atf_check bectl -r ${zpool}/ROOT destroy default3
208         atf_check bectl -r ${zpool}/ROOT destroy default2
209         atf_check bectl -r ${zpool}/ROOT destroy default4
210
211         # Create two BEs, then create an unrelated snapshot on the originating
212         # BE and destroy it.  We shouldn't have promoted the second BE, and it's
213         # only possible to tell if we promoted it by making sure we didn't
214         # demote the first BE at some point -- if we did, it's origin will no
215         # longer be empty.
216         atf_check bectl -r ${zpool}/ROOT create -e default default2
217         atf_check bectl -r ${zpool}/ROOT create default@test
218
219         atf_check bectl -r ${zpool}/ROOT destroy default@test
220         atf_check -o inline:"-\n" zfs get -Ho value origin ${zpool}/ROOT/default
221         atf_check bectl -r ${zpool}/ROOT destroy default2
222
223         # As observed by beadm, if we explicitly try to destroy a snapshot that
224         # leads to clones, we shouldn't have allowed it.
225         atf_check bectl -r ${zpool}/ROOT create default@test
226         atf_check bectl -r ${zpool}/ROOT create -e default@test default2
227
228         atf_check -e  not-empty -s not-exit:0 bectl -r ${zpool}/ROOT destroy \
229             default@test
230 }
231 bectl_destroy_cleanup()
232 {
233
234         bectl_cleanup $(get_zpool_name)
235 }
236
237 atf_test_case bectl_export_import cleanup
238 bectl_export_import_head()
239 {
240
241         atf_set "descr" "Check bectl export and import"
242         atf_set "require.user" root
243 }
244 bectl_export_import_body()
245 {
246         if [ "$(atf_config_get ci false)" = "true" ] && \
247                 [ "$(uname -p)" = "i386" ]; then
248                 atf_skip "https://bugs.freebsd.org/249055"
249         fi
250
251         if [ "$(atf_config_get ci false)" = "true" ] && \
252                 [ "$(uname -p)" = "armv7" ]; then
253                 atf_skip "https://bugs.freebsd.org/249229"
254         fi
255
256         cwd=$(realpath .)
257         zpool=$(make_zpool_name)
258         disk=${cwd}/disk.img
259         mount=${cwd}/mnt
260
261         bectl_create_setup ${zpool} ${disk} ${mount}
262         atf_check -o save:exported bectl -r ${zpool}/ROOT export default
263         atf_check -x "bectl -r ${zpool}/ROOT import default2 < exported"
264         atf_check -o not-empty zfs get mountpoint ${zpool}/ROOT/default2
265         atf_check -e ignore bectl -r ${zpool}/ROOT destroy default2
266         atf_check -e not-empty -s not-exit:0 zfs get mountpoint \
267             ${zpool}/ROOT/default2
268 }
269 bectl_export_import_cleanup()
270 {
271
272         bectl_cleanup $(get_zpool_name)
273 }
274
275 atf_test_case bectl_list cleanup
276 bectl_list_head()
277 {
278
279         atf_set "descr" "Check bectl list"
280         atf_set "require.user" root
281 }
282 bectl_list_body()
283 {
284         if [ "$(atf_config_get ci false)" = "true" ] && \
285                 [ "$(uname -p)" = "i386" ]; then
286                 atf_skip "https://bugs.freebsd.org/249055"
287         fi
288
289         if [ "$(atf_config_get ci false)" = "true" ] && \
290                 [ "$(uname -p)" = "armv7" ]; then
291                 atf_skip "https://bugs.freebsd.org/249229"
292         fi
293
294         cwd=$(realpath .)
295         zpool=$(make_zpool_name)
296         disk=${cwd}/disk.img
297         mount=${cwd}/mnt
298
299         bectl_create_setup ${zpool} ${disk} ${mount}
300         # Test the list functionality, including that BEs come and go away
301         # as they're created and destroyed.  Creation and destruction tests
302         # use the 'zfs' utility to verify that they're actually created, so
303         # these are just light tests that 'list' is picking them up.
304         atf_check -o save:list.out bectl -r ${zpool}/ROOT list
305         atf_check -o not-empty grep 'default' list.out
306         atf_check bectl -r ${zpool}/ROOT create -e default default2
307         atf_check -o save:list.out bectl -r ${zpool}/ROOT list
308         atf_check -o not-empty grep 'default2' list.out
309         atf_check -e ignore bectl -r ${zpool}/ROOT destroy default2
310         atf_check -o save:list.out bectl -r ${zpool}/ROOT list
311         atf_check -s not-exit:0 grep 'default2' list.out
312         # XXX TODO: Formatting checks
313 }
314 bectl_list_cleanup()
315 {
316
317         bectl_cleanup $(get_zpool_name)
318 }
319
320 atf_test_case bectl_mount cleanup
321 bectl_mount_head()
322 {
323
324         atf_set "descr" "Check bectl mount/unmount"
325         atf_set "require.user" root
326 }
327 bectl_mount_body()
328 {
329         if [ "$(atf_config_get ci false)" = "true" ] && \
330                 [ "$(uname -p)" = "i386" ]; then
331                 atf_skip "https://bugs.freebsd.org/249055"
332         fi
333
334         if [ "$(atf_config_get ci false)" = "true" ] && \
335                 [ "$(uname -p)" = "armv7" ]; then
336                 atf_skip "https://bugs.freebsd.org/249229"
337         fi
338
339         cwd=$(realpath .)
340         zpool=$(make_zpool_name)
341         disk=${cwd}/disk.img
342         mount=${cwd}/mnt
343         root=${mount}/root
344
345         bectl_create_deep_setup ${zpool} ${disk} ${mount}
346         atf_check mkdir -p ${root}
347         # Test unmount first...
348         atf_check -o not-empty bectl -r ${zpool}/ROOT mount default ${root}
349         atf_check -o not-empty -x "mount | grep '^${zpool}/ROOT/default'"
350         atf_check bectl -r ${zpool}/ROOT unmount default
351         atf_check -s not-exit:0 -x "mount | grep '^${zpool}/ROOT/default'"
352         # Then umount!
353         atf_check -o not-empty bectl -r ${zpool}/ROOT mount default ${root}
354         atf_check -o not-empty -x "mount | grep '^${zpool}/ROOT/default'"
355         atf_check bectl -r ${zpool}/ROOT umount default
356         atf_check -s not-exit:0 -x "mount | grep '^${zpool}/ROOT/default'"
357 }
358 bectl_mount_cleanup()
359 {
360
361         bectl_cleanup $(get_zpool_name)
362 }
363
364 atf_test_case bectl_rename cleanup
365 bectl_rename_head()
366 {
367
368         atf_set "descr" "Check bectl rename"
369         atf_set "require.user" root
370 }
371 bectl_rename_body()
372 {
373         if [ "$(atf_config_get ci false)" = "true" ] && \
374                 [ "$(uname -p)" = "i386" ]; then
375                 atf_skip "https://bugs.freebsd.org/249055"
376         fi
377
378         if [ "$(atf_config_get ci false)" = "true" ] && \
379                 [ "$(uname -p)" = "armv7" ]; then
380                 atf_skip "https://bugs.freebsd.org/249229"
381         fi
382
383         cwd=$(realpath .)
384         zpool=$(make_zpool_name)
385         disk=${cwd}/disk.img
386         mount=${cwd}/mnt
387
388         bectl_create_setup ${zpool} ${disk} ${mount}
389         atf_check bectl -r ${zpool}/ROOT rename default default2
390         atf_check -o not-empty zfs get mountpoint ${zpool}/ROOT/default2
391         atf_check -e not-empty -s not-exit:0 zfs get mountpoint \
392             ${zpool}/ROOT/default
393 }
394 bectl_rename_cleanup()
395 {
396
397         bectl_cleanup $(get_zpool_name)
398 }
399
400 atf_test_case bectl_jail cleanup
401 bectl_jail_head()
402 {
403
404         atf_set "descr" "Check bectl rename"
405         atf_set "require.user" root
406         atf_set "require.progs" jail
407 }
408 bectl_jail_body()
409 {
410         if [ "$(atf_config_get ci false)" = "true" ] && \
411                 [ "$(uname -p)" = "i386" ]; then
412                 atf_skip "https://bugs.freebsd.org/249055"
413         fi
414
415         if [ "$(atf_config_get ci false)" = "true" ] && \
416                 [ "$(uname -p)" = "armv7" ]; then
417                 atf_skip "https://bugs.freebsd.org/249229"
418         fi
419
420         cwd=$(realpath .)
421         zpool=$(make_zpool_name)
422         disk=${cwd}/disk.img
423         mount=${cwd}/mnt
424         root=${mount}/root
425
426         if [ ! -f /rescue/rescue ]; then
427                 atf_skip "This test requires a rescue binary"
428         fi
429         bectl_create_deep_setup ${zpool} ${disk} ${mount}
430         # Prepare our minimal BE... plop a rescue binary into it
431         atf_check mkdir -p ${root}
432         atf_check -o ignore bectl -r ${zpool}/ROOT mount default ${root}
433         atf_check mkdir -p ${root}/rescue
434         atf_check cp /rescue/rescue ${root}/rescue/rescue
435         atf_check bectl -r ${zpool}/ROOT umount default
436
437         # Prepare some more boot environments
438         atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT create -e default target
439         atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT create -e default 1234
440
441         # Attempt to unjail a BE with numeric name; jail_getid at one point
442         # did not validate that the input was a valid jid before returning the
443         # jid.
444         atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b 1234
445         atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail 1234
446
447         # When a jail name is not explicit, it should match the jail id.
448         atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b -o jid=233637 default
449         atf_check -o inline:"233637\n" -s exit:0 -x "jls -j 233637 name"
450         atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail default
451
452         # Basic command-mode tests, with and without jail cleanup
453         atf_check -o inline:"rescue\nusr\n" bectl -r ${zpool}/ROOT \
454             jail default /rescue/rescue ls -1
455         atf_check -o inline:"rescue\nusr\n" bectl -r ${zpool}/ROOT \
456             jail -Uo path=${root} default /rescue/rescue ls -1
457         atf_check [ -f ${root}/rescue/rescue ]
458         atf_check bectl -r ${zpool}/ROOT ujail default
459
460         # Batch mode tests
461         atf_check bectl -r ${zpool}/ROOT jail -bo path=${root} default
462         atf_check -o not-empty -x "jls | grep -F \"${root}\""
463         atf_check bectl -r ${zpool}/ROOT ujail default
464         atf_check -s not-exit:0 -x "jls | grep -F \"${root}\""
465         # 'unjail' naming
466         atf_check bectl -r ${zpool}/ROOT jail -b default
467         atf_check bectl -r ${zpool}/ROOT unjail default
468         atf_check -s not-exit:0 -x "jls | grep -F \"${root}\""
469         # 'unjail' by BE name. Force bectl to lookup jail id by the BE name.
470         atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b default
471         atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b -o name=bectl_test target
472         atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail target
473         atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail default
474         # cannot unjail an unjailed BE (by either command name)
475         atf_check -e ignore -s not-exit:0 bectl -r ${zpool}/ROOT ujail default
476         atf_check -e ignore -s not-exit:0 bectl -r ${zpool}/ROOT unjail default
477
478         # set+unset
479         atf_check bectl -r ${zpool}/ROOT jail -b -o path=${root} -u path default
480         # Ensure that it didn't mount at ${root}
481         atf_check -s not-exit:0 -x "mount | grep -F '${root}'"
482         atf_check bectl -r ${zpool}/ROOT ujail default
483 }
484
485 # If a test has failed, it's possible that the boot environment hasn't
486 # been 'unjail'ed. We want to remove the jail before 'bectl_cleanup'
487 # attempts to destroy the zpool.
488 bectl_jail_cleanup()
489 {
490         if [ "$(atf_config_get ci false)" = "true" ] && \
491                 [ "$(uname -p)" = "i386" ]; then
492                 atf_skip "https://bugs.freebsd.org/249055"
493         fi
494
495         if [ "$(atf_config_get ci false)" = "true" ] && \
496                 [ "$(uname -p)" = "armv7" ]; then
497                 atf_skip "https://bugs.freebsd.org/249229"
498         fi
499
500         zpool=$(get_zpool_name)
501         for bootenv in "default" "target" "1234"; do
502                 # mountpoint of the boot environment
503                 mountpoint="$(bectl -r ${zpool}/ROOT list -H | grep ${bootenv} | awk '{print $3}')"
504
505                 # see if any jail paths match the boot environment mountpoint
506                 jailid="$(jls | grep ${mountpoint} | awk '{print $1}')"
507
508                 if [ -z "$jailid" ]; then
509                        continue;
510                 fi
511                 jail -r ${jailid}
512         done;
513
514         bectl_cleanup ${zpool}
515 }
516
517 atf_init_test_cases()
518 {
519         atf_add_test_case bectl_create
520         atf_add_test_case bectl_destroy
521         atf_add_test_case bectl_export_import
522         atf_add_test_case bectl_list
523         atf_add_test_case bectl_mount
524         atf_add_test_case bectl_rename
525         atf_add_test_case bectl_jail
526 }