summaryrefslogtreecommitdiffhomepage
path: root/test/libsystem_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/libsystem_test
parentaf944082df5844cf3215dc9dd4960aeedd18bd75 (diff)
feat: test add more tests.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'test/libsystem_test')
-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
3 files changed, 433 insertions, 0 deletions
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;
+}