Add tests for gunion(8)

Reviewed by:	mckusick (earlier version)
MFC after:	3 days
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D41645
This commit is contained in:
Yan-Hao Wang 2023-11-16 15:58:49 +08:00 committed by Li-Wen Hsu
parent 3aebcb9ecb
commit 55141f2c89
No known key found for this signature in database
GPG key ID: 82B261B14D3BC7AF
5 changed files with 390 additions and 0 deletions

View file

@ -795,6 +795,8 @@
..
stripe
..
union
..
uzip
etalon
..

View file

@ -17,6 +17,7 @@ TESTS_SUBDIRS+= part
TESTS_SUBDIRS+= raid3
TESTS_SUBDIRS+= shsec
TESTS_SUBDIRS+= stripe
TESTS_SUBDIRS+= union
TESTS_SUBDIRS+= uzip
${PACKAGE}FILES+= geom_subr.sh

View file

@ -0,0 +1,9 @@
PACKAGE= tests
TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
ATF_TESTS_SH+= union_test
${PACKAGE}FILES+= conf.sh
.include <bsd.test.mk>

View file

@ -0,0 +1,40 @@
#!/bin/sh
class="union"
base=$(atf_get ident)
attach_md()
{
local test_md
test_md=$(mdconfig -a "$@") || atf_fail "failed to allocate md(4)"
echo $test_md >> $TEST_MDS_FILE || exit
echo $test_md
}
gunion_test_cleanup()
{
if mount | grep -q "/gunionmnt"; then
umount gunionmnt
fi
if mount | grep -q "/uppermnt"; then
umount uppermnt
fi
if mount | grep -q "/lowermnt"; then
umount lowermnt
fi
if [ -e "guniondev" ]; then
gunion destroy "$(cat guniondev)"
fi
geom_test_cleanup
}
gunion_test_setup()
{
geom_atf_test_setup
}
ATF_TEST=true
. `dirname $0`/../geom_subr.sh

View file

@ -0,0 +1,338 @@
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2023 The FreeBSD Foundation
#
# This software was developed1 by Yan-Hao Wang <bses30074@gmail.com>
# under sponsorship from the FreeBSD Foundation.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
. $(atf_get_srcdir)/conf.sh
atf_test_case create cleanup
create_head()
{
atf_set "descr" "Test gunion create and destroy"
atf_set "require.user" "root"
}
create_body()
{
gunion_test_setup
upperdev="$(attach_md -s 1m)"
lowerdev="$(attach_md -s 1m)"
newfs -U "/dev/${lowerdev}"
atf_check gunion create "$upperdev" "$lowerdev"
guniondev="${upperdev}-${lowerdev}.union"
atf_check -o inline:"/dev/${guniondev}\n" ls "/dev/${guniondev}"
atf_check -o ignore fsck -p -f "/dev/${guniondev}"
atf_check gunion destroy "$guniondev"
atf_check -s not-exit:0 -o ignore -e ignore ls "/dev/${guniondev}"
}
create_cleanup()
{
gunion_test_cleanup
}
atf_test_case basic cleanup
basic_head()
{
atf_set "descr" "Check gunion doesn't affect lowerdev status and lowerdev can't be mounted when being in a gunion"
atf_set "require.user" "root"
}
basic_body()
{
gunion_test_setup
upperdev="$(attach_md -s 1m)"
lowerdev="$(attach_md -s 1m)"
newfs -U "/dev/${lowerdev}"
mkdir lowermnt
mkdir gunionmnt
mount "/dev/${lowerdev}" lowermnt
echo "lower file" > lower_file
cp lower_file lowermnt/lower_file
sync
umount lowermnt
gunion create "$upperdev" "$lowerdev"
guniondev="${upperdev}-${lowerdev}.union"
atf_check -s not-exit:0 -o ignore -e ignore mount "/dev/${lowerdev}" lowermnt
mount "/dev/${guniondev}" gunionmnt
echo "update lower file" >> gunionmnt/lower_file
echo "gunion file" > gunion_file
cp gunion_file gunionmnt/gunion_file
sync
umount gunionmnt
gunion destroy "$guniondev"
mount "/dev/${lowerdev}" lowermnt
checksum lowermnt/lower_file lower_file
atf_check -s not-exit:0 -o ignore -e ignore ls lowermnt/gunion_file
}
basic_cleanup()
{
gunion_test_cleanup
}
atf_test_case commit cleanup
commit_head()
{
atf_set "descr" "Test basic gunion commit without option"
atf_set "require.user" "root"
}
commit_body()
{
gunion_test_setup
upperdev="$(attach_md -s 1m)"
lowerdev="$(attach_md -s 1m)"
newfs -U "/dev/${lowerdev}"
mkdir lowermnt
mkdir gunionmnt
mount "/dev/${lowerdev}" lowermnt
echo "lower file" > lower_file
cp lower_file lowermnt/lower_file
sync
umount lowermnt
gunion create "$upperdev" "$lowerdev"
guniondev="${upperdev}-${lowerdev}.union"
mount "/dev/${guniondev}" gunionmnt
checksum gunionmnt/lower_file lower_file
echo "update lower file" >> lower_file
cp -f lower_file gunionmnt/lower_file
echo "gunion file" > gunion_file
cp gunion_file gunionmnt/gunion_file
sync
umount gunionmnt
atf_check gunion commit "$guniondev"
gunion destroy "$guniondev"
atf_check -o ignore fsck -p -f "/dev/${lowerdev}"
mount "/dev/${lowerdev}" lowermnt
checksum lowermnt/lower_file lower_file
checksum lowermnt/gunion_file gunion_file
}
commit_cleanup()
{
gunion_test_cleanup
}
atf_test_case offset cleanup
offset_head()
{
atf_set "descr" "Test gunion create with -o offset option"
atf_set "require.user" "root"
}
offset_body()
{
gunion_test_setup
upperdev="$(attach_md -s 1m)"
lowerdev="$(attach_md -s 1m)"
gpart create -s GPT "/dev/${lowerdev}"
gpart add -t freebsd-ufs "$lowerdev"
newfs "/dev/${lowerdev}p1"
gpt_entry_1=$(gpart show "/dev/${lowerdev}")
mkdir gunionmnt
secsize="$(diskinfo "/dev/${lowerdev}" | awk '{print $2}')"
p1_start_sector="$(gpart show -p "/dev/${lowerdev}" | grep ${lowerdev}p1 | awk '{print $1}')"
offset_size="$((secsize * p1_start_sector))"
gunion create -o "$offset_size" "$upperdev" "$lowerdev"
guniondev="${upperdev}-${lowerdev}.union"
atf_check -o ignore fsck -p -f "/dev/${guniondev}"
atf_check mount "/dev/${guniondev}" gunionmnt
umount gunionmnt
gunion destroy "$guniondev"
gpt_entry_2=$(gpart show "/dev/${lowerdev}")
atf_check_equal "$gpt_entry_1" "$gpt_entry_2"
}
offset_cleanup()
{
gunion_test_cleanup
}
atf_test_case size cleanup
size_head()
{
atf_set "descr" "Test gunion create with -s size option"
atf_set "require.user" "root"
}
size_body()
{
gunion_test_setup
upperdev="$(attach_md -s 2m)"
lowerdev="$(attach_md -s 1m)"
newfs -U "/dev/${lowerdev}"
gunion create -s 2m "$upperdev" "$lowerdev"
guniondev="${upperdev}-${lowerdev}.union"
echo "$guniondev" > guniondev
size="$(diskinfo "/dev/$guniondev" | awk '{print $3}')"
atf_check_equal "2097152" "$size" # 2 MB = 2097152 bytes
}
size_cleanup()
{
gunion_test_cleanup
}
atf_test_case secsize cleanup
secsize_head()
{
atf_set "descr" "Test gunion create with -S secsize option"
atf_set "require.user" "root"
}
secsize_body()
{
gunion_test_setup
upperdev="$(attach_md -s 1m)"
lowerdev="$(attach_md -s 1m)"
newfs -S 512 -U "/dev/${lowerdev}"
lower_secsize="$(diskinfo "/dev/${lowerdev}" | awk '{print $2}')"
atf_check_equal "512" "$lower_secsize"
gunion create -S 1024 "$upperdev" "$lowerdev"
guniondev="${upperdev}-${lowerdev}.union"
echo "$guniondev" > guniondev
secsize="$(diskinfo "/dev/${guniondev}" | awk '{print $2}')"
atf_check_equal "1024" "$secsize"
}
secsize_cleanup()
{
gunion_test_cleanup
}
atf_test_case gunionname cleanup
gunionname_head()
{
atf_set "descr" "Test gunion create with -Z gunionname option"
atf_set "require.user" "root"
}
gunionname_body()
{
gunion_test_setup
upperdev="$(attach_md -s 1m)"
lowerdev="$(attach_md -s 1m)"
newfs -U "/dev/${lowerdev}"
gunion create -Z gunion1 "$upperdev" "$lowerdev"
echo "gunion1.union" > guniondev
atf_check -o inline:"/dev/gunion1.union\n" ls /dev/gunion1.union
}
gunionname_cleanup()
{
gunion_test_cleanup
}
atf_test_case revert cleanup
revert_head()
{
atf_set "descr" "Test gunion revert"
atf_set "require.user" "root"
}
revert_body()
{
gunion_test_setup
upperdev="$(attach_md -s 1m)"
lowerdev="$(attach_md -s 1m)"
newfs -U "/dev/${lowerdev}"
mkdir lowermnt
mkdir gunionmnt
mount "/dev/${lowerdev}" lowermnt
echo "lower file" > lower_file
cp lower_file lowermnt/lower_file
sync
umount lowermnt
atf_check gunion create "$upperdev" "$lowerdev"
guniondev="${upperdev}-${lowerdev}.union"
mount "/dev/${guniondev}" gunionmnt
echo "update lower file" >> gunionmnt/lower_file
echo "gunion file" > gunion_file
cp gunion_file gunionmnt/gunion_file
sync
umount gunionmnt
atf_check gunion revert "$guniondev"
mount "/dev/${guniondev}" gunionmnt
checksum gunionmnt/lower_file lower_file
atf_check -s not-exit:0 -o ignore -e ignore ls gunionmnt/gunion_file
umount gunionmnt
gunion destroy "$guniondev"
}
revert_cleanup()
{
gunion_test_cleanup
}
atf_init_test_cases()
{
atf_add_test_case create
atf_add_test_case basic
atf_add_test_case commit
atf_add_test_case offset
atf_add_test_case size
atf_add_test_case secsize
atf_add_test_case gunionname
atf_add_test_case revert
}
checksum()
{
src=$1
work=$2
if [ ! -e "$src" ]; then
atf_fail "file not exist"
fi
if [ ! -e "$work" ]; then
atf_fail "file not exist"
fi
src_checksum=$(md5 -q "$src")
work_checksum=$(md5 -q "$work")
if [ "$work_checksum" != "$src_checksum" ]; then
atf_fail "md5 checksum didn't match with ${src} and ${work}"
fi
}