summaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-12-31 09:50:47 +0100
committerAmlal El Mahrouss <amlal@nekernel.org>2025-12-31 09:50:47 +0100
commit9f2369825584529ed2036588263aecf01bf89818 (patch)
treee47b2f6ab27c3701eeb872be1a25cc9233455910 /test
parentaf944082df5844cf3215dc9dd4960aeedd18bd75 (diff)
feat: test add more tests.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'test')
-rw-r--r--test/kernel_test/error.test.cc67
-rw-r--r--test/kernel_test/event.test.cc103
-rw-r--r--test/kernel_test/kout.test.cc58
-rw-r--r--test/kernel_test/process.test.cc66
-rw-r--r--test/kernel_test/scheduler.test.cc108
-rw-r--r--test/libsystem_test/io.test.cc155
-rw-r--r--test/libsystem_test/memory.test.cc136
-rw-r--r--test/libsystem_test/thread.test.cc142
8 files changed, 832 insertions, 3 deletions
diff --git a/test/kernel_test/error.test.cc b/test/kernel_test/error.test.cc
new file mode 100644
index 00000000..084566b2
--- /dev/null
+++ b/test/kernel_test/error.test.cc
@@ -0,0 +1,67 @@
+/// \file error.test.cc
+/// \brief Error handling API tests.
+/// \author Amlal El Mahrouss (amlal at nekernel dot org)
+
+#include <libSystem/SystemKit/System.h>
+#include <public/frameworks/KernelTest.fwrk/headers/TestCase.h>
+
+/// \note ErrGetLastError tests
+KT_DECL_TEST(ErrGetLastErrorInitial, []() -> bool {
+ SInt32 error = ErrGetLastError();
+ return error >= 0;
+});
+
+KT_DECL_TEST(ErrGetLastErrorAfterSuccess, []() -> bool {
+ auto heap = MmCreateHeap(1024, 0);
+ if (!heap) return NO;
+
+ SInt32 error = ErrGetLastError();
+ MmDestroyHeap(heap);
+
+ return error == 0;
+});
+
+KT_DECL_TEST(ErrGetLastErrorAfterFailure, []() -> bool {
+ auto heap = MmCreateHeap(0, 0);
+
+ SInt32 error = ErrGetLastError();
+
+ return error != 0;
+});
+
+KT_DECL_TEST(ErrGetLastErrorAfterInvalidFile, []() -> bool {
+ auto file = IoOpenFile("/invalid/path/that/does/not/exist", nullptr);
+
+ SInt32 error = ErrGetLastError();
+
+ if (file) IoCloseFile(file);
+
+ return error != 0;
+});
+
+KT_DECL_TEST(ErrGetLastErrorAfterNullOp, []() -> bool {
+ auto ptr = MmCopyMemory(nullptr, nullptr, 10);
+
+ SInt32 error = ErrGetLastError();
+
+ return error != 0;
+});
+
+KT_DECL_TEST(ErrGetLastErrorMultipleCalls, []() -> bool {
+ SInt32 error1 = ErrGetLastError();
+ SInt32 error2 = ErrGetLastError();
+
+ return error1 == error2;
+});
+
+/// \brief Run error tests.
+SInt32 KT_TEST_MAIN() {
+ KT_RUN_TEST(ErrGetLastErrorInitial);
+ KT_RUN_TEST(ErrGetLastErrorAfterSuccess);
+ KT_RUN_TEST(ErrGetLastErrorAfterFailure);
+ KT_RUN_TEST(ErrGetLastErrorAfterInvalidFile);
+ KT_RUN_TEST(ErrGetLastErrorAfterNullOp);
+ KT_RUN_TEST(ErrGetLastErrorMultipleCalls);
+
+ return KT_TEST_SUCCESS;
+}
diff --git a/test/kernel_test/event.test.cc b/test/kernel_test/event.test.cc
new file mode 100644
index 00000000..6e342c6b
--- /dev/null
+++ b/test/kernel_test/event.test.cc
@@ -0,0 +1,103 @@
+/// \file event.test.cc
+/// \brief Event handling API tests.
+/// \author Amlal El Mahrouss (amlal at nekernel dot org)
+
+#include <libSystem/SystemKit/System.h>
+#include <public/frameworks/KernelTest.fwrk/headers/TestCase.h>
+
+/// \note Mock event listener
+static Bool event_listener_called = NO;
+
+static Void mock_event_listener(VoidPtr data) {
+ event_listener_called = YES;
+}
+
+/// \note EvtAddListener tests
+KT_DECL_TEST(EvtAddListenerValid, []() -> bool {
+ REF_TYPE listener_ref;
+ listener_ref.__hash = 0x1234;
+ listener_ref.__self = (VoidPtr) mock_event_listener;
+
+ EvtAddListener("test_event", (Ref) &listener_ref);
+ return YES;
+});
+
+KT_DECL_TEST(EvtAddListenerNull, []() -> bool {
+ EvtAddListener(nullptr, nullptr);
+ return YES;
+});
+
+/// \note EvtRemoveListener tests
+KT_DECL_TEST(EvtRemoveListenerValid, []() -> bool {
+ REF_TYPE listener_ref;
+ listener_ref.__hash = 0x1234;
+ listener_ref.__self = (VoidPtr) mock_event_listener;
+
+ EvtAddListener("remove_test", (Ref) &listener_ref);
+ EvtRemoveListener("remove_test", (Ref) &listener_ref);
+ return YES;
+});
+
+KT_DECL_TEST(EvtRemoveListenerNull, []() -> bool {
+ EvtRemoveListener(nullptr, nullptr);
+ return YES;
+});
+
+/// \note EvtDispatchEvent tests
+KT_DECL_TEST(EvtDispatchEventValid, []() -> bool {
+ REF_TYPE listener_ref;
+ listener_ref.__hash = 0x5678;
+ listener_ref.__self = (VoidPtr) mock_event_listener;
+
+ event_listener_called = NO;
+
+ EvtAddListener("dispatch_test", (Ref) &listener_ref);
+
+ char data[] = "event_data";
+ EvtDispatchEvent("dispatch_test", (VoidPtr) data);
+
+ return YES;
+});
+
+KT_DECL_TEST(EvtDispatchEventNull, []() -> bool {
+ VoidPtr result = EvtDispatchEvent(nullptr, nullptr);
+ return result == nullptr;
+});
+
+KT_DECL_TEST(EvtDispatchEventNotExist, []() -> bool {
+ VoidPtr result = EvtDispatchEvent("nonexistent_event", nullptr);
+ return YES;
+});
+
+/// \note Event lifecycle test
+KT_DECL_TEST(EvtLifecycleTest, []() -> bool {
+ REF_TYPE listener_ref;
+ listener_ref.__hash = 0xABCD;
+ listener_ref.__self = (VoidPtr) mock_event_listener;
+
+ EvtAddListener("lifecycle_event", (Ref) &listener_ref);
+
+ char data[] = "test";
+ EvtDispatchEvent("lifecycle_event", (VoidPtr) data);
+
+ EvtRemoveListener("lifecycle_event", (Ref) &listener_ref);
+
+ return YES;
+});
+
+/// \brief Run event tests.
+SInt32 KT_TEST_MAIN() {
+ KT_RUN_TEST(EvtAddListenerValid);
+ KT_RUN_TEST(EvtAddListenerNull);
+
+ KT_RUN_TEST(EvtRemoveListenerValid);
+ KT_RUN_TEST(EvtRemoveListenerNull);
+
+ KT_RUN_TEST(EvtDispatchEventValid);
+ KT_RUN_TEST(EvtDispatchEventNull);
+ KT_RUN_TEST(EvtDispatchEventNotExist);
+
+ KT_RUN_TEST(EvtLifecycleTest);
+
+ return KT_TEST_SUCCESS;
+}
diff --git a/test/kernel_test/kout.test.cc b/test/kernel_test/kout.test.cc
index 639ab94e..fb395b90 100644
--- a/test/kernel_test/kout.test.cc
+++ b/test/kernel_test/kout.test.cc
@@ -4,14 +4,70 @@
#include <libSystem/SystemKit/System.h>
#include <public/frameworks/KernelTest.fwrk/headers/TestCase.h>
-/// \note Declare tests
+/// \note PrintGet tests
KT_DECL_TEST(KOutIsNull, []() -> bool { return PrintGet("/null/") == nullptr; });
KT_DECL_TEST(KOutIsNotNull, []() -> bool { return PrintGet(nullptr) != nullptr; });
+/// \note PrintCreate/PrintRelease tests
+KT_DECL_TEST(PrintCreateValid, []() -> bool {
+ auto handle = PrintCreate();
+ if (!handle) return NO;
+ PrintRelease(handle);
+ return YES;
+});
+
+KT_DECL_TEST(PrintReleaseValid, []() -> bool {
+ auto handle = PrintCreate();
+ if (!handle) return NO;
+ return PrintRelease(handle) == 0;
+});
+
+KT_DECL_TEST(PrintReleaseNull, []() -> bool { return PrintRelease(nullptr) != 0; });
+
+/// \note PrintOut tests
+KT_DECL_TEST(PrintOutValid, []() -> bool {
+ SInt32 result = PrintOut(nullptr, "Test output\n");
+ return result >= 0;
+});
+
+KT_DECL_TEST(PrintOutWithHandle, []() -> bool {
+ auto handle = PrintCreate();
+ SInt32 result = PrintOut(handle, "Test with handle\n");
+ PrintRelease(handle);
+ return result >= 0;
+});
+
+KT_DECL_TEST(PrintOutNull, []() -> bool {
+ SInt32 result = PrintOut(nullptr, nullptr);
+ return result < 0;
+});
+
+KT_DECL_TEST(PrintOutFormatted, []() -> bool {
+ SInt32 result = PrintOut(nullptr, "Value: %d\n", 42);
+ return result >= 0;
+});
+
+/// \note PrintIn tests
+KT_DECL_TEST(PrintInValid, []() -> bool {
+ SInt32 result = PrintIn(nullptr, "Input prompt: ");
+ return result >= 0;
+});
+
/// \brief Run 'kout' test.
SInt32 KT_TEST_MAIN() {
KT_RUN_TEST(KOutIsNull);
KT_RUN_TEST(KOutIsNotNull);
+ KT_RUN_TEST(PrintCreateValid);
+ KT_RUN_TEST(PrintReleaseValid);
+ KT_RUN_TEST(PrintReleaseNull);
+
+ KT_RUN_TEST(PrintOutValid);
+ KT_RUN_TEST(PrintOutWithHandle);
+ KT_RUN_TEST(PrintOutNull);
+ KT_RUN_TEST(PrintOutFormatted);
+
+ KT_RUN_TEST(PrintInValid);
+
return KT_TEST_SUCCESS;
} \ No newline at end of file
diff --git a/test/kernel_test/process.test.cc b/test/kernel_test/process.test.cc
index 8a1a946e..1c7af22c 100644
--- a/test/kernel_test/process.test.cc
+++ b/test/kernel_test/process.test.cc
@@ -1,11 +1,11 @@
/// \file process.test.cc
-/// \brief Process Out tests.
+/// \brief Process management tests.
/// \author Amlal El Mahrouss (amlal at nekernel dot org)
#include <libSystem/SystemKit/System.h>
#include <public/frameworks/KernelTest.fwrk/headers/TestCase.h>
-/// \note Declare tests
+/// \note RtlSpawnProcess tests
KT_DECL_TEST(ProcessHasFailed, []() -> bool {
/// \todo we return -1 here, should we document that or classify as common knowledge?
return RtlSpawnProcess("/", 0, nullptr, nullptr, 0) == -1;
@@ -17,10 +17,72 @@ KT_DECL_TEST(ProcessHasSucceeded, []() -> bool {
return RtlSpawnProcess("/system/list", 0, nullptr, nullptr, 0) > 0;
});
+KT_DECL_TEST(ProcessSpawnWithArgs, []() -> bool {
+ Char* argv[] = {(Char*) "arg1", (Char*) "arg2"};
+ Char* envp[] = {(Char*) "VAR=value"};
+
+ UIntPtr pid = RtlSpawnProcess("/system/list", 2, argv, envp, 1);
+ return pid > 0;
+});
+
+KT_DECL_TEST(ProcessSpawnNullPath, []() -> bool {
+ return RtlSpawnProcess(nullptr, 0, nullptr, nullptr, 0) == -1;
+});
+
+KT_DECL_TEST(ProcessSpawnInvalidPath, []() -> bool {
+ return RtlSpawnProcess("/invalid/nonexistent", 0, nullptr, nullptr, 0) == -1;
+});
+
+/// \note RtlSpawnIB tests
+KT_DECL_TEST(ProcessSpawnIBValid, []() -> bool {
+ UIntPtr pid = RtlSpawnProcess("/system/list", 0, nullptr, nullptr, 0);
+ if (pid <= 0) return NO;
+
+ UInt32 result = RtlSpawnIB(pid);
+ return result == 0;
+});
+
+KT_DECL_TEST(ProcessSpawnIBInvalid, []() -> bool {
+ UInt32 result = RtlSpawnIB(0);
+ return result > 0;
+});
+
+/// \note RtlExitProcess tests
+KT_DECL_TEST(ProcessExitValid, []() -> bool {
+ UIntPtr pid = RtlSpawnProcess("/system/list", 0, nullptr, nullptr, 0);
+ if (pid <= 0) return NO;
+
+ Bool result = RtlExitProcess(pid, 0);
+ return result == YES;
+});
+
+KT_DECL_TEST(ProcessExitWithCode, []() -> bool {
+ UIntPtr pid = RtlSpawnProcess("/system/list", 0, nullptr, nullptr, 0);
+ if (pid <= 0) return NO;
+
+ Bool result = RtlExitProcess(pid, 42);
+ return result == YES;
+});
+
+KT_DECL_TEST(ProcessExitInvalid, []() -> bool {
+ Bool result = RtlExitProcess(0, 0);
+ return result == NO;
+});
+
/// \brief Run 'process' test.
SInt32 KT_TEST_MAIN() {
KT_RUN_TEST(ProcessHasFailed);
KT_RUN_TEST(ProcessHasSucceeded);
+ KT_RUN_TEST(ProcessSpawnWithArgs);
+ KT_RUN_TEST(ProcessSpawnNullPath);
+ KT_RUN_TEST(ProcessSpawnInvalidPath);
+
+ KT_RUN_TEST(ProcessSpawnIBValid);
+ KT_RUN_TEST(ProcessSpawnIBInvalid);
+
+ KT_RUN_TEST(ProcessExitValid);
+ KT_RUN_TEST(ProcessExitWithCode);
+ KT_RUN_TEST(ProcessExitInvalid);
return KT_TEST_SUCCESS;
}
diff --git a/test/kernel_test/scheduler.test.cc b/test/kernel_test/scheduler.test.cc
new file mode 100644
index 00000000..58cf6017
--- /dev/null
+++ b/test/kernel_test/scheduler.test.cc
@@ -0,0 +1,108 @@
+/// \file scheduler.test.cc
+/// \brief Scheduler and debugging API tests.
+/// \author Amlal El Mahrouss (amlal at nekernel dot org)
+
+#include <libSystem/SystemKit/System.h>
+#include <public/frameworks/KernelTest.fwrk/headers/TestCase.h>
+
+/// \note SchedGetCurrentProcessID tests
+KT_DECL_TEST(SchedGetCurrentPIDValid, []() -> bool {
+ UIntPtr pid = SchedGetCurrentProcessID();
+ return pid > 0;
+});
+
+/// \note SchedSetAffinity/SchedGetAffinity tests
+KT_DECL_TEST(SchedSetAffinityValid, []() -> bool {
+ UIntPtr pid = SchedGetCurrentProcessID();
+ AffinityRef affinity;
+
+ SInt32 result = SchedSetAffinity(pid, 1, &affinity);
+ return result >= 0;
+});
+
+KT_DECL_TEST(SchedGetAffinityValid, []() -> bool {
+ UIntPtr pid = SchedGetCurrentProcessID();
+ AffinityRef affinity;
+
+ SInt32 result = SchedGetAffinity(pid, &affinity);
+ return result >= 0;
+});
+
+KT_DECL_TEST(SchedSetAffinityInvalid, []() -> bool {
+ AffinityRef affinity;
+ SInt32 result = SchedSetAffinity(0, 1, &affinity);
+ return result < 0;
+});
+
+KT_DECL_TEST(SchedGetAffinityInvalid, []() -> bool {
+ AffinityRef affinity;
+ SInt32 result = SchedGetAffinity(0, &affinity);
+ return result < 0;
+});
+
+KT_DECL_TEST(SchedAffinityRoundTrip, []() -> bool {
+ UIntPtr pid = SchedGetCurrentProcessID();
+ AffinityRef affinity_set;
+ AffinityRef affinity_get;
+
+ SchedSetAffinity(pid, 2, &affinity_set);
+ SInt32 result = SchedGetAffinity(pid, &affinity_get);
+
+ return result >= 0;
+});
+
+/// \note SchedFireSignal tests
+KT_DECL_TEST(SchedFireSignalValid, []() -> bool {
+ UIntPtr pid = SchedGetCurrentProcessID();
+ SInt32 result = SchedFireSignal(pid, 1);
+ return result >= 0;
+});
+
+KT_DECL_TEST(SchedFireSignalInvalid, []() -> bool {
+ SInt32 result = SchedFireSignal(0, 1);
+ return result < 0;
+});
+
+/// \note SchedReadMemory/SchedWriteMemory tests
+KT_DECL_TEST(SchedReadMemoryValid, []() -> bool {
+ UIntPtr pid = SchedGetCurrentProcessID();
+ SInt32 result = SchedReadMemory(pid, 0x1000, 64);
+ return result >= 0;
+});
+
+KT_DECL_TEST(SchedWriteMemoryValid, []() -> bool {
+ UIntPtr pid = SchedGetCurrentProcessID();
+ SInt32 result = SchedWriteMemory(pid, 0x1000, 0x42);
+ return result >= 0;
+});
+
+KT_DECL_TEST(SchedReadMemoryInvalid, []() -> bool {
+ SInt32 result = SchedReadMemory(0, 0x1000, 64);
+ return result < 0;
+});
+
+KT_DECL_TEST(SchedWriteMemoryInvalid, []() -> bool {
+ SInt32 result = SchedWriteMemory(0, 0x1000, 0x42);
+ return result < 0;
+});
+
+/// \brief Run scheduler tests.
+SInt32 KT_TEST_MAIN() {
+ KT_RUN_TEST(SchedGetCurrentPIDValid);
+
+ KT_RUN_TEST(SchedSetAffinityValid);
+ KT_RUN_TEST(SchedGetAffinityValid);
+ KT_RUN_TEST(SchedSetAffinityInvalid);
+ KT_RUN_TEST(SchedGetAffinityInvalid);
+ KT_RUN_TEST(SchedAffinityRoundTrip);
+
+ KT_RUN_TEST(SchedFireSignalValid);
+ KT_RUN_TEST(SchedFireSignalInvalid);
+
+ KT_RUN_TEST(SchedReadMemoryValid);
+ KT_RUN_TEST(SchedWriteMemoryValid);
+ KT_RUN_TEST(SchedReadMemoryInvalid);
+ KT_RUN_TEST(SchedWriteMemoryInvalid);
+
+ return KT_TEST_SUCCESS;
+}
diff --git a/test/libsystem_test/io.test.cc b/test/libsystem_test/io.test.cc
new file mode 100644
index 00000000..dfc21990
--- /dev/null
+++ b/test/libsystem_test/io.test.cc
@@ -0,0 +1,155 @@
+/// \file io.test.cc
+/// \brief File I/O API tests.
+/// \author Amlal El Mahrouss (amlal at nekernel dot org)
+
+#include <libSystem/SystemKit/System.h>
+#include <public/frameworks/KernelTest.fwrk/headers/TestCase.h>
+
+/// \note File open/close tests
+
+KT_DECL_TEST(IoOpenFileInvalid, []() -> bool {
+ auto file = IoOpenFile(nullptr, nullptr);
+ return file == nullptr;
+});
+
+KT_DECL_TEST(IoOpenFileValidPath, []() -> bool {
+ auto file = IoOpenFile("/test.txt", nullptr);
+ if (!file) return NO;
+ IoCloseFile(file);
+ return YES;
+});
+
+KT_DECL_TEST(IoCloseFileValid, []() -> bool {
+ auto file = IoOpenFile("/test.txt", nullptr);
+ if (!file) return NO;
+ IoCloseFile(file);
+ return YES;
+});
+
+/// \note File positioning tests
+
+KT_DECL_TEST(IoSeekFileValid, []() -> bool {
+ auto file = IoOpenFile("/test.txt", nullptr);
+ if (!file) return NO;
+
+ UInt64 pos = IoSeekFile(file, 100);
+ IoCloseFile(file);
+
+ return pos != ~0UL;
+});
+
+KT_DECL_TEST(IoTellFileValid, []() -> bool {
+ auto file = IoOpenFile("/test.txt", nullptr);
+ if (!file) return NO;
+
+ IoSeekFile(file, 50);
+ UInt64 pos = IoTellFile(file);
+ IoCloseFile(file);
+
+ return pos == 50;
+});
+
+KT_DECL_TEST(IoRewindFileValid, []() -> bool {
+ auto file = IoOpenFile("/test.txt", nullptr);
+ if (!file) return NO;
+
+ IoSeekFile(file, 100);
+ IoRewindFile(file);
+ UInt64 pos = IoTellFile(file);
+ IoCloseFile(file);
+
+ return pos == 0;
+});
+
+/// \note File read/write tests
+
+KT_DECL_TEST(IoWriteFileValid, []() -> bool {
+ auto file = IoOpenFile("/test_write.txt", nullptr);
+ if (!file) return NO;
+
+ const char data[] = "Test data";
+ UInt32 written = IoWriteFile(file, (VoidPtr) data, sizeof(data));
+ IoCloseFile(file);
+
+ return written == sizeof(data);
+});
+
+KT_DECL_TEST(IoReadFileValid, []() -> bool {
+ auto file = IoOpenFile("/test_read.txt", nullptr);
+ if (!file) return NO;
+
+ char buffer[64];
+ VoidPtr buf_ptr = buffer;
+ UInt32 read = IoReadFile(file, &buf_ptr, sizeof(buffer));
+ IoCloseFile(file);
+
+ return read > 0;
+});
+
+KT_DECL_TEST(IoWriteFileNull, []() -> bool {
+ auto file = IoOpenFile("/test.txt", nullptr);
+ if (!file) return NO;
+
+ UInt32 written = IoWriteFile(file, nullptr, 10);
+ IoCloseFile(file);
+
+ return written == 0;
+});
+
+/// \note File metadata tests
+
+KT_DECL_TEST(IoMimeFileValid, []() -> bool {
+ auto file = IoOpenFile("/test.txt", nullptr);
+ if (!file) return NO;
+
+ const Char* mime = IoMimeFile(file);
+ IoCloseFile(file);
+
+ return mime != nullptr;
+});
+
+KT_DECL_TEST(IoDimFileValid, []() -> bool {
+ auto file = IoOpenFile("/test_dir", nullptr);
+ if (!file) return NO;
+
+ const Char* dim = IoDimFile(file);
+ IoCloseFile(file);
+
+ return dim != nullptr;
+});
+
+/// \note File control tests
+
+KT_DECL_TEST(IoCtrlFileValid, []() -> bool {
+ auto file = IoOpenFile("/test.txt", nullptr);
+ if (!file) return NO;
+
+ char in_data[16] = {0};
+ char out_data[16] = {0};
+ SInt32 result = IoCtrlFile(file, 1, in_data, out_data);
+ IoCloseFile(file);
+
+ return result != 0;
+});
+
+/// \brief Run file I/O tests.
+SInt32 KT_TEST_MAIN() {
+ KT_RUN_TEST(IoOpenFileInvalid);
+ KT_RUN_TEST(IoOpenFileValidPath);
+ KT_RUN_TEST(IoCloseFileValid);
+
+ KT_RUN_TEST(IoSeekFileValid);
+ KT_RUN_TEST(IoTellFileValid);
+ KT_RUN_TEST(IoRewindFileValid);
+
+ KT_RUN_TEST(IoWriteFileValid);
+ KT_RUN_TEST(IoReadFileValid);
+ KT_RUN_TEST(IoWriteFileNull);
+
+ KT_RUN_TEST(IoMimeFileValid);
+ KT_RUN_TEST(IoDimFileValid);
+
+ KT_RUN_TEST(IoCtrlFileValid);
+
+ return KT_TEST_SUCCESS;
+}
diff --git a/test/libsystem_test/memory.test.cc b/test/libsystem_test/memory.test.cc
new file mode 100644
index 00000000..5083570c
--- /dev/null
+++ b/test/libsystem_test/memory.test.cc
@@ -0,0 +1,136 @@
+/// \file memory.test.cc
+/// \brief Memory Manager API tests.
+/// \author Amlal El Mahrouss (amlal at nekernel dot org)
+
+#include <libSystem/SystemKit/System.h>
+#include <public/frameworks/KernelTest.fwrk/headers/TestCase.h>
+
+/// \note Memory allocation tests
+
+KT_DECL_TEST(MmCreateHeapSuccess, []() -> bool {
+ auto heap = MmCreateHeap(1024, 0);
+ if (!heap) return NO;
+ MmDestroyHeap(heap);
+ return YES;
+});
+
+KT_DECL_TEST(MmCreateHeapZeroSize, []() -> bool {
+ auto heap = MmCreateHeap(0, 0);
+ return heap == nullptr;
+});
+
+KT_DECL_TEST(MmDestroyHeapValid, []() -> bool {
+ auto heap = MmCreateHeap(1024, 0);
+ if (!heap) return NO;
+ return MmDestroyHeap(heap) == 0;
+});
+
+KT_DECL_TEST(MmDestroyHeapNull, []() -> bool { return MmDestroyHeap(nullptr) != 0; });
+
+/// \note Memory operations tests
+
+KT_DECL_TEST(MmCopyMemoryNonOverlapping, []() -> bool {
+ char src[16] = "Hello, World!";
+ char dst[16] = {0};
+
+ auto result = MmCopyMemory(dst, src, 13);
+ if (!result) return NO;
+
+ return MmStrCmp(src, dst) == 0;
+});
+
+KT_DECL_TEST(MmCopyMemoryNull,
+ []() -> bool { return MmCopyMemory(nullptr, nullptr, 10) == nullptr; });
+
+KT_DECL_TEST(MmFillMemoryPattern, []() -> bool {
+ char buffer[16] = {0};
+ MmFillMemory(buffer, 16, 0xAA);
+
+ for (int i = 0; i < 16; i++) {
+ if ((unsigned char) buffer[i] != 0xAA) return NO;
+ }
+ return YES;
+});
+
+KT_DECL_TEST(MmFillMemoryNull, []() -> bool { return MmFillMemory(nullptr, 10, 0xFF) == nullptr; });
+
+KT_DECL_TEST(MmCmpMemoryEqual, []() -> bool {
+ char buf1[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+ char buf2[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+
+ return MmCmpMemory(buf1, buf2, 8) == 0;
+});
+
+KT_DECL_TEST(MmCmpMemoryNotEqual, []() -> bool {
+ char buf1[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+ char buf2[8] = {1, 2, 3, 9, 5, 6, 7, 8};
+
+ return MmCmpMemory(buf1, buf2, 8) != 0;
+});
+
+/// \note String operations tests
+
+KT_DECL_TEST(MmStrLenNonEmpty, []() -> bool {
+ const char* str = "Hello";
+ return MmStrLen(str) == 5;
+});
+
+KT_DECL_TEST(MmStrLenEmpty, []() -> bool {
+ const char* str = "";
+ return MmStrLen(str) == 0;
+});
+
+KT_DECL_TEST(MmStrLenNull, []() -> bool { return MmStrLen(nullptr) < 0; });
+
+KT_DECL_TEST(MmStrCmpEqual, []() -> bool { return MmStrCmp("test", "test") == 0; });
+
+KT_DECL_TEST(MmStrCmpNotEqual, []() -> bool { return MmStrCmp("test", "fest") != 0; });
+
+/// \note Heap flags tests
+
+KT_DECL_TEST(MmSetGetHeapFlags, []() -> bool {
+ auto heap = MmCreateHeap(1024, 0x01);
+ if (!heap) return NO;
+
+ MmSetHeapFlags(heap, 0x02);
+ UInt32 flags = MmGetHeapFlags(heap);
+
+ MmDestroyHeap(heap);
+ return flags == 0x02;
+});
+
+KT_DECL_TEST(MmFillCRC32HeapValid, []() -> bool {
+ auto heap = MmCreateHeap(1024, 0);
+ if (!heap) return NO;
+
+ UInt32 crc = MmFillCRC32Heap(heap);
+
+ MmDestroyHeap(heap);
+ return crc != 0;
+});
+
+/// \brief Run memory tests.
+SInt32 KT_TEST_MAIN() {
+ KT_RUN_TEST(MmCreateHeapSuccess);
+ KT_RUN_TEST(MmCreateHeapZeroSize);
+ KT_RUN_TEST(MmDestroyHeapValid);
+ KT_RUN_TEST(MmDestroyHeapNull);
+
+ KT_RUN_TEST(MmCopyMemoryNonOverlapping);
+ KT_RUN_TEST(MmCopyMemoryNull);
+ KT_RUN_TEST(MmFillMemoryPattern);
+ KT_RUN_TEST(MmFillMemoryNull);
+ KT_RUN_TEST(MmCmpMemoryEqual);
+ KT_RUN_TEST(MmCmpMemoryNotEqual);
+
+ KT_RUN_TEST(MmStrLenNonEmpty);
+ KT_RUN_TEST(MmStrLenEmpty);
+ KT_RUN_TEST(MmStrLenNull);
+ KT_RUN_TEST(MmStrCmpEqual);
+ KT_RUN_TEST(MmStrCmpNotEqual);
+
+ KT_RUN_TEST(MmSetGetHeapFlags);
+ KT_RUN_TEST(MmFillCRC32HeapValid);
+
+ return KT_TEST_SUCCESS;
+}
diff --git a/test/libsystem_test/thread.test.cc b/test/libsystem_test/thread.test.cc
new file mode 100644
index 00000000..ec8ccbad
--- /dev/null
+++ b/test/libsystem_test/thread.test.cc
@@ -0,0 +1,142 @@
+/// \file thread.test.cc
+/// \brief Threading API tests.
+/// \author Amlal El Mahrouss (amlal at nekernel dot org)
+
+#include <libSystem/SystemKit/System.h>
+#include <public/frameworks/KernelTest.fwrk/headers/TestCase.h>
+
+/// \note Thread procedure for testing
+static SInt32 test_thread_proc(SInt32 argc, Char** argv) {
+ return 0;
+}
+
+static SInt32 test_thread_proc_with_arg(SInt32 argc, Char** argv) {
+ if (argc > 0 && argv) {
+ return 1;
+ }
+ return 0;
+}
+
+/// \note Thread creation tests
+
+KT_DECL_TEST(ThrCreateThreadValid, []() -> bool {
+ auto thread = ThrCreateThread("test_thread", test_thread_proc, 0, 0);
+ if (!thread) return NO;
+ ThrJoinThread(thread);
+ return YES;
+});
+
+KT_DECL_TEST(ThrCreateThreadNull, []() -> bool {
+ auto thread = ThrCreateThread(nullptr, nullptr, 0, 0);
+ return thread == nullptr;
+});
+
+KT_DECL_TEST(ThrCreateThreadWithName, []() -> bool {
+ auto thread = ThrCreateThread("named_thread", test_thread_proc, 0, 0);
+ if (!thread) return NO;
+ ThrJoinThread(thread);
+ return YES;
+});
+
+/// \note Thread lifecycle tests
+
+KT_DECL_TEST(ThrJoinThreadValid, []() -> bool {
+ auto thread = ThrCreateThread("join_test", test_thread_proc, 0, 0);
+ if (!thread) return NO;
+
+ SInt32 result = ThrJoinThread(thread);
+ return result == 0;
+});
+
+KT_DECL_TEST(ThrDetachThreadValid, []() -> bool {
+ auto thread = ThrCreateThread("detach_test", test_thread_proc, 0, 0);
+ if (!thread) return NO;
+
+ SInt32 result = ThrDetachThread(thread);
+ return result == 0;
+});
+
+KT_DECL_TEST(ThrYieldThreadValid, []() -> bool {
+ auto thread = ThrCreateThread("yield_test", test_thread_proc, 0, 0);
+ if (!thread) return NO;
+
+ SInt32 result = ThrYieldThread(thread);
+ ThrJoinThread(thread);
+
+ return result == 0;
+});
+
+/// \note Thread exit tests
+
+KT_DECL_TEST(ThrExitThreadValid, []() -> bool {
+ auto thread = ThrCreateThread("exit_test", test_thread_proc, 0, 0);
+ if (!thread) return NO;
+
+ SInt32 result = ThrExitThread(thread, 0);
+ return result == 0;
+});
+
+KT_DECL_TEST(ThrExitThreadWithCode, []() -> bool {
+ auto thread = ThrCreateThread("exit_code_test", test_thread_proc, 0, 0);
+ if (!thread) return NO;
+
+ SInt32 result = ThrExitThread(thread, 42);
+ return result == 0;
+});
+
+/// \note Thread argument tests
+
+KT_DECL_TEST(ThrCreateThreadWithArgs, []() -> bool {
+ auto thread = ThrCreateThread("args_test", test_thread_proc_with_arg, 1, 0);
+ if (!thread) return NO;
+ ThrJoinThread(thread);
+ return YES;
+});
+
+KT_DECL_TEST(ThrCreateThreadMultiple, []() -> bool {
+ auto thread1 = ThrCreateThread("multi_test_1", test_thread_proc, 0, 0);
+ auto thread2 = ThrCreateThread("multi_test_2", test_thread_proc, 0, 0);
+
+ if (!thread1 || !thread2) return NO;
+
+ ThrJoinThread(thread1);
+ ThrJoinThread(thread2);
+
+ return YES;
+});
+
+/// \note Current thread tests
+
+KT_DECL_TEST(ThrExitCurrentThreadValid, []() -> bool {
+ // Note: Can't directly test this as it would exit the test thread
+ // This is a placeholder for integration testing
+ return YES;
+});
+
+KT_DECL_TEST(ThrExitMainThreadValid, []() -> bool {
+ // Note: Can't directly test this as it would exit the main thread
+ // This is a placeholder for integration testing
+ return YES;
+});
+
+/// \brief Run threading tests.
+SInt32 KT_TEST_MAIN() {
+ KT_RUN_TEST(ThrCreateThreadValid);
+ KT_RUN_TEST(ThrCreateThreadNull);
+ KT_RUN_TEST(ThrCreateThreadWithName);
+
+ KT_RUN_TEST(ThrJoinThreadValid);
+ KT_RUN_TEST(ThrDetachThreadValid);
+ KT_RUN_TEST(ThrYieldThreadValid);
+
+ KT_RUN_TEST(ThrExitThreadValid);
+ KT_RUN_TEST(ThrExitThreadWithCode);
+
+ KT_RUN_TEST(ThrCreateThreadWithArgs);
+ KT_RUN_TEST(ThrCreateThreadMultiple);
+
+ KT_RUN_TEST(ThrExitCurrentThreadValid);
+ KT_RUN_TEST(ThrExitMainThreadValid);
+
+ return KT_TEST_SUCCESS;
+}