git: 8fd4d1c0fff8 - main - tests: Add pjdfstest integration
Date: Fri, 19 Jun 2026 15:39:57 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=8fd4d1c0fff8441b42dbab767810db7aeaf796c3
commit 8fd4d1c0fff8441b42dbab767810db7aeaf796c3
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-06-19 13:27:04 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-06-19 15:20:51 +0000
tests: Add pjdfstest integration
Use ATF to wrap the new reimplementation of pjdfstest that came out of
GSOC 2022, now available in the ports tree as filesystems/pjdfstest.
So far I added tests for UFS (with several different option
combinations), tmpfs and ZFS, plus ZFS+nullfs. All of these create a
memory disk, initialize the filesystem, and point the pjdfstest
executable at it.
In the future it would be good to add tests for at least NFS and p9fs.
Reviewed by: asomers
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D56605
---
etc/mtree/BSD.tests.dist | 2 +
tests/sys/fs/Makefile | 1 +
tests/sys/fs/pjdfstest/Makefile | 12 ++++
tests/sys/fs/pjdfstest/tmpfs.sh | 60 +++++++++++++++++++
tests/sys/fs/pjdfstest/ufs.sh | 130 ++++++++++++++++++++++++++++++++++++++++
tests/sys/fs/pjdfstest/zfs.sh | 96 +++++++++++++++++++++++++++++
6 files changed, 301 insertions(+)
diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
index b6c415e9e789..3c3662c11502 100644
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -834,6 +834,8 @@
fs
fusefs
..
+ pjdfstest
+ ..
tarfs
..
tmpfs
diff --git a/tests/sys/fs/Makefile b/tests/sys/fs/Makefile
index 254394f43714..823a31a4dbbe 100644
--- a/tests/sys/fs/Makefile
+++ b/tests/sys/fs/Makefile
@@ -12,6 +12,7 @@ TESTSRC= ${SRCTOP}/contrib/netbsd-tests/fs
.if ${COMPILER_FEATURES:Mc++14} && ${MK_GOOGLETEST} != "no"
TESTS_SUBDIRS+= fusefs
.endif
+TESTS_SUBDIRS+= pjdfstest
TESTS_SUBDIRS+= tarfs
TESTS_SUBDIRS+= tmpfs
TESTS_SUBDIRS+= unionfs
diff --git a/tests/sys/fs/pjdfstest/Makefile b/tests/sys/fs/pjdfstest/Makefile
new file mode 100644
index 000000000000..62e937198e34
--- /dev/null
+++ b/tests/sys/fs/pjdfstest/Makefile
@@ -0,0 +1,12 @@
+TESTSDIR= ${TESTSBASE}/sys/fs/pjdfstest
+
+PACKAGE= tests
+
+ATF_TESTS_SH+= tmpfs \
+ ufs \
+ zfs
+
+# Tests use an external resource.
+TEST_METADATA.p9fs+= is_exclusive=true
+
+.include <bsd.test.mk>
diff --git a/tests/sys/fs/pjdfstest/tmpfs.sh b/tests/sys/fs/pjdfstest/tmpfs.sh
new file mode 100644
index 000000000000..cd56acbd04c6
--- /dev/null
+++ b/tests/sys/fs/pjdfstest/tmpfs.sh
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 2026 Mark Johnston <markj@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+setup()
+{
+ cat <<__EOF__ > pjdfstest.toml
+[features]
+chflags = {}
+posix_fallocate = {}
+rename_ctime = {}
+stat_st_birthtime = {}
+utimensat = {}
+utime_now = {}
+
+[settings]
+naptime = 0.001
+__EOF__
+
+ atf_check mkdir mnt
+ atf_check mount -t tmpfs none mnt
+}
+
+doit()
+{
+ atf_check -o ignore pjdfstest -c pjdfstest.toml -p mnt
+ atf_check umount mnt
+ atf_check rmdir mnt
+}
+
+cleanup()
+{
+ if [ -d ./mnt ]; then
+ umount ./mnt
+ fi
+}
+
+atf_test_case tmpfs cleanup
+tmpfs_head()
+{
+ atf_set descr "Checks that pjdfstest passes on tmpfs"
+ atf_set require.progs pjdfstest
+ atf_set require.user root
+}
+tmpfs_body()
+{
+ setup
+ doit
+}
+tmpfs_cleanup()
+{
+ cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case tmpfs
+}
diff --git a/tests/sys/fs/pjdfstest/ufs.sh b/tests/sys/fs/pjdfstest/ufs.sh
new file mode 100644
index 000000000000..4bba5698df00
--- /dev/null
+++ b/tests/sys/fs/pjdfstest/ufs.sh
@@ -0,0 +1,130 @@
+#
+# Copyright (c) 2026 Mark Johnston <markj@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+setup()
+{
+ local md
+
+ atf_check -o save:md mdconfig -a -t swap -s 1g
+ md=/dev/$(cat md)
+ atf_check -o ignore -e ignore newfs -t $@ $md
+
+ cat <<__EOF__ > pjdfstest.toml
+[features]
+chflags = {}
+posix_fallocate = {}
+rename_ctime = {}
+stat_st_birthtime = {}
+utimensat = {}
+utime_now = {}
+
+[settings]
+naptime = 0.001
+__EOF__
+
+ atf_check mkdir mnt
+ atf_check mount $md ./mnt
+}
+
+doit()
+{
+ atf_check -o ignore pjdfstest -c pjdfstest.toml -p mnt
+ atf_check umount ./mnt
+ atf_check rmdir ./mnt
+}
+
+cleanup()
+{
+ if [ -d ./mnt ]; then
+ umount ./mnt
+ fi
+ if [ -s md ]; then
+ mdconfig -d -u $(cat md)
+ fi
+}
+
+atf_test_case ufs1 cleanup
+ufs1_head()
+{
+ atf_set descr "Run pjdfstest on a UFS1 filesystem"
+ atf_set require.user root
+ atf_set require.progs pjdfstest
+}
+ufs1_body()
+{
+ setup -O 1
+ # UFS1 doesn't have 64-bit timestamps or a birthtime field in the inode.
+ cat >> pjdfstest.toml <<__EOF__
+expected_failures = [
+"utimensat::birthtime",
+"utimensat::y2038"
+]
+__EOF__
+ doit
+}
+ufs1_cleanup()
+{
+ cleanup
+}
+
+atf_test_case ufs2_nosu cleanup
+ufs2_nosu_head()
+{
+ atf_set descr "Run pjdfstest on a UFS2 filesystem without soft updates"
+ atf_set require.user root
+ atf_set require.progs pjdfstest
+}
+ufs2_nosu_body()
+{
+ setup -O 2 -u
+ doit
+}
+ufs2_nosu_cleanup()
+{
+ cleanup
+}
+
+atf_test_case ufs2_su cleanup
+ufs2_su_head()
+{
+ atf_set descr "Run pjdfstest on a UFS2 filesystem with soft updates"
+ atf_set require.user root
+ atf_set require.progs pjdfstest
+}
+ufs2_su_body()
+{
+ setup -O 2 -U
+ doit
+}
+ufs2_su_cleanup()
+{
+ cleanup
+}
+
+atf_test_case ufs2_suj cleanup
+ufs2_suj_head()
+{
+ atf_set descr "Run pjdfstest on a UFS2 filesystem with soft updates journaling"
+ atf_set require.user root
+ atf_set require.progs pjdfstest
+}
+ufs2_suj_body()
+{
+ setup -O 2 -U -j
+ doit
+}
+ufs2_suj_cleanup()
+{
+ cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case ufs1
+ atf_add_test_case ufs2_nosu
+ atf_add_test_case ufs2_su
+ atf_add_test_case ufs2_suj
+}
diff --git a/tests/sys/fs/pjdfstest/zfs.sh b/tests/sys/fs/pjdfstest/zfs.sh
new file mode 100644
index 000000000000..44e539b7abd2
--- /dev/null
+++ b/tests/sys/fs/pjdfstest/zfs.sh
@@ -0,0 +1,96 @@
+#
+# Copyright (c) 2026 Mark Johnston <markj@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+setup()
+{
+ local disk pool
+
+ truncate -s 1g disk
+
+ cat <<__EOF__ > pjdfstest.toml
+[features]
+chflags = {}
+rename_ctime = {}
+stat_st_birthtime = {}
+utimensat = {}
+utime_now = {}
+
+[settings]
+naptime = 0.001
+__EOF__
+
+ atf_check mkdir mnt
+ pool=pjdfstest$$
+ atf_check zpool create -m $(pwd)/mnt $pool $(pwd)/disk
+ echo $pool > pool
+}
+
+doit()
+{
+ local mp
+
+ mp=${1:-mnt}
+ atf_check -o ignore pjdfstest -c pjdfstest.toml -p $mp
+ if [ "$mp" != "mnt" ]; then
+ atf_check umount $mp
+ atf_check rmdir $mp
+ fi
+ atf_check zpool destroy $(cat pool)
+ atf_check rm -f pool
+}
+
+cleanup()
+{
+ if [ -s pool ]; then
+ zpool destroy $(cat pool)
+ fi
+}
+
+atf_test_case zfs cleanup
+zfs_head()
+{
+ atf_set descr "Checks that pjdfstest passes on zfs"
+ atf_set require.user root
+ atf_set require.progs pjdfstest
+}
+zfs_body()
+{
+ setup
+ doit
+}
+zfs_cleanup()
+{
+ cleanup
+}
+
+atf_test_case zfs_nullfs cleanup
+zfs_nullfs_head()
+{
+ atf_set descr "Checks that pjdfstest passes on zfs mounted via nullfs"
+ atf_set require.user root
+ atf_set require.progs pjdfstest
+}
+zfs_nullfs_body()
+{
+ setup
+ atf_check mkdir mnt2
+ atf_check mount -t nullfs mnt mnt2
+ doit mnt2
+}
+zfs_nullfs_cleanup()
+{
+ if [ -d mnt2 ]; then
+ umount mnt2
+ rmdir mnt2
+ fi
+ cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case zfs
+ atf_add_test_case zfs_nullfs
+}