diff mbox series

[v2] xfs: test xfs_quota's 'dump' and 'report' -L/-R range parameters

Message ID 20220802130554.117320-1-aalbersh@redhat.com (mailing list archive)
State New, archived
Headers show
Series [v2] xfs: test xfs_quota's 'dump' and 'report' -L/-R range parameters | expand

Commit Message

Andrey Albershteyn Aug. 2, 2022, 1:05 p.m. UTC
These parameters define ID range of users/groups/projects to show.
This test adds more checks for wider coverage (e.g. empty range,
full range, open range).

Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
---

This is regression test in relation to the patch [1].

Changes from v1:
 - Moved to separate test (initially added to 152)

[1]: https://lore.kernel.org/all/20220328222503.146496-1-aalbersh@redhat.com/

---

 common/filter     |   5 +
 tests/xfs/550     | 163 ++++++++++++++++++++++++++++++++
 tests/xfs/550.out | 232 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 400 insertions(+)
 create mode 100755 tests/xfs/550
 create mode 100644 tests/xfs/550.out

Comments

Dave Chinner Aug. 2, 2022, 11:12 p.m. UTC | #1
On Tue, Aug 02, 2022 at 03:05:55PM +0200, Andrey Albershteyn wrote:
> These parameters define ID range of users/groups/projects to show.
> This test adds more checks for wider coverage (e.g. empty range,
> full range, open range).
> 
> Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
> ---
> 
> This is regression test in relation to the patch [1].
> 
> Changes from v1:
>  - Moved to separate test (initially added to 152)
> 
> [1]: https://lore.kernel.org/all/20220328222503.146496-1-aalbersh@redhat.com/
....
> +filter_dump()
> +{
> +	_filter_scratch| _filter_trailing_spaces | \
> +		sed -E '/^[0-9]+/s/^[0-9]+/#ID/g'
> +}

Some sed hints. This looks like you are converting a line like:

"123 xyz 456 abc     "

to

"#ID xyz 456 abc"

In this situation, you don't need a line filter regex for sed to do
the right thing - it's redundant because the search regex will pull
exactly the same line into the pattern space as the line filter
would that the regex then acts upon. Hence the sed expression can be
simplified to:

sed -E 's/^[0-9]+/#ID/g'


Then because the regex is matching the start of the line, there
cannot more than one match per line. Hence the "g" suffix that tells
sed to continue searching the pattern space after the first match
has been found is not necessary. Now we have:

sed -E 's/^[0-9]+/#ID/'

And then if we look at _filter_trailing_spaces() we see it's just
another simple sed expression. But sed has this annoying CLI issue
where if you use extended regexes (-E ...) then you can only specify
one regex to apply to the pattern space. This makes matching the
start and end of the line a bit messy and error prone. e.g:

sed -E 's/^[0-9]+(\s+.*[[:alnum:]])\s*$/#ID\1/'

Will match the ID at the start, store the bit in the middle that we
want to retain in a register by assuming it ends with a number or
letter then whitespace, then matches the whitespace at the end of
the line. It then outputs #ID followed by the contents of register
1, thereby stripping the whitespace at the end of the line.

It's a complex regex, hard to read, and quite fragile.

But if we drop the extended regexes, we can now chain multiple
simple regexes together to be applied sequentially to the pattern
space line via multiple CLI "-e" expressions. So the sed command
becomes:

_filter_scratch | sed -e 's/^[0-9]\+/#ID/' -e 's/\s*$//'

Which is much easier to understand, and does all the work in a
single sed invocation.

> +
> +filter_report()
> +{
> +	_filter_quota | _filter_trailing_spaces | grep -v "^root \|^\#0 " \
> +		| sed -e '/^#[0-9]*/s/^#[0-9]*/#ID/g'
> +}

And the same here - this removes lines starting with root or #0 from
the output with grep, then replaces the initial ID with #ID via sed.
This can all be done with a single sed invocation, and this time we
use line matching regexes to delete the pattern space before
applying the substution regexes which then don't match anything
because the pattern space is empty for the lines we want to delete
from the output:

	_filter_quota | sed -e '/^root/d' \
				-e '/^#0/d' \
				-e 's/^[0-9]\+/#ID/' \
				-e 's/\s*$//'


> +set_quota_limit()
> +{
> +	local bs=$1
> +	local bh=$2
> +	local is=$3
> +	local ih=$4
> +	local user=$5
> +
> +	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> +			-c "limit -$type bsoft=$bs bhard=$bh $user" \
> +			-c "limit -$type isoft=$is ihard=$ih $user" \
> +			$SCRATCH_MNT
> +}
> +
> +test_dump()
> +{
> +	local opt="$*"
> +
> +	rm -f $tmp.backup 2>>/dev/null
> +	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> +			-c "dump -$type $opt -f $tmp.backup" \
> +			$SCRATCH_MNT | _filter_scratch
> +	cat $tmp.backup | filter_dump
> +}
> +
> +test_report()
> +{
> +	local opt="$*"
> +
> +	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
> +			-c "report -$type $opt -bi" \
> +			$SCRATCH_MNT | filter_report
> +}
> +
> +test_xfs_quota()
> +{
> +	set_quota_limit 512k 2048k 10 20 $id
> +	set_quota_limit 1024k 4096k 10 20 $id2
> +
> +	echo "dump options test (type=$type)"
> +	echo "no options (full range)"; test_dump
> +	echo "-L option"; test_dump -L $id
> +	echo "-U option"; test_dump -U $id
> +	echo "-L/-U options (one element range)"; test_dump -L $id -U $id
> +	echo "-L/-U options (multiple elements range)"; test_dump -L $id -U $id2
> +	echo "-L/-U options (empty range)"; test_dump -L $id2 -U $id
> +	echo "-L/-U options (full range)"; test_dump -L 0 -U 0

While compact, this is difficult to read. Can you separate the echo
command from the actual test that is run? i.e.

	echo "dump options test (type=$type)"
	echo "no options (full range)";
	test_dump

	echo "-L option"
	test_dump -L $id

	echo "-U option"
	test_dump -U $id

Another option, which is also compact, is to call the test function
like so:

	test_dump "no options"
	test_dump "-L option" -L $id
	test_dump "-U option" -U $id
	.....

And capture the test description like so:

test_dump()
{
	local description=$1 ; shift
	local opt="$*"

	echo "Options: $description"

	....
}

Cheers,

Dave.
diff mbox series

Patch

diff --git a/common/filter b/common/filter
index 28dea646..5abe884a 100644
--- a/common/filter
+++ b/common/filter
@@ -278,6 +278,11 @@  _filter_spaces()
 	sed -e "s/\s\+/ /g"
 }
 
+_filter_trailing_spaces()
+{
+	sed -e "s/\s*$//g"
+}
+
 _filter_quota()
 {
 	# Long dev name might be split onto its own line; last
diff --git a/tests/xfs/550 b/tests/xfs/550
new file mode 100755
index 00000000..a420b1fd
--- /dev/null
+++ b/tests/xfs/550
@@ -0,0 +1,163 @@ 
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022 Andrey Albershteyn <aalbersh@redhat.com>.
+# All Rights Reserved.
+#
+# FS QA Test 550
+#
+# Test xfs_quota -L/-U range parameters for report and dump commands. These
+# parameters define ID range of users/groups/projects with non-zero quota to
+# show.
+#
+. ./common/preamble
+_begin_fstest quick quota
+
+# Override the default cleanup function.
+_cleanup()
+{
+	_scratch_unmount >/dev/null 2>&1
+	cd /
+	rm -f $tmp.*
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/quota
+
+# real QA test starts here
+_supported_fs xfs
+_require_test
+_require_scratch
+_require_xfs_quota
+_require_user fsgqa
+_require_user fsgqa2
+_require_group fsgqa
+_require_group fsgqa2
+
+_scratch_mkfs_xfs >>$seqres.full || _fail "mkfs failed"
+
+uqid=`id -u fsgqa`
+gqid=`id -g fsgqa`
+
+uqid2=`id -u fsgqa2`
+gqid2=`id -g fsgqa2`
+
+[ $uqid -ge $uqid2 ] && _notrun \
+	"ID of fsgqa user ($uqid) expected to be lower than fsgqa2 ($uqid2)"
+[ $gqid -ge $gqid2 ] && _notrun \
+	"ID of fsgqa group ($gqid) expected to be lower than fsgqa2 ($gqid2)"
+
+pqid=10
+pqid2=42
+cat >$tmp.projects <<EOF
+$pqid:$SCRATCH_MNT
+$pqid2:$SCRATCH_MNT
+EOF
+
+cat >$tmp.projid <<EOF
+root:0
+fsgqa:$pqid
+fsgqa2:$pqid2
+EOF
+
+filter_dump()
+{
+	_filter_scratch| _filter_trailing_spaces | \
+		sed -E '/^[0-9]+/s/^[0-9]+/#ID/g'
+}
+
+filter_report()
+{
+	_filter_quota | _filter_trailing_spaces | grep -v "^root \|^\#0 " \
+		| sed -e '/^#[0-9]*/s/^#[0-9]*/#ID/g'
+}
+
+set_quota_limit()
+{
+	local bs=$1
+	local bh=$2
+	local is=$3
+	local ih=$4
+	local user=$5
+
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "limit -$type bsoft=$bs bhard=$bh $user" \
+			-c "limit -$type isoft=$is ihard=$ih $user" \
+			$SCRATCH_MNT
+}
+
+test_dump()
+{
+	local opt="$*"
+
+	rm -f $tmp.backup 2>>/dev/null
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "dump -$type $opt -f $tmp.backup" \
+			$SCRATCH_MNT | _filter_scratch
+	cat $tmp.backup | filter_dump
+}
+
+test_report()
+{
+	local opt="$*"
+
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "report -$type $opt -bi" \
+			$SCRATCH_MNT | filter_report
+}
+
+test_xfs_quota()
+{
+	set_quota_limit 512k 2048k 10 20 $id
+	set_quota_limit 1024k 4096k 10 20 $id2
+
+	echo "dump options test (type=$type)"
+	echo "no options (full range)"; test_dump
+	echo "-L option"; test_dump -L $id
+	echo "-U option"; test_dump -U $id
+	echo "-L/-U options (one element range)"; test_dump -L $id -U $id
+	echo "-L/-U options (multiple elements range)"; test_dump -L $id -U $id2
+	echo "-L/-U options (empty range)"; test_dump -L $id2 -U $id
+	echo "-L/-U options (full range)"; test_dump -L 0 -U 0
+
+	echo "report options test (type=$type)"
+	echo "no options (full range)"; test_report
+	echo "-L options"; test_report -L $id
+	echo "-U options"; test_report -U $id
+	echo "-L/-U options (one element range)"; test_report -L $id -U $id
+	echo "-L/-U options (multiple elements range)"; test_report -L $id \
+		-U $id2
+	echo "-L/-U options (empty range)"; test_report -L $id2 -U $id
+	echo "-L/-U options (full range)"; test_report -L 0 -U 0
+}
+
+echo "Checking User quota"
+_scratch_unmount >/dev/null 2>&1
+_qmount_option "uquota"
+_try_scratch_mount || _fail "qmount failed"
+type=u
+id=$uqid
+id2=$uqid2
+test_xfs_quota
+
+echo "Checking Group quota"
+_scratch_unmount >/dev/null 2>&1
+_qmount_option "gquota"
+_try_scratch_mount || _fail "qmount failed"
+type=g
+id=$gqid
+id2=$gqid2
+test_xfs_quota
+
+echo "Checking Project quota"
+_scratch_unmount >/dev/null 2>&1
+_qmount_option "pquota"
+_try_scratch_mount || _fail "qmount failed"
+type=p
+id=$pqid
+id2=$pqid2
+test_xfs_quota
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/550.out b/tests/xfs/550.out
new file mode 100644
index 00000000..2b73c5cc
--- /dev/null
+++ b/tests/xfs/550.out
@@ -0,0 +1,232 @@ 
+QA output created by 550
+Checking User quota
+dump options test (type=u)
+no options (full range)
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+fs = SCRATCH_DEV
+#ID          2048    8192      10      20
+-L option
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+fs = SCRATCH_DEV
+#ID          2048    8192      10      20
+-U option
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+-L/-U options (one element range)
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+-L/-U options (multiple elements range)
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+fs = SCRATCH_DEV
+#ID          2048    8192      10      20
+-L/-U options (empty range)
+-L/-U options (full range)
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+fs = SCRATCH_DEV
+#ID          2048    8192      10      20
+report options test (type=u)
+no options (full range)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+fsgqa 0 512 2048 00 [--------] 0 10 20 00 [--------]
+fsgqa2 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+
+-L options
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+#ID 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+
+-U options
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+
+-L/-U options (one element range)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+
+-L/-U options (multiple elements range)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+#ID 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+
+-L/-U options (empty range)
+-L/-U options (full range)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+#ID 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+
+Checking Group quota
+dump options test (type=g)
+no options (full range)
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+fs = SCRATCH_DEV
+#ID          2048    8192      10      20
+-L option
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+fs = SCRATCH_DEV
+#ID          2048    8192      10      20
+-U option
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+-L/-U options (one element range)
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+-L/-U options (multiple elements range)
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+fs = SCRATCH_DEV
+#ID          2048    8192      10      20
+-L/-U options (empty range)
+-L/-U options (full range)
+fs = SCRATCH_DEV
+#ID          1024    4096      10      20
+fs = SCRATCH_DEV
+#ID          2048    8192      10      20
+report options test (type=g)
+no options (full range)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+fsgqa 0 512 2048 00 [--------] 0 10 20 00 [--------]
+fsgqa2 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+
+-L options
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+#ID 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+
+-U options
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+
+-L/-U options (one element range)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+
+-L/-U options (multiple elements range)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+#ID 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+
+-L/-U options (empty range)
+-L/-U options (full range)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+#ID 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+
+Checking Project quota
+dump options test (type=p)
+no options (full range)
+fs = SCRATCH_DEV
+#ID            1024    4096      10      20
+fs = SCRATCH_DEV
+#ID            2048    8192      10      20
+-L option
+fs = SCRATCH_DEV
+#ID            1024    4096      10      20
+fs = SCRATCH_DEV
+#ID            2048    8192      10      20
+-U option
+fs = SCRATCH_DEV
+#ID            1024    4096      10      20
+-L/-U options (one element range)
+fs = SCRATCH_DEV
+#ID            1024    4096      10      20
+-L/-U options (multiple elements range)
+fs = SCRATCH_DEV
+#ID            1024    4096      10      20
+fs = SCRATCH_DEV
+#ID            2048    8192      10      20
+-L/-U options (empty range)
+-L/-U options (full range)
+fs = SCRATCH_DEV
+#ID            1024    4096      10      20
+fs = SCRATCH_DEV
+#ID            2048    8192      10      20
+report options test (type=p)
+no options (full range)
+Project quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Project ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+fsgqa 0 512 2048 00 [--------] 0 10 20 00 [--------]
+fsgqa2 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+
+-L options
+Project quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Project ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+#ID 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+
+-U options
+Project quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Project ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+
+-L/-U options (one element range)
+Project quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Project ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+
+-L/-U options (multiple elements range)
+Project quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Project ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+#ID 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+
+-L/-U options (empty range)
+-L/-U options (full range)
+Project quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes
+Project ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace
+---------- -------------------------------------------------- --------------------------------------------------
+#ID 0 512 2048 00 [--------] 0 10 20 00 [--------]
+#ID 0 1024 4096 00 [--------] 0 10 20 00 [--------]
+