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;
|
||||
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