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# Establishes a bectl_create zpool that can be used for some light testing; contains 30# a 'default' BE and not much else. 31bectl_create_setup() 32{ 33 zpool=$1 34 disk=$2 35 mnt=$3 36 37 kldload -n -q zfs || atf_skip "ZFS module not loaded on the current system" 38 atf_check mkdir -p ${mnt} 39 atf_check truncate -s 1G ${disk} 40 atf_check zpool create -o altroot=${mnt} ${zpool} ${disk} 41 atf_check zfs create -o mountpoint=none ${zpool}/ROOT 42 atf_check zfs create -o mountpoint=/ -o canmount=noauto \ 43 ${zpool}/ROOT/default 44} 45bectl_create_deep_setup() 46{ 47 zpool=$1 48 disk=$2 49 mnt=$3 50 51 bectl_create_setup ${zpool} ${disk} ${mnt} 52 atf_check mkdir -p ${root} 53 atf_check -o ignore bectl -r ${zpool}/ROOT mount default ${root} 54 atf_check mkdir -p ${root}/usr 55 atf_check zfs create -o mountpoint=/usr -o canmount=noauto \ 56 ${zpool}/ROOT/default/usr 57 atf_check -o ignore bectl -r ${zpool}/ROOT umount default 58} 59 60bectl_cleanup() 61{ 62 zpool=$1 63 64 if zpool get health ${zpool} >/dev/null 2>&1; then 65 zpool destroy -f ${zpool} 66 fi 67} 68 69atf_test_case bectl_create cleanup 70bectl_create_head() 71{ 72 73 atf_set "descr" "Check the various forms of bectl create" 74 atf_set "require.user" root 75} 76bectl_create_body() 77{ 78 cwd=$(realpath .) 79 zpool=bectl_test 80 disk=${cwd}/disk.img 81 mount=${cwd}/mnt 82 83 bectl_create_setup ${zpool} ${disk} ${mount} 84 # Test standard creation, creation of a snapshot, and creation from a 85 # snapshot. 86 atf_check bectl -r ${zpool}/ROOT create -e default default2 87 atf_check bectl -r ${zpool}/ROOT create default2@test_snap 88 atf_check bectl -r ${zpool}/ROOT create -e default2@test_snap default3 89} 90bectl_create_cleanup() 91{ 92 93 bectl_cleanup bectl_test 94} 95 96atf_test_case bectl_destroy cleanup 97bectl_destroy_head() 98{ 99 100 atf_set "descr" "Check bectl destroy" 101 atf_set "require.user" root 102} 103bectl_destroy_body() 104{ 105 cwd=$(realpath .) 106 zpool=bectl_test 107 disk=${cwd}/disk.img 108 mount=${cwd}/mnt 109 110 bectl_create_setup ${zpool} ${disk} ${mount} 111 atf_check bectl -r ${zpool}/ROOT create -e default default2 112 atf_check -o not-empty zfs get mountpoint ${zpool}/ROOT/default2 113 atf_check bectl -r ${zpool}/ROOT destroy default2 114 atf_check -e not-empty -s not-exit:0 zfs get mountpoint ${zpool}/ROOT/default2 115} 116bectl_destroy_cleanup() 117{ 118 119 bectl_cleanup bectl_test 120} 121 122atf_test_case bectl_export_import cleanup 123bectl_export_import_head() 124{ 125 126 atf_set "descr" "Check bectl export and import" 127 atf_set "require.user" root 128} 129bectl_export_import_body() 130{ 131 cwd=$(realpath .) 132 zpool=bectl_test 133 disk=${cwd}/disk.img 134 mount=${cwd}/mnt 135 136 bectl_create_setup ${zpool} ${disk} ${mount} 137 atf_check -o save:exported bectl -r ${zpool}/ROOT export default 138 atf_check -x "bectl -r ${zpool}/ROOT import default2 < exported" 139 atf_check -o not-empty zfs get mountpoint ${zpool}/ROOT/default2 140 atf_check bectl -r ${zpool}/ROOT destroy default2 141 atf_check -e not-empty -s not-exit:0 zfs get mountpoint \ 142 ${zpool}/ROOT/default2 143} 144bectl_export_import_cleanup() 145{ 146 147 bectl_cleanup bectl_test 148} 149 150atf_test_case bectl_list cleanup 151bectl_list_head() 152{ 153 154 atf_set "descr" "Check bectl list" 155 atf_set "require.user" root 156} 157bectl_list_body() 158{ 159 cwd=$(realpath .) 160 zpool=bectl_test 161 disk=${cwd}/disk.img 162 mount=${cwd}/mnt 163 164 bectl_create_setup ${zpool} ${disk} ${mount} 165 # Test the list functionality, including that BEs come and go away 166 # as they're created and destroyed. Creation and destruction tests 167 # use the 'zfs' utility to verify that they're actually created, so 168 # these are just light tests that 'list' is picking them up. 169 atf_check -o save:list.out bectl -r ${zpool}/ROOT list 170 atf_check -o not-empty grep 'default' list.out 171 atf_check bectl -r ${zpool}/ROOT create -e default default2 172 atf_check -o save:list.out bectl -r ${zpool}/ROOT list 173 atf_check -o not-empty grep 'default2' list.out 174 atf_check bectl -r ${zpool}/ROOT destroy default2 175 atf_check -o save:list.out bectl -r ${zpool}/ROOT list 176 atf_check -s not-exit:0 grep 'default2' list.out 177 # XXX TODO: Formatting checks 178} 179bectl_list_cleanup() 180{ 181 182 bectl_cleanup bectl_test 183} 184 185atf_test_case bectl_mount cleanup 186bectl_mount_head() 187{ 188 189 atf_set "descr" "Check bectl mount/unmount" 190 atf_set "require.user" root 191} 192bectl_mount_body() 193{ 194 cwd=$(realpath .) 195 zpool=bectl_test 196 disk=${cwd}/disk.img 197 mount=${cwd}/mnt 198 root=${mount}/root 199 200 bectl_create_deep_setup ${zpool} ${disk} ${mount} 201 atf_check mkdir -p ${root} 202 # Test unmount first... 203 atf_check -o not-empty bectl -r ${zpool}/ROOT mount default ${root} 204 atf_check -o not-empty -x "mount | grep '^${zpool}/ROOT/default'" 205 atf_check bectl -r ${zpool}/ROOT unmount default 206 atf_check -s not-exit:0 -x "mount | grep '^${zpool}/ROOT/default'" 207 # Then umount! 208 atf_check -o not-empty bectl -r ${zpool}/ROOT mount default ${root} 209 atf_check -o not-empty -x "mount | grep '^${zpool}/ROOT/default'" 210 atf_check bectl -r ${zpool}/ROOT umount default 211 atf_check -s not-exit:0 -x "mount | grep '^${zpool}/ROOT/default'" 212} 213bectl_mount_cleanup() 214{ 215 216 bectl_cleanup bectl_test 217} 218 219atf_test_case bectl_rename cleanup 220bectl_rename_head() 221{ 222 223 atf_set "descr" "Check bectl rename" 224 atf_set "require.user" root 225} 226bectl_rename_body() 227{ 228 cwd=$(realpath .) 229 zpool=bectl_test 230 disk=${cwd}/disk.img 231 mount=${cwd}/mnt 232 233 bectl_create_setup ${zpool} ${disk} ${mount} 234 atf_check bectl -r ${zpool}/ROOT rename default default2 235 atf_check -o not-empty zfs get mountpoint ${zpool}/ROOT/default2 236 atf_check -e not-empty -s not-exit:0 zfs get mountpoint \ 237 ${zpool}/ROOT/default 238} 239bectl_rename_cleanup() 240{ 241 242 bectl_cleanup bectl_test 243} 244 245atf_test_case bectl_jail cleanup 246bectl_jail_head() 247{ 248 249 atf_set "descr" "Check bectl rename" 250 atf_set "require.user" root 251} 252bectl_jail_body() 253{ 254 cwd=$(realpath .) 255 zpool=bectl_test 256 disk=${cwd}/disk.img 257 mount=${cwd}/mnt 258 root=${mount}/root 259 260 if [ ! -f /rescue/rescue ]; then 261 atf_skip "This test requires a rescue binary" 262 fi 263 bectl_create_deep_setup ${zpool} ${disk} ${mount} 264 # Prepare our minimal BE... plop a rescue binary into it 265 atf_check mkdir -p ${root} 266 atf_check -o ignore bectl -r ${zpool}/ROOT mount default ${root} 267 atf_check mkdir -p ${root}/rescue 268 atf_check cp /rescue/rescue ${root}/rescue/rescue 269 atf_check bectl -r ${zpool}/ROOT umount default 270 271 # Prepare a second boot environment 272 atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT create -e default target 273 274 # When a jail name is not explicit, it should match the jail id. 275 atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b -o jid=233637 default 276 atf_check -o inline:"233637\n" -s exit:0 -x "jls -j 233637 name" 277 atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail default 278 279 # Basic command-mode tests, with and without jail cleanup 280 atf_check -o inline:"rescue\nusr\n" bectl -r ${zpool}/ROOT \ 281 jail default /rescue/rescue ls -1 282 atf_check -o inline:"rescue\nusr\n" bectl -r ${zpool}/ROOT \ 283 jail -Uo path=${root} default /rescue/rescue ls -1 284 atf_check [ -f ${root}/rescue/rescue ] 285 atf_check bectl -r ${zpool}/ROOT ujail default 286 287 # Batch mode tests 288 atf_check bectl -r ${zpool}/ROOT jail -bo path=${root} default 289 atf_check -o not-empty -x "jls | grep -F \"${root}\"" 290 atf_check bectl -r ${zpool}/ROOT ujail default 291 atf_check -s not-exit:0 -x "jls | grep -F \"${root}\"" 292 # 'unjail' naming 293 atf_check bectl -r ${zpool}/ROOT jail -b default 294 atf_check bectl -r ${zpool}/ROOT unjail default 295 atf_check -s not-exit:0 -x "jls | grep -F \"${root}\"" 296 # 'unjail' by BE name. Force bectl to lookup jail id by the BE name. 297 atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b default 298 atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT jail -b -o name=bectl_test target 299 atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail target 300 atf_check -o empty -s exit:0 bectl -r ${zpool}/ROOT unjail default 301 # cannot unjail an unjailed BE (by either command name) 302 atf_check -e ignore -s not-exit:0 bectl -r ${zpool}/ROOT ujail default 303 atf_check -e ignore -s not-exit:0 bectl -r ${zpool}/ROOT unjail default 304 305 # set+unset 306 atf_check bectl -r ${zpool}/ROOT jail -b -o path=${root} -u path default 307 # Ensure that it didn't mount at ${root} 308 atf_check -s not-exit:0 -x "mount | grep -F '${root}'" 309 atf_check bectl -r ${zpool}/ROOT ujail default 310} 311 312# If a test has failed, it's possible that the boot environment hasn't 313# been 'unjail'ed. We want to remove the jail before 'bectl_cleanup' 314# attempts to destroy the zpool. 315bectl_jail_cleanup() 316{ 317 for bootenv in "default" "target"; do 318 # mountpoint of the boot environment 319 mountpoint="$(bectl -r bectl_test/ROOT list -H | grep ${bootenv} | awk '{print $3}')" 320 321 # see if any jail paths match the boot environment mountpoint 322 jailid="$(jls | grep ${mountpoint} | awk '{print $1}')" 323 324 if [ -z "$jailid" ]; then 325 continue; 326 fi 327 jail -r ${jailid} 328 done; 329 330 bectl_cleanup bectl_test 331} 332 333atf_init_test_cases() 334{ 335 atf_add_test_case bectl_create 336 atf_add_test_case bectl_destroy 337 atf_add_test_case bectl_export_import 338 atf_add_test_case bectl_list 339 atf_add_test_case bectl_mount 340 atf_add_test_case bectl_rename 341 atf_add_test_case bectl_jail 342} 343