diff options
author | dzwdz | 2023-08-14 18:51:07 +0200 |
---|---|---|
committer | dzwdz | 2023-08-14 18:51:07 +0200 |
commit | 642b5fb0007b64c77d186fcb018d571152ee1d47 (patch) | |
tree | 1c466461f3602d306be309a053edae558ef2568e /src/user/app/tests/kernel | |
parent | 8050069c57b729c18c19b1a03ab6e4bf63b4735e (diff) |
reorganization: first steps
Diffstat (limited to 'src/user/app/tests/kernel')
-rw-r--r-- | src/user/app/tests/kernel/fdlimit.c | 49 | ||||
-rw-r--r-- | src/user/app/tests/kernel/fs.c | 79 | ||||
-rw-r--r-- | src/user/app/tests/kernel/misc.c | 66 | ||||
-rw-r--r-- | src/user/app/tests/kernel/miscsyscall.c | 315 | ||||
-rw-r--r-- | src/user/app/tests/kernel/path.c | 108 | ||||
-rw-r--r-- | src/user/app/tests/kernel/threads.c | 55 |
6 files changed, 0 insertions, 672 deletions
diff --git a/src/user/app/tests/kernel/fdlimit.c b/src/user/app/tests/kernel/fdlimit.c deleted file mode 100644 index f332357..0000000 --- a/src/user/app/tests/kernel/fdlimit.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "../tests.h" -#include <camellia/flags.h> -#include <errno.h> -#include <unistd.h> - -static void test_fdlimit_pipe(void) { - hid_t ends[2]; - hid_t h[2] = {-1, -1}; - for (;;) { - hid_t cur = _sys_open("/", 1, OPEN_READ); - if (cur == -EMFILE) break; - test(cur >= 0); - h[0] = h[1]; - h[1] = cur; - } - test(h[0] >= 0); /* we need at least two handles */ - - test(_sys_pipe(ends, 0) == -EMFILE); - test(_sys_open("/", 1, OPEN_READ) == -EMFILE); - - close(h[1]); - test(_sys_pipe(ends, 0) == -EMFILE); - test(_sys_open("/", 1, OPEN_READ) == h[1]); - test(_sys_open("/", 1, OPEN_READ) == -EMFILE); - - close(h[0]); - close(h[1]); - test(_sys_pipe(ends, 0) == 0); -} - -static void test_fdlimit_fork(void) { - for (;;) { - hid_t cur = _sys_open("/", 1, OPEN_READ); - if (cur == -EMFILE) break; - test(cur >= 0); - } - - if (!_sys_fork(0, NULL)) _sys_exit(123); - - test(_sys_fork(FORK_NEWFS, NULL) == -EMFILE); - test(_sys_await() == 123); - test(_sys_await() == ~0); -} - -void r_k_fdlimit(void) { - /* all these tests implicitly test if the vfs returns -EMFILE */ - run_test(test_fdlimit_pipe); - run_test(test_fdlimit_fork); -} diff --git a/src/user/app/tests/kernel/fs.c b/src/user/app/tests/kernel/fs.c deleted file mode 100644 index b5684d7..0000000 --- a/src/user/app/tests/kernel/fs.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "../tests.h" -#include <camellia/flags.h> -#include <camellia/syscalls.h> -#include <stdbool.h> -#include <string.h> - -static void test_unfinished_req(void) { - hid_t h = -1; - int ret = _sys_fork(FORK_NEWFS, &h); - test(0 <= ret); - if (ret == 0) { - // TODO make a similar test with all 0s passed to fs_wait - struct ufs_request res; - _sys_fs_wait(NULL, 0, &res); - // TODO second fs_wait - exit(0); - } else { - test(0 <= h); - test(_sys_mount(h, "/", 1) == 0); - int ret = _sys_open("/", 1, 0); - test(ret < 0); - // the handler quits while handling that call - but this syscall should return anyways - } -} - -static void test_orphaned_fs(void) { - hid_t h = -1; - int ret = _sys_fork(FORK_NEWFS, &h); - test(0 <= ret); - if (ret == 0) { - exit(0); - } else { - test(0 <= h); - test(_sys_mount(h, "/", 1) == 0); - int ret = _sys_open("/", 1, 0); - test(ret < 0); - } -} - -static void test_fs_cleanup(void) { - const char *msg = "success"; - int msglen = 8; - char buf[16]; - hid_t ends[2]; - test(_sys_pipe(ends, 0) >= 0); - if (!_sys_fork(0, NULL)) { - hid_t h = -1; - if (_sys_fork(FORK_NEWFS, &h) == 0) { - for (;;) { - struct ufs_request req; - hid_t reqh = _sys_fs_wait(buf, sizeof buf, &req); - if (reqh < 0) break; - _sys_fs_respond(reqh, NULL, 0, 0); /* success */ - } - /* this is the test: does it break out of the loop - * when it should cleanup */ - _sys_write(ends[1], msg, msglen, -1, 0); - exit(0); - } else { - test(_sys_mount(h, "/", 1) == 0); - h = _sys_open("/", 1, 0); - test(h >= 0); - _sys_close(h); - // TODO another test without the delay - _sys_sleep(0); - exit(0); - } - } else { - test(_sys_read(ends[0], buf, sizeof buf, 0) == msglen); - test(memcmp(buf, msg, msglen) == 0); - } -} - -void r_k_fs(void) { - run_test(test_unfinished_req); - run_test(test_orphaned_fs); - run_test(test_fs_cleanup); - run_test(test_fs_cleanup); -} diff --git a/src/user/app/tests/kernel/misc.c b/src/user/app/tests/kernel/misc.c deleted file mode 100644 index 5d6b531..0000000 --- a/src/user/app/tests/kernel/misc.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "../tests.h" -#include <camellia/errno.h> -#include <camellia/flags.h> -#include <camellia/syscalls.h> -#include <string.h> -#include <unistd.h> - -static void test_fault_kill(void) { - if (!fork()) { /* invalid memory access */ - asm volatile("movb $69, 0" ::: "memory"); - test_fail(); - } - if (!fork()) { /* #GP */ - asm volatile("hlt" ::: "memory"); - test_fail(); - } - - int await_cnt = 0; - while (_sys_await() != ~0) await_cnt++; - test(await_cnt == 2); -} - -static void test_efault(void) { -#if 0 - const char *str = "o, 16 characters"; - char str2[16]; - char *invalid = (void*)0x1000; - hid_t h; - - memcpy(str2, str, 16); - - test((h = _sys_open(TMPFILEPATH, strlen(TMPFILEPATH), OPEN_CREATE | OPEN_WRITE)) >= 0); - test(_sys_write(h, str, 16, 0, 0) == 16); - test(_sys_write(h, str2, 16, 0, 0) == 16); - - test(_sys_write(h, invalid, 16, 0, 0) == -EFAULT); - - /* x64 non-canonical pointers */ - test(_sys_write(h, (void*)((uintptr_t)str ^ 0x8000000000000000), 16, 0, 0) == -EFAULT); - test(_sys_write(h, (void*)((uintptr_t)str ^ 0x1000000000000000), 16, 0, 0) == -EFAULT); - test(_sys_write(h, (void*)((uintptr_t)str ^ 0x0100000000000000), 16, 0, 0) == -EFAULT); - test(_sys_write(h, (void*)((uintptr_t)str ^ 0x0010000000000000), 16, 0, 0) == -EFAULT); - test(_sys_write(h, (void*)((uintptr_t)str ^ 0x0001000000000000), 16, 0, 0) == -EFAULT); - test(_sys_write(h, (void*)((uintptr_t)str ^ 0x0000800000000000), 16, 0, 0) == -EFAULT); - - test(_sys_write(h, (void*)((uintptr_t)str2 ^ 0x8000000000000000), 16, 0, 0) == -EFAULT); - test(_sys_write(h, (void*)((uintptr_t)str2 ^ 0x1000000000000000), 16, 0, 0) == -EFAULT); - test(_sys_write(h, (void*)((uintptr_t)str2 ^ 0x0100000000000000), 16, 0, 0) == -EFAULT); - test(_sys_write(h, (void*)((uintptr_t)str2 ^ 0x0010000000000000), 16, 0, 0) == -EFAULT); - test(_sys_write(h, (void*)((uintptr_t)str2 ^ 0x0001000000000000), 16, 0, 0) == -EFAULT); - test(_sys_write(h, (void*)((uintptr_t)str2 ^ 0x0000800000000000), 16, 0, 0) == -EFAULT); - - test(_sys_write(h, str, 16, 0, 0) == 16); - close(h); -#endif -} - -static void test_invalid_syscall(void) { - test(_syscall(~0, 0, 0, 0, 0, 0) < 0); -} - -void r_k_misc(void) { - run_test(test_fault_kill); - run_test(test_efault); - run_test(test_invalid_syscall); -} diff --git a/src/user/app/tests/kernel/miscsyscall.c b/src/user/app/tests/kernel/miscsyscall.c deleted file mode 100644 index 459da2a..0000000 --- a/src/user/app/tests/kernel/miscsyscall.c +++ /dev/null @@ -1,315 +0,0 @@ -#include "../tests.h" -#include <camellia/errno.h> -#include <camellia/execbuf.h> -#include <camellia/flags.h> -#include <camellia/syscalls.h> -#include <string.h> -#include <unistd.h> - - -static void test_await(void) { - /* creates 16 child processes, each returning a different value. then checks - * if await() returns every value exactly once */ - int ret; - int counts[16] = {0}; - - for (int i = 0; i < 16; i++) - if (!fork()) - exit(i); - - while ((ret = _sys_await()) != ~0) { - test(0 <= ret && ret < 16); - counts[ret]++; - } - - for (int i = 0; i < 16; i++) - test(counts[i] == 1); -} - -static void test_await2(void) { - /* hangs on failure */ - if (!fork()) { - if (!fork()) { - for (;;) _sys_sleep(1000000000); - } else { - exit(123); - } - } - test(_sys_await() == 123); - test(_sys_await() == ~0); /* don't wait for tombstone */ - _sys_filicide(); -} - -static void test_wait2_basic(void) { - struct sys_wait2 data = {0}; - int pid; - pid = fork(); - if (pid == 0) { - exit(420); - } - test(_sys_wait2(-1, 0, &data) == pid); - test(data.status == 420); - test(_sys_wait2(-1, 0, NULL) == -ECHILD); -} - -static void test_pipe(void) { - const char *pipe_msgs[2] = {"hello", "world"}; - hid_t ends[2]; - char buf[16]; - - /* test regular reads / writes */ - test(_sys_pipe(ends, 0) >= 0); - if (!fork()) { - /* those repeated asserts ensure that you can't read/write to the wrong ends */ - test(_sys_read(ends[1], buf, 16, 0) < 0); - test(_sys_write(ends[0], buf, 16, 0, 0) < 0); - - test(5 == _sys_write(ends[1], pipe_msgs[0], 5, -1, 0)); - - test(_sys_read(ends[1], buf, 16, 0) < 0); - test(_sys_write(ends[0], buf, 16, 0, 0) < 0); - - test(5 == _sys_write(ends[1], pipe_msgs[1], 5, -1, 0)); - - exit(0); - } else { - test(_sys_read(ends[1], buf, 16, 0) < 0); - test(_sys_write(ends[0], buf, 16, 0, 0) < 0); - - test(5 == _sys_read(ends[0], buf, 16, 0)); - test(!memcmp(buf, pipe_msgs[0], 5)); - - test(_sys_read(ends[1], buf, 16, 0) < 0); - test(_sys_write(ends[0], buf, 16, 0, 0) < 0); - - test(5 == _sys_read(ends[0], buf, 16, 0)); - test(!memcmp(buf, pipe_msgs[1], 5)); - - _sys_await(); - } - close(ends[0]); - close(ends[1]); - - - /* writing to pipes with one end closed */ - test(_sys_pipe(ends, 0) >= 0); - for (int i = 0; i < 16; i++) { - if (!fork()) { - close(ends[1]); - test(_sys_read(ends[0], buf, 16, 0) < 0); - exit(0); - } - } - close(ends[1]); - for (int i = 0; i < 16; i++) - _sys_await(); - close(ends[0]); - - test(_sys_pipe(ends, 0) >= 0); - for (int i = 0; i < 16; i++) { - if (!fork()) { - close(ends[0]); - test(_sys_write(ends[1], buf, 16, 0, 0) < 0); - exit(0); - } - } - close(ends[0]); - for (int i = 0; i < 16; i++) - _sys_await(); - close(ends[1]); - - - /* queueing */ - test(_sys_pipe(ends, 0) >= 0); - for (int i = 0; i < 16; i++) { - if (!fork()) { - test(_sys_write(ends[1], pipe_msgs[0], 5, -1, 0) == 5); - exit(0); - } - } - close(ends[1]); - for (int i = 0; i < 16; i++) { - test(_sys_read(ends[0], buf, sizeof buf, 0) == 5); - _sys_await(); - } - test(_sys_read(ends[0], buf, sizeof buf, 0) < 0); - close(ends[0]); - - test(_sys_pipe(ends, 0) >= 0); - for (int i = 0; i < 16; i++) { - if (!fork()) { - memset(buf, 0, sizeof buf); - test(_sys_read(ends[0], buf, 5, -1) == 5); - test(!memcmp(buf, pipe_msgs[1], 5)); - exit(0); - } - } - close(ends[0]); - for (int i = 0; i < 16; i++) { - test(_sys_write(ends[1], pipe_msgs[1], 5, -1, 0) == 5); - _sys_await(); - } - test(_sys_write(ends[1], pipe_msgs[1], 5, -1, 0) < 0); - close(ends[1]); - - - // not a to.do detect when all processes that can read are stuck on writing to the pipe and vice versa - // it seems like linux just lets the process hang endlessly. -} - -static void test_memflag(void) { - void *page = (void*)0x77777000; - _sys_memflag(page, 4096, MEMFLAG_PRESENT); // allocate page - memset(page, 77, 4096); // write to it - _sys_memflag(page, 4096, 0); // free it - - if (!fork()) { - memset(page, 11, 4096); // should segfault - exit(0); - } else { - test(_sys_await() != 0); // test if the process crashed - } - - char *pages[4]; - for (size_t i = 0; i < 4; i++) { - pages[i] = _sys_memflag(NULL, 4096, MEMFLAG_FINDFREE); - test(pages[i] == _sys_memflag(NULL, 4096, MEMFLAG_FINDFREE | MEMFLAG_PRESENT)); - if (i > 0) test(pages[i] != pages[i-1]); - *pages[i] = 0x77; - } - - for (size_t i = 0; i < 4; i++) - _sys_memflag(pages, 4096, MEMFLAG_PRESENT); -} - -static void test_dup(void) { - hid_t pipe[2]; - hid_t h1, h2; - test(_sys_pipe(pipe, 0) >= 0); - - if (!fork()) { - close(pipe[0]); - - h1 = _sys_dup(pipe[1], -1, 0); - test(h1 >= 0); - test(h1 != pipe[1]); - h2 = _sys_dup(h1, -1, 0); - test(h2 >= 0); - test(h2 != pipe[1] && h2 != h1); - - _sys_write(pipe[1], "og", 2, 0, 0); - _sys_write(h1, "h1", 2, 0, 0); - _sys_write(h2, "h2", 2, 0, 0); - - close(pipe[1]); - _sys_write(h1, "h1", 2, 0, 0); - _sys_write(h2, "h2", 2, 0, 0); - - test(_sys_dup(h1, pipe[1], 0) == pipe[1]); - test(_sys_dup(h2, pipe[1], 0) == pipe[1]); - test(_sys_dup(h1, pipe[1], 0) == pipe[1]); - test(_sys_dup(h2, pipe[1], 0) == pipe[1]); - close(h1); - close(h2); - - test(_sys_dup(pipe[1], h2, 0) == h2); - _sys_write(h2, "h2", 2, 0, 0); - close(h2); - - test(_sys_dup(pipe[1], h1, 0) == h1); - _sys_write(h1, "h1", 2, 0, 0); - close(h1); - - exit(0); - } else { - char buf[16]; - size_t count = 0; - close(pipe[1]); - while (_sys_read(pipe[0], buf, sizeof buf, 0) >= 0) - count++; - test(count == 7); - _sys_await(); - } - - - close(pipe[0]); -} - -static void test_execbuf(void) { - if (!fork()) { - uint64_t buf[] = { - EXECBUF_SYSCALL, _SYS_EXIT, 123, 0, 0, 0, 0, - }; - _sys_execbuf(buf, sizeof buf); - test_fail(); - } else { - test(_sys_await() == 123); - } -} - -static void test_sleep(void) { - hid_t reader; - FILE *writer; - if (!forkpipe(&writer, &reader)) { - if (!fork()) { - if (!fork()) { - _sys_sleep(100); - fprintf(writer, "1"); - _sys_sleep(200); - fprintf(writer, "3"); - _sys_sleep(200); - fprintf(writer, "5"); - _sys_exit(0); - } - if (!fork()) { - fprintf(writer, "0"); - _sys_sleep(200); - fprintf(writer, "2"); - _sys_sleep(200); - fprintf(writer, "4"); - /* get killed while asleep - * a peaceful death, i suppose. */ - for (;;) _sys_sleep(1000000000); - } - _sys_await(); - _sys_filicide(); - _sys_exit(0); - } - - /* this part checks if, after killing an asleep process, - * other processes can still wake up */ - _sys_sleep(600); - fprintf(writer, "6"); - exit(0); - } else { - const char *expected = "0123456"; - size_t target = strlen(expected); - size_t pos = 0; - for (;;) { - char buf[128]; - long ret = _sys_read(reader, buf, sizeof buf, 0); - if (ret < 0) break; - test(pos + ret <= target); - test(memcmp(buf, expected + pos, ret) == 0); - pos += ret; - } - test(pos == target); - } -} - -static void test_badopen(void) { - test(_sys_open(TMPFILEPATH, strlen(TMPFILEPATH), OPEN_CREATE | OPEN_WRITE) >= 0); - test(_sys_open(TMPFILEPATH, strlen(TMPFILEPATH), OPEN_CREATE) == -EINVAL); -} - -void r_k_miscsyscall(void) { - run_test(test_await); - run_test(test_await2); - run_test(test_wait2_basic); - run_test(test_pipe); - run_test(test_memflag); - run_test(test_dup); - run_test(test_execbuf); - run_test(test_sleep); - run_test(test_badopen); -} diff --git a/src/user/app/tests/kernel/path.c b/src/user/app/tests/kernel/path.c deleted file mode 100644 index 5a22c36..0000000 --- a/src/user/app/tests/kernel/path.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "../tests.h" -#include <camellia/path.h> -#include <string.h> -#include <camellia/compat.h> -#include <camellia/fs/misc.h> - -static void test_path_simplify(void) { - const char *testcases[][2] = { - {"/", "/"}, - {"/.", "/"}, - {"//", "/"}, - {"/asdf", "/asdf"}, - {"/asdf/", "/asdf/"}, - {"/asdf//", "/asdf/"}, - {"/asdf/./", "/asdf/"}, - {"/a/./b", "/a/b"}, - {"/a/./b/", "/a/b/"}, - - // some slightly less easy cases - {"/asdf/..", "/"}, - {"/asdf/../", "/"}, - {"/asdf/.", "/asdf/"}, - {"/asdf//.", "/asdf/"}, - - {"/foo/bar/..", "/foo/"}, - {"/foo/bar/../baz", "/foo/baz"}, - {"/foo/bar/../baz/", "/foo/baz/"}, - {"/foo/bar/xyz/..", "/foo/bar/"}, - {"/foo/bar/xyz/../", "/foo/bar/"}, - - // going under the root or close to it - {"/..", NULL}, - {"/../asdf", NULL}, - {"/../asdf/", NULL}, - {"/./a/../..", NULL}, - {"/a/a/../..", "/"}, - {"/a/../a/..", "/"}, - {"/a/../../a", NULL}, - {"/../a/../a", NULL}, - {"/../../a/a", NULL}, - {"/////../..", NULL}, - {"//a//../..", NULL}, - - // relative paths aren't allowed - {"relative", NULL}, - {"some/stuff", NULL}, - {"./stuff", NULL}, - {"../stuff", NULL}, - {"", NULL}, - }; - - char buf[256]; - for (size_t i = 0; i < sizeof(testcases) / sizeof(testcases[0]); i++) { - const char *input = testcases[i][0]; - const char *expected = testcases[i][1]; - int len = path_simplify(input, buf, strlen(input)); - if (expected == NULL) { - test(len == 0); - } else { - // TODO an argument for printing info on test failure - test(len == (int)strlen(expected) && !memcmp(expected, buf, len)); - } - } -} - -static void mount_resolve_drv(const char *path) { - if (mount_at(path) != 0) return; - - struct ufs_request res; - while (!c0_fs_wait(NULL, 0, &res)) { - // TODO does the first argument of c0_fs_respond need to be non-const? - c0_fs_respond((void*)path, strlen(path), 0); - } - exit(1); -} - -static void test_mount_resolve(void) { - const char *testcases[][2] = { - {"/", "/"}, - {"/test", "/"}, - {"/dir", "/dir"}, - {"/dir/..", "/"}, - {"/dir/../dir", "/dir"}, - {"/dirry", "/"}, - {"/dir/", "/dir"}, - {"/dir/shadowed", "/dir"}, - {"/dir/shadowed/", "/dir"}, - }; - mount_resolve_drv("/"); - mount_resolve_drv("/dir/shadowed"); - mount_resolve_drv("/dir"); - - char buf[16]; - for (size_t i = 0; i < sizeof(testcases) / sizeof(testcases[0]); i++) { - const char *input = testcases[i][0]; - const char *expected = testcases[i][1]; - hid_t h = _sys_open(input, strlen(input), 0); - test(h >= 0); - int len = _sys_read(h, buf, sizeof buf, 0); - test(len == (int)strlen(expected) && !memcmp(expected, buf, len)); - _sys_close(h); - } -} - -void r_k_path(void) { - run_test(test_path_simplify); - run_test(test_mount_resolve); -} diff --git a/src/user/app/tests/kernel/threads.c b/src/user/app/tests/kernel/threads.c deleted file mode 100644 index b3c1c06..0000000 --- a/src/user/app/tests/kernel/threads.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "../tests.h" -#include <camellia/flags.h> -#include <camellia/syscalls.h> -#include <string.h> -#include <esemaphore.h> -#include <thread.h> - -int global_n; -static void basic_thread(void *sem) { - global_n = 10; - esem_signal(sem); -} -static void test_basic_thread(void) { - struct evil_sem *sem = esem_new(0); - global_n = 0; - thread_create(FORK_NOREAP, basic_thread, sem); - esem_wait(sem); - test(global_n == 10); -} - -hid_t global_h; -static void shared_handle(void *sem) { - hid_t ends[2]; - test(_sys_pipe(ends, 0) >= 0); - global_h = ends[0]; - esem_signal(sem); - _sys_write(ends[1], "Hello!", 7, -1, 0); -} -static void test_shared_handle(void) { - struct evil_sem *sem = esem_new(0); - char buf[16]; - global_h = -1; - thread_create(FORK_NOREAP, shared_handle, sem); - esem_wait(sem); - - test(global_h >= 0); - test(_sys_read(global_h, buf, sizeof buf, 0) == 7); - test(!strcmp("Hello!", buf)); -} - -static void many_thread(void *arg) { - *(uint64_t*)arg += 10; -} -static void test_many_threads(void) { - uint64_t n = 0; - for (int i = 0; i < 10; i++) thread_create(0, many_thread, &n); - for (int i = 0; i < 10; i++) _sys_await(); - test(n == 100); -} - -void r_k_threads(void) { - run_test(test_basic_thread); - run_test(test_shared_handle); - run_test(test_many_threads); -} |