test: add more cases for schedTest

This commit is contained in:
dualfroz committed 2026-09-11 16:10:55 +02:00
1 parent f7c3e005a1
commit 86ef404a1f
1 file changed
+157
+157
View File
@@ -1254,3 +1254,160 @@ KTEST(threadCreateDefaultsPgidToItsOwnIdWhenCurrentIsTheIdleThread)
KT_TRUE(t, threadDiscard(id));
}
KTEST(threadCreateUserDefaultsPgidToItsOwnIdWhenCurrentIsTheIdleThread)
{
uint64 entry = 0x350000000ull + 0x2000;
uint32 id = threadCreateUser("pgidDefaultUser", entry, elfSlotStackTop(entry));
KT_NE(t, id, threadInvalidId);
KT_EQU(t, threadAt(id)->pgid, id);
KT_TRUE(t, threadDiscard(id));
}
/*
* Thread.uid (sched.h) -- the credential vfs.c's vfsPermitted consults
* alongside a file's own owner uid and mode (see coreTest.c's own
* vfsPermitted coverage for that pure-logic half). Same "ktestRunAll
* always runs as the idle thread" reasoning as the pgid tests immediately
* above applies here too: every plain threadCreate/threadCreateUser call
* exercises the "boot-time thread starts as uid 0" default; the OTHER
* default (a runtime child inheriting a genuinely running, non-root
* parent's uid) can only ever be exercised by a real ring-3 userSpawn,
* which is why user/identtest.c's own inheritance-then-drop demo is this
* feature's live proof instead. currentThreadSetUid's own privilege rule
* (root may become anyone; anyone else only their own current uid) is
* likewise never exercised here on purpose: it can only ever act on
* "whoever is currently running" (see its own doc comment), and mutating
* ktestRunAll's own idle-thread uid away from 0 would permanently corrupt
* every later test AND every boot-time spawnUser call still to come after
* ktestRunAll returns -- a real, one-way privilege drop is exactly the
* kind of state no shared test-suite context may ever touch.
*/
KTEST(threadCreateDefaultsUidToRootWhenCurrentIsTheIdleThread)
{
uint32 id = threadCreate("uidDefaultKernel", noopThreadEntry);
KT_NE(t, id, threadInvalidId);
KT_EQU(t, threadAt(id)->uid, 0u);
KT_TRUE(t, threadDiscard(id));
}
KTEST(threadCreateUserDefaultsUidToRootWhenCurrentIsTheIdleThread)
{
uint64 entry = 0x350000000ull + 0x2000;
uint32 id = threadCreateUser("uidDefaultUser", entry, elfSlotStackTop(entry));
KT_NE(t, id, threadInvalidId);
KT_EQU(t, threadAt(id)->uid, 0u);
KT_TRUE(t, threadDiscard(id));
}
KTEST(threadPgidReturnsInvalidForOutOfRangeOrNeverCreatedSlots)
{
KT_EQU(t, threadPgid(threadCapacity()), threadInvalidId);
KT_EQU(t, threadPgid(threadCapacity() + 1000), threadInvalidId);
uint32 neverUsed = threadCount();
if (neverUsed < threadCapacity())
KT_EQU(t, threadPgid(neverUsed), threadInvalidId);
}
KTEST(threadPgidReturnsInvalidAfterDiscardOrReap)
{
uint32 id = threadCreate("pgidGoneAfterDiscard", noopThreadEntry);
KT_NE(t, id, threadInvalidId);
KT_EQU(t, threadPgid(id), id);
KT_TRUE(t, threadDiscard(id));
KT_EQU(t, threadPgid(id), threadInvalidId);
}
KTEST(threadSetPgidRejectsIdleOutOfRangeAndNeverCreatedSlots)
{
KT_FALSE(t, threadSetPgid(0, 1));
KT_FALSE(t, threadSetPgid(threadCapacity(), 1));
KT_FALSE(t, threadSetPgid(threadCapacity() + 1000, 1));
uint32 neverUsed = threadCount();
if (neverUsed < threadCapacity())
KT_FALSE(t, threadSetPgid(neverUsed, 1));
}
KTEST(threadSetPgidChangesGroupOfALiveThread)
{
uint32 leader = threadCreate("pgidLeader", noopThreadEntry);
uint32 joiner = threadCreate("pgidJoiner", noopThreadEntry);
KT_NE(t, leader, threadInvalidId);
KT_NE(t, joiner, threadInvalidId);
/* Each started as its own group leader (the KTEST-runs-as-idle default
above) -- explicitly move joiner into leader's group, exactly like a
real setpgid(joinerPid, leaderPid) call. */
KT_NE(t, threadAt(joiner)->pgid, threadAt(leader)->pgid);
KT_TRUE(t, threadSetPgid(joiner, threadAt(leader)->pgid));
KT_EQU(t, threadAt(joiner)->pgid, threadAt(leader)->pgid);
KT_TRUE(t, threadDiscard(leader));
KT_TRUE(t, threadDiscard(joiner));
}
KTEST(threadSetPgidRejectsDeadOrUnusedTarget)
{
uint32 id = threadCreate("pgidSetOnDead", noopThreadEntry);
KT_NE(t, id, threadInvalidId);
KT_TRUE(t, threadKill(id));
KT_FALSE(t, threadSetPgid(id, 12345));
KT_TRUE(t, threadReap(id));
KT_FALSE(t, threadSetPgid(id, 12345));
}
KTEST(threadPriorityDefaultsToSchedDefaultWeightForANewThread)
{
uint32 id = threadCreate("priorityDefault", noopThreadEntry);
KT_NE(t, id, threadInvalidId);
KT_EQU(t, threadPriority(id), schedDefaultWeight);
KT_TRUE(t, threadDiscard(id));
}
KTEST(threadPriorityReturnsZeroForOutOfRangeOrNeverCreatedSlots)
{
KT_EQU(t, threadPriority(threadCapacity()), 0u);
KT_EQU(t, threadPriority(threadCapacity() + 1000), 0u);
uint32 neverUsed = threadCount();
if (neverUsed < threadCapacity())
KT_EQU(t, threadPriority(neverUsed), 0u);
}
KTEST(threadPriorityReturnsZeroAfterDiscard)
{
uint32 id = threadCreate("priorityGoneAfterDiscard", noopThreadEntry);
KT_NE(t, id, threadInvalidId);
KT_EQU(t, threadPriority(id), schedDefaultWeight);
KT_TRUE(t, threadDiscard(id));
KT_EQU(t, threadPriority(id), 0u);
}
KTEST(threadSetPriorityRejectsIdleOutOfRangeZeroWeightAndNeverCreatedSlots)
{
KT_FALSE(t, threadSetPriority(0, 2048));
KT_FALSE(t, threadSetPriority(threadCapacity(), 2048));
KT_FALSE(t, threadSetPriority(threadCapacity() + 1000, 2048));
uint32 id = threadCreate("priorityRejectZero", noopThreadEntry);
KT_NE(t, id, threadInvalidId);
KT_FALSE(t, threadSetPriority(id, 0));
KT_EQU(t, threadPriority(id), schedDefaultWeight);
KT_TRUE(t, threadDiscard(id));
uint32 neverUsed = threadCount();
if (neverUsed < threadCapacity())
KT_FALSE(t, threadSetPriority(neverUsed, 2048));
}
KTEST(threadSetPriorityChangesWeightOfALiveThread)
{
uint32 id = threadCreate("priorityChange", noopThreadEntry);
KT_NE(t, id, threadInvalidId);