test: strengthen tests for sfsTest
This commit is contained in:
1 parent
404a1e62b8
commit
f99e8eeed4
1 file changed
+156
+156
@@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user