test: strengthen tests for sfsTest

This commit is contained in:
dualfroz committed 2026-09-11 18:41:39 +02:00
1 parent 404a1e62b8
commit f99e8eeed4
1 file changed
+156
+156
View File
@@ -468,3 +468,159 @@ KTEST(sfsPersistsMtimeAndCtimeAcrossUnmountRemount)
return; return;
KT_EQ(t, sfsWriteAt(f, 0, "persisted", 9), 9); KT_EQ(t, sfsWriteAt(f, 0, "persisted", 9), 9);
uint64 mtimeBefore = sfsMtimeOf(f);
uint64 ctimeBefore = sfsCtimeOf(f);
KT_GT(t, mtimeBefore, 0);
sfsUnmount();
KT_TRUE(t, sfsMount());
int32 reloaded = sfsLookup("timepersist.txt");
KT_EQ(t, reloaded, f);
KT_EQ(t, sfsMtimeOf(reloaded), mtimeBefore);
KT_EQ(t, sfsCtimeOf(reloaded), ctimeBefore);
}
/* Real chmod(2) owner rwx bits (fs.h's fsModeOwner*): createNode stamps a
type-based default (a file gets fsModeDefaultFile, a directory gets
fsModeDefaultDir), sfsChmod overwrites it and bumps ctime like any other
metadata-only mutation (sfsLink's linkCount bump does the same, see
above), and sfsModeOf/sfsChmod on an invalid inode number fail the same
way sfsSizeOf/sfsTypeOf already do for one. */
KTEST(sfsModeDefaultsByTypeAndChmodBumpsCtime)
{
if (!KT_TRUE(t, sfsFormat()))
return;
int32 f = sfsCreateFile("modefile.txt");
if (!KT_TRUE(t, f > 0))
return;
KT_EQ(t, sfsModeOf(f), fsModeDefaultFile);
int32 d = sfsCreateDir("modedir");
if (!KT_TRUE(t, d > 0))
return;
KT_EQ(t, sfsModeOf(d), fsModeDefaultDir);
uint64 ctimeBefore = sfsCtimeOf(f);
int64 before = rtcNow();
KT_TRUE(t, sfsChmod(f, 0400));
int64 after = rtcNow();
KT_EQ(t, sfsModeOf(f), 0400u);
KT_GE(t, sfsCtimeOf(f), ctimeBefore);
KT_GE(t, sfsCtimeOf(f), before);
KT_LE(t, sfsCtimeOf(f), after);
KT_EQ(t, sfsModeOf(-1), 0u);
KT_EQ(t, sfsModeOf(9999), 0u);
KT_FALSE(t, sfsChmod(-1, 0644));
KT_FALSE(t, sfsChmod(9999, 0644));
}
/* Same real point as sfsPersistsMtimeAndCtimeAcrossUnmountRemount above,
applied to mode: sfsUnmount() drops every in-memory structure, so an
exact match after sfsMount() proves the chmod'd value genuinely lives on
disk inside the inode, not in some cache that happens to survive. */
KTEST(sfsPersistsModeAcrossUnmountRemount)
{
if (!KT_TRUE(t, sfsFormat()))
return;
int32 f = sfsCreateFile("modepersist.txt");
if (!KT_TRUE(t, f > 0))
return;
KT_TRUE(t, sfsChmod(f, 0400));
sfsUnmount();
KT_TRUE(t, sfsMount());
int32 reloaded = sfsLookup("modepersist.txt");
KT_EQ(t, reloaded, f);
KT_EQ(t, sfsModeOf(reloaded), 0400u);
}
/* Real owner identity (fs.h's FbStat.uid, sched.h's currentThreadUid()):
createNode stamps every new node -- file, dir, symlink, fifo all go
through it, exactly like mtime/ctime already verified sufficient for
(FALA 39's own note) -- with whoever is CURRENT at creation time.
ktestRunAll always runs as the permanent idle thread (id 0, uid 0), the
same context schedTest.c's own uid-default tests already document
relying on, so both a freshly created file and the root inode itself
(sfsFormat, this test's own sfsFormat() call included) come back
root-owned. sfsUidOf on an invalid inode number fails the same way
sfsModeOf/sfsSizeOf/sfsTypeOf already do for one. */
KTEST(sfsCreateNodeStampsCreatorUidAsOwner)
{
if (!KT_TRUE(t, sfsFormat()))
return;
KT_EQU(t, sfsUidOf(sfsRootInode), 0u);
int32 f = sfsCreateFile("uidfile.txt");
if (!KT_TRUE(t, f > 0))
return;
KT_EQU(t, sfsUidOf(f), 0u);
int32 d = sfsCreateDir("uiddir");
if (!KT_TRUE(t, d > 0))
return;
KT_EQU(t, sfsUidOf(d), 0u);
KT_EQU(t, sfsUidOf(-1), 0u);
KT_EQU(t, sfsUidOf(9999), 0u);
}
/* Same real point as sfsPersistsModeAcrossUnmountRemount above, applied to
uid: sfsUnmount() drops every in-memory structure, so an exact match
after sfsMount() proves ownership genuinely lives on disk inside the
inode, not in some cache that happens to survive. */
KTEST(sfsPersistsUidAcrossUnmountRemount)
{
if (!KT_TRUE(t, sfsFormat()))
return;
int32 f = sfsCreateFile("uidpersist.txt");
if (!KT_TRUE(t, f > 0))
return;
KT_EQU(t, sfsUidOf(f), 0u);
sfsUnmount();
KT_TRUE(t, sfsMount());
int32 reloaded = sfsLookup("uidpersist.txt");
KT_EQ(t, reloaded, f);
KT_EQU(t, sfsUidOf(reloaded), 0u);
}
/* Real chown(2)'s on-disk half (sfsChown): overwrites the inode's owner
uid outright and bumps ctime like sfsChmod's own metadata-only mutation
does -- same "bump ctime, invalid inode fails the same way" shape as
sfsModeDefaultsByTypeAndChmodBumpsCtime above. sfsChown itself has no
privilege check (vfsChown, vfs.c, is the real choke point that enforces
chown(2)'s root-only rule), so calling it directly here at any uid is
deliberately not restricted. */
KTEST(sfsChownReassignsOwnerAndBumpsCtime)
{
if (!KT_TRUE(t, sfsFormat()))
return;
int32 f = sfsCreateFile("chownfile.txt");
if (!KT_TRUE(t, f > 0))
return;
KT_EQU(t, sfsUidOf(f), 0u);
uint64 ctimeBefore = sfsCtimeOf(f);
int64 before = rtcNow();
KT_TRUE(t, sfsChown(f, 9001));
int64 after = rtcNow();
KT_EQU(t, sfsUidOf(f), 9001u);
KT_GE(t, sfsCtimeOf(f), ctimeBefore);
KT_GE(t, sfsCtimeOf(f), before);
KT_LE(t, sfsCtimeOf(f), after);
KT_FALSE(t, sfsChown(-1, 1000));
KT_FALSE(t, sfsChown(9999, 1000));
}