xref: /freebsd/usr.sbin/quot/tests/quot_test.sh (revision aa870a1935bccb66e02c4c31630706768a3e7d74)
1*aa870a19SDag-Erling Smørgrav#
2*aa870a19SDag-Erling Smørgrav# Copyright (c) 2025 Dag-Erling Smørgrav <des@FreeBSD.org>
3*aa870a19SDag-Erling Smørgrav#
4*aa870a19SDag-Erling Smørgrav# SPDX-License-Identifier: BSD-2-Clause
5*aa870a19SDag-Erling Smørgrav#
6*aa870a19SDag-Erling Smørgrav
7*aa870a19SDag-Erling Smørgrav# Create and mount a UFS filesystem on a small memory disk
8*aa870a19SDag-Erling Smørgravquot_setup()
9*aa870a19SDag-Erling Smørgrav{
10*aa870a19SDag-Erling Smørgrav	atf_check -o save:dev mdconfig -t malloc -s 16M
11*aa870a19SDag-Erling Smørgrav	local dev=$(cat dev)
12*aa870a19SDag-Erling Smørgrav	atf_check -o ignore newfs "$@" /dev/$dev
13*aa870a19SDag-Erling Smørgrav	atf_check mkdir mnt
14*aa870a19SDag-Erling Smørgrav	local mnt=$(realpath mnt)
15*aa870a19SDag-Erling Smørgrav	atf_check mount /dev/$dev "$mnt"
16*aa870a19SDag-Erling Smørgrav	echo "/dev/$dev: ($mnt)" >expect
17*aa870a19SDag-Erling Smørgrav	printf "%5d\t%5d\t%-8s\n" 8 2 "#0" >>expect
18*aa870a19SDag-Erling Smørgrav}
19*aa870a19SDag-Erling Smørgrav
20*aa870a19SDag-Erling Smørgrav# Create a directory owned by a given UID
21*aa870a19SDag-Erling Smørgravquot_adduid()
22*aa870a19SDag-Erling Smørgrav{
23*aa870a19SDag-Erling Smørgrav	local uid=$1
24*aa870a19SDag-Erling Smørgrav	atf_check install -d -o $uid -g 0 mnt/$uid
25*aa870a19SDag-Erling Smørgrav	printf "%5d\t%5d\t%-8s\n" 4 1 "#$uid" >>expect
26*aa870a19SDag-Erling Smørgrav}
27*aa870a19SDag-Erling Smørgrav
28*aa870a19SDag-Erling Smørgrav# Perform the tests
29*aa870a19SDag-Erling Smørgravquot_test()
30*aa870a19SDag-Erling Smørgrav{
31*aa870a19SDag-Erling Smørgrav	local dev=$(cat dev)
32*aa870a19SDag-Erling Smørgrav	# Create inodes owned by a large number of users to exercise
33*aa870a19SDag-Erling Smørgrav	# hash collisions and rehashing.  The code uses an open hash
34*aa870a19SDag-Erling Smørgrav	# table that starts out with only 8 entries and doubles every
35*aa870a19SDag-Erling Smørgrav	# time it fills up.
36*aa870a19SDag-Erling Smørgrav	local uid
37*aa870a19SDag-Erling Smørgrav	for uid in $(seq 1 32); do
38*aa870a19SDag-Erling Smørgrav		quot_adduid $uid
39*aa870a19SDag-Erling Smørgrav	done
40*aa870a19SDag-Erling Smørgrav	# Also create inodes owned by users with long UIDs, up to the
41*aa870a19SDag-Erling Smørgrav	# highest possible value (2^32 - 2, because chown(2) and
42*aa870a19SDag-Erling Smørgrav	# friends interpret 2^32 - 1 as “leave unchanged”).
43*aa870a19SDag-Erling Smørgrav	local shift
44*aa870a19SDag-Erling Smørgrav	for shift in $(seq 6 32); do
45*aa870a19SDag-Erling Smørgrav		quot_adduid $(((1 << shift) - 2))
46*aa870a19SDag-Erling Smørgrav	done
47*aa870a19SDag-Erling Smørgrav	# Since quot operates directly on the underlying device, not
48*aa870a19SDag-Erling Smørgrav	# on the mounted filesystem, we remount read-only to ensure
49*aa870a19SDag-Erling Smørgrav	# that everything gets flushed to the memory disk.
50*aa870a19SDag-Erling Smørgrav	atf_check mount -ur /dev/$dev
51*aa870a19SDag-Erling Smørgrav	atf_check -o file:expect quot -fkN /dev/$dev
52*aa870a19SDag-Erling Smørgrav	atf_check -o file:expect quot -fkN $(realpath mnt)
53*aa870a19SDag-Erling Smørgrav}
54*aa870a19SDag-Erling Smørgrav
55*aa870a19SDag-Erling Smørgrav# Unmount and release the memory disk
56*aa870a19SDag-Erling Smørgravquot_cleanup()
57*aa870a19SDag-Erling Smørgrav{
58*aa870a19SDag-Erling Smørgrav	if [ -d mnt ]; then
59*aa870a19SDag-Erling Smørgrav		umount mnt || true
60*aa870a19SDag-Erling Smørgrav	fi
61*aa870a19SDag-Erling Smørgrav	if [ -f dev ]; then
62*aa870a19SDag-Erling Smørgrav		mdconfig -d -u $(cat dev) || true
63*aa870a19SDag-Erling Smørgrav	fi
64*aa870a19SDag-Erling Smørgrav}
65*aa870a19SDag-Erling Smørgrav
66*aa870a19SDag-Erling Smørgravatf_test_case ufs1 cleanup
67*aa870a19SDag-Erling Smørgravufs1_head()
68*aa870a19SDag-Erling Smørgrav{
69*aa870a19SDag-Erling Smørgrav	atf_set descr "Test quot on UFS1"
70*aa870a19SDag-Erling Smørgrav	atf_set require.user root
71*aa870a19SDag-Erling Smørgrav}
72*aa870a19SDag-Erling Smørgravufs1_body()
73*aa870a19SDag-Erling Smørgrav{
74*aa870a19SDag-Erling Smørgrav	quot_setup -O1
75*aa870a19SDag-Erling Smørgrav	quot_test
76*aa870a19SDag-Erling Smørgrav}
77*aa870a19SDag-Erling Smørgravufs1_cleanup()
78*aa870a19SDag-Erling Smørgrav{
79*aa870a19SDag-Erling Smørgrav	quot_cleanup
80*aa870a19SDag-Erling Smørgrav}
81*aa870a19SDag-Erling Smørgrav
82*aa870a19SDag-Erling Smørgravatf_test_case ufs2 cleanup
83*aa870a19SDag-Erling Smørgravufs2_head()
84*aa870a19SDag-Erling Smørgrav{
85*aa870a19SDag-Erling Smørgrav	atf_set descr "Test quot on UFS2"
86*aa870a19SDag-Erling Smørgrav	atf_set require.user root
87*aa870a19SDag-Erling Smørgrav}
88*aa870a19SDag-Erling Smørgravufs2_body()
89*aa870a19SDag-Erling Smørgrav{
90*aa870a19SDag-Erling Smørgrav	quot_setup -O2
91*aa870a19SDag-Erling Smørgrav	quot_test
92*aa870a19SDag-Erling Smørgrav}
93*aa870a19SDag-Erling Smørgravufs2_cleanup()
94*aa870a19SDag-Erling Smørgrav{
95*aa870a19SDag-Erling Smørgrav	quot_cleanup
96*aa870a19SDag-Erling Smørgrav}
97*aa870a19SDag-Erling Smørgrav
98*aa870a19SDag-Erling Smørgravatf_init_test_cases()
99*aa870a19SDag-Erling Smørgrav{
100*aa870a19SDag-Erling Smørgrav	atf_add_test_case ufs1
101*aa870a19SDag-Erling Smørgrav	atf_add_test_case ufs2
102*aa870a19SDag-Erling Smørgrav}
103