1#!/bin/sh 2#- 3# SPDX-License-Identifier: BSD-2-Clause 4# 5# Copyright (c) 2025 Klara, Inc. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28 29# Create and mount a filesystem for use in our tests 30unionfs_mkfs() { 31 local name=$1 32 local size=${2:-1} 33 # Create mountpoint 34 atf_check mkdir ${name} 35 # Create filesystem image 36 atf_check -e ignore dd if=/dev/zero of=${name}.img bs=1m count=${size} 37 echo ${name} >>imgs 38 # Create memory disk 39 atf_check -o save:${name}.md mdconfig ${name}.img 40 md=$(cat ${name}.md) 41 echo ${md} >>mds 42 # Format and mount filesystem 43 atf_check -o ignore newfs /dev/${md} 44 atf_check mount /dev/${md} ${name} 45 echo ${name} >>mounts 46} 47 48# Mount a unionfs 49unionfs_mount() { 50 local upper=$1 51 local lower=$2 52 # Mount upper over lower 53 atf_check mount -t unionfs ${upper} ${lower} 54 echo ${lower} >>mounts 55} 56 57# Clean up after a test 58unionfs_cleanup() { 59 # Unmount filesystems 60 if [ -f mounts ]; then 61 tail -r mounts | while read mount; do 62 umount ${mount} || true 63 done 64 fi 65 # Destroy memory disks 66 if [ -f mds ]; then 67 tail -r mds | while read md; do 68 mdconfig -d -u ${md} || true 69 done 70 fi 71 # Delete filesystem images and mountpoints 72 if [ -f imgs ]; then 73 tail -r imgs | while read name; do 74 rm -f ${name}.img || true 75 rmdir ${name} || true 76 done 77 fi 78} 79 80atf_test_case unionfs_basic cleanup 81unionfs_basic_head() { 82 atf_set "descr" "Basic function test" 83 atf_set "require.user" "root" 84 atf_set "require.kmods" "unionfs" 85} 86unionfs_basic_body() { 87 # Create upper and lower 88 unionfs_mkfs upper 89 unionfs_mkfs lower 90 # Mount upper over lower 91 unionfs_mount upper lower 92 # Create object on unionfs 93 atf_check touch upper/file 94 atf_check mkdir upper/dir 95 atf_check touch lower/dir/file 96 # Verify that objects were created on upper 97 atf_check test -f lower/file 98 atf_check test -d lower/dir 99 atf_check test -f upper/dir/file 100} 101unionfs_basic_cleanup() { 102 unionfs_cleanup 103} 104 105atf_test_case unionfs_exec cleanup 106unionfs_exec_head() { 107 atf_set "descr" "Test executing programs" 108 atf_set "require.user" "root" 109 atf_set "require.kmods" "unionfs" 110} 111unionfs_exec_body() { 112 # Create upper and copy a binary to it 113 unionfs_mkfs upper 114 atf_check cp -p /usr/bin/true upper/upper 115 # Create lower and copy a binary to it 116 unionfs_mkfs lower 117 atf_check cp -p /usr/bin/true lower/lower 118 # Mount upper over lower 119 unionfs_mount upper lower 120 # Execute both binaries 121 atf_check lower/lower 122 atf_check lower/upper 123} 124unionfs_exec_cleanup() { 125 unionfs_cleanup 126} 127 128atf_test_case unionfs_rename cleanup 129unionfs_rename_head() { 130 atf_set "descr" "Test renaming objects on lower" 131 atf_set "require.user" "root" 132 atf_set "require.kmods" "unionfs" 133} 134unionfs_rename_body() { 135 # Create upper and lower 136 unionfs_mkfs upper 137 unionfs_mkfs lower 138 # Create objects on lower 139 atf_check touch lower/file 140 atf_check mkdir lower/dir 141 atf_check ln -s dead lower/link 142 # Mount upper over lower 143 unionfs_mount upper lower 144 # Rename objects 145 atf_check mv lower/file lower/newfile 146 atf_check mv lower/dir lower/newdir 147 atf_check mv lower/link lower/newlink 148 # Verify that old names no longer exist 149 atf_check test ! -f lower/file 150 atf_check test ! -d lower/dir 151 atf_check test ! -L lower/link 152 # Verify that new names exist on upper 153 atf_check test -f upper/newfile 154 atf_check test -d upper/newdir 155 atf_check test -L upper/newlink 156} 157unionfs_rename_cleanup() { 158 unionfs_cleanup 159} 160 161atf_init_test_cases() { 162 atf_add_test_case unionfs_basic 163 atf_add_test_case unionfs_exec 164 atf_add_test_case unionfs_rename 165} 166