test: cover printLong and bytesEqual
This commit is contained in:
1 parent
afe8ddf044
commit
b4fbcaf660
2 files changed
+202
No files matched your search
+131
@@ -0,0 +1,131 @@
|
|||||||
|
#include "ulib.h"
|
||||||
|
#include "fs.h"
|
||||||
|
|
||||||
|
static const char* diskPath = "/dev/disk0";
|
||||||
|
|
||||||
|
static void printLong(const char* label, long value)
|
||||||
|
{
|
||||||
|
print(label);
|
||||||
|
printDec(value);
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bytesEqual(const char* a, const char* b, unsigned long n)
|
||||||
|
{
|
||||||
|
for (unsigned long i = 0; i < n; i++)
|
||||||
|
if (a[i] != b[i])
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
print("disktest: start, pid=");
|
||||||
|
printDec(userGetpid());
|
||||||
|
print("\n");
|
||||||
|
|
||||||
|
FbStat st;
|
||||||
|
if (userStat(diskPath, &st) != 0) {
|
||||||
|
print("disktest: stat failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printLong("disktest: disk size bytes=", (long)st.size);
|
||||||
|
if (st.size < 64 * 1024) {
|
||||||
|
print("disktest: FAIL disk suspiciously small\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = (int)userOpen(diskPath, oReadWrite);
|
||||||
|
if (fd < 0) {
|
||||||
|
print("disktest: open failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
long end = userLseek(fd, 0, seekEnd);
|
||||||
|
printLong("disktest: seekEnd=", end);
|
||||||
|
if (end != (long)st.size) {
|
||||||
|
print("disktest: FAIL seekEnd does not match stat size\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unaligned write/read spanning a 512-byte sector boundary: byte offset
|
||||||
|
50*512 + 500 leaves 12 bytes in sector 50 and spills 8 bytes into
|
||||||
|
sector 51, exercising the read-modify-write path in vfs.c blockDevRead
|
||||||
|
/blockDevWrite rather than a single aligned sector transfer. */
|
||||||
|
const long straddleOffset = 50L * 512 + 500;
|
||||||
|
const char* straddlePayload = "ABCDEFGHIJKLMNOPQRST"; /* 20 bytes */
|
||||||
|
const unsigned long straddleLen = 20;
|
||||||
|
|
||||||
|
if (userLseek(fd, straddleOffset, seekSet) != straddleOffset) {
|
||||||
|
print("disktest: FAIL lseek to straddle offset\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
long written = userWrite(fd, straddlePayload, straddleLen);
|
||||||
|
printLong("disktest: straddle write bytes=", written);
|
||||||
|
if (written != (long)straddleLen) {
|
||||||
|
print("disktest: FAIL short straddle write\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userLseek(fd, straddleOffset, seekSet) != straddleOffset) {
|
||||||
|
print("disktest: FAIL lseek back to straddle offset\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
char straddleBack[20];
|
||||||
|
long straddleRead = userRead(fd, straddleBack, straddleLen);
|
||||||
|
if (straddleRead != (long)straddleLen || !bytesEqual(straddleBack, straddlePayload, straddleLen)) {
|
||||||
|
print("disktest: FAIL straddle round-trip mismatch\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
print("disktest: straddle round-trip ok\n");
|
||||||
|
|
||||||
|
/* Aligned full-sector write/read at a disjoint offset (sector 55),
|
||||||
|
proving the non-read-modify-write path also works. */
|
||||||
|
const long alignedOffset = 55L * 512;
|
||||||
|
char alignedOut[512];
|
||||||
|
for (int i = 0; i < 512; i++)
|
||||||
|
alignedOut[i] = (char)('a' + (i % 26));
|
||||||
|
|
||||||
|
if (userLseek(fd, alignedOffset, seekSet) != alignedOffset) {
|
||||||
|
print("disktest: FAIL lseek to aligned offset\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (userWrite(fd, alignedOut, sizeof(alignedOut)) != (long)sizeof(alignedOut)) {
|
||||||
|
print("disktest: FAIL aligned sector write\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (userLseek(fd, alignedOffset, seekSet) != alignedOffset) {
|
||||||
|
print("disktest: FAIL lseek back to aligned offset\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
char alignedIn[512];
|
||||||
|
if (userRead(fd, alignedIn, sizeof(alignedIn)) != (long)sizeof(alignedIn) ||
|
||||||
|
!bytesEqual(alignedIn, alignedOut, sizeof(alignedOut))) {
|
||||||
|
print("disktest: FAIL aligned sector round-trip mismatch\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
print("disktest: aligned sector round-trip ok\n");
|
||||||
|
|
||||||
|
/* Overwrite proves the second write actually lands on disk, not just in
|
||||||
|
a stale in-memory copy: reading back must see the newest data. */
|
||||||
|
if (userLseek(fd, alignedOffset, seekSet) != alignedOffset)
|
||||||
|
return 1;
|
||||||
|
char overwrite[512];
|
||||||
|
for (int i = 0; i < 512; i++)
|
||||||
|
overwrite[i] = (char)('A' + (i % 26));
|
||||||
|
userWrite(fd, overwrite, sizeof(overwrite));
|
||||||
|
|
||||||
|
if (userLseek(fd, alignedOffset, seekSet) != alignedOffset)
|
||||||
|
return 1;
|
||||||
|
char reread[512];
|
||||||
|
userRead(fd, reread, sizeof(reread));
|
||||||
|
if (!bytesEqual(reread, overwrite, sizeof(overwrite)) || bytesEqual(reread, alignedOut, sizeof(alignedOut))) {
|
||||||
|
print("disktest: FAIL overwrite not reflected\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
print("disktest: overwrite round-trip ok\n");
|
||||||
|
|
||||||
|
userClose(fd);
|
||||||
|
print("disktest: done\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
#include "ulib.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Boot-time driver for early-wake signal delivery (signal.h/sched.c's
|
||||||
|
* threadWakeForSignal): spawns eintrtarget.c, waits for a real
|
||||||
|
* happens-before confirmation that it is about to block forever on a read
|
||||||
|
* that no writer will ever satisfy (the same unsatisfiable-by-construction
|
||||||
|
* setup killtest.c's killvictim.c already established for threadKill), and
|
||||||
|
* sends it a real sigTerm through userSigSend -- an ORDINARY signal with
|
||||||
|
* its real default disposition (Terminate), not threadKill's direct
|
||||||
|
* bypass.
|
||||||
|
*
|
||||||
|
* If userWait below ever hung the whole boot (see ci-test.sh's 25s QEMU
|
||||||
|
* timeout), that would itself BE the regression this proves against: a
|
||||||
|
* Blocked thread that never naturally wakes has no other way back to ring 3
|
||||||
|
* for isr.c's deliverPendingSignals to ever reach it, without the
|
||||||
|
* early-wake this test exists to exercise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
print("eintrtest: start, pid=");
|
||||||
|
printDec(userGetpid());
|
||||||
|
print("\n");
|
||||||
|
|
||||||
|
long readyHandle = userPipeCreate();
|
||||||
|
if (readyHandle < 0) {
|
||||||
|
print("eintrtest: FAIL create ready pipe\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
long readyFd = userPipeAttach(readyHandle, 0);
|
||||||
|
if (readyFd < 0) {
|
||||||
|
print("eintrtest: FAIL attach ready pipe\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char readyHandleStr[24];
|
||||||
|
decToString(readyHandle, readyHandleStr);
|
||||||
|
char* targetArgv[] = { "/bin/eintrtarget", readyHandleStr, 0 };
|
||||||
|
long target = userSpawn("/bin/eintrtarget", targetArgv);
|
||||||
|
if (target < 0) {
|
||||||
|
print("eintrtest: FAIL spawn eintrtarget\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char readyByte;
|
||||||
|
if (userRead((int)readyFd, &readyByte, 1) != 1) {
|
||||||
|
print("eintrtest: FAIL read ready byte\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
userClose((int)readyFd);
|
||||||
|
print("eintrtest: eintrtarget ready\n");
|
||||||
|
|
||||||
|
if (userSigSend(target, sigTerm) != 0) {
|
||||||
|
print("eintrtest: FAIL send sigTerm to eintrtarget\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
print("eintrtest: sent sigTerm to eintrtarget\n");
|
||||||
|
|
||||||
|
long status = userWait(target);
|
||||||
|
print("eintrtest: eintrtarget exit status=");
|
||||||
|
printDec(status);
|
||||||
|
print("\n");
|
||||||
|
if (status != 128 + sigTerm) {
|
||||||
|
print("eintrtest: FAIL expected eintrtarget exit status 128+sigTerm\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
print("eintrtest: early-wake-signal-ok\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user