diff options
Diffstat (limited to 'src/user/app/tests')
-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 | ||||
-rw-r--r-- | src/user/app/tests/libc/esemaphore.c | 95 | ||||
-rw-r--r-- | src/user/app/tests/libc/setjmp.c | 31 | ||||
-rw-r--r-- | src/user/app/tests/libc/string.c | 124 | ||||
-rw-r--r-- | src/user/app/tests/shared/printf.c | 55 | ||||
-rw-r--r-- | src/user/app/tests/shared/ringbuf.c | 49 | ||||
-rw-r--r-- | src/user/app/tests/stress.c | 28 | ||||
-rw-r--r-- | src/user/app/tests/tests.c | 68 | ||||
-rw-r--r-- | src/user/app/tests/tests.h | 37 |
14 files changed, 0 insertions, 1159 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); -} diff --git a/src/user/app/tests/libc/esemaphore.c b/src/user/app/tests/libc/esemaphore.c deleted file mode 100644 index f089f4f..0000000 --- a/src/user/app/tests/libc/esemaphore.c +++ /dev/null @@ -1,95 +0,0 @@ -#include "../tests.h" -#include <camellia/flags.h> -#include <camellia/syscalls.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <esemaphore.h> - -static void odd(hid_t out, struct evil_sem *sem1, struct evil_sem *sem2) { - _sys_write(out, "1", 1, -1, 0); - esem_signal(sem1); - - esem_wait(sem2); - _sys_write(out, "3", 1, -1, 0); - esem_signal(sem1); - - esem_wait(sem2); - _sys_write(out, "5", 1, -1, 0); - esem_signal(sem1); -} - -static void even(hid_t out, struct evil_sem *sem1, struct evil_sem *sem2) { - esem_wait(sem1); - _sys_write(out, "2", 1, -1, 0); - esem_signal(sem2); - - esem_wait(sem1); - _sys_write(out, "4", 1, -1, 0); - esem_signal(sem2); - - esem_wait(sem1); - _sys_write(out, "6", 1, -1, 0); - esem_signal(sem2); -} - -static void test_semaphore(void) { - struct evil_sem *sem1, *sem2; - hid_t pipe[2]; - test(_sys_pipe(pipe, 0) >= 0); - - if (!fork()) { - sem1 = esem_new(0); - sem2 = esem_new(0); - test(sem1 && sem2); - if (!fork()) { - odd(pipe[1], sem1, sem2); - exit(69); - } else { - even(pipe[1], sem1, sem2); - test(_sys_await() == 69); - } - esem_free(sem1); - esem_free(sem2); - - _sys_write(pipe[1], "|", 1, -1, 0); - - sem1 = esem_new(0); - sem2 = esem_new(0); - test(sem1 && sem2); - if (!fork()) { - even(pipe[1], sem1, sem2); - exit(69); - } else { - odd(pipe[1], sem1, sem2); - test(_sys_await() == 69); - _sys_await(); - } - esem_free(sem1); - esem_free(sem2); - - _sys_filicide(); - exit(0); - } else { - close(pipe[1]); - - char buf[16]; - size_t pos = 0; - for (;;) { - int ret = _sys_read(pipe[0], buf + pos, sizeof(buf) - pos, 0); - if (ret < 0) break; - pos += ret; - } - buf[pos] = '\0'; // idc about the "potential" overflow - if (strcmp(buf, "123456|123456")) { - printf("%s\n", buf); - test_fail(); - } - - _sys_await(); - } -} - -void r_libc_esemaphore(void) { - run_test(test_semaphore); -} diff --git a/src/user/app/tests/libc/setjmp.c b/src/user/app/tests/libc/setjmp.c deleted file mode 100644 index 0dded9d..0000000 --- a/src/user/app/tests/libc/setjmp.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "../tests.h" -#include <stdbool.h> -#include <setjmp.h> - -static void test_setjmp(void) { - jmp_buf env; - volatile bool inner; - int val; - inner = false; - if (!(val = setjmp(env))) { - inner = true; - longjmp(env, 1234); - test(0); - } else { - test(val == 1234); - test(inner); - } - inner = false; - if (!(val = setjmp(env))) { - inner = true; - longjmp(env, 0); - test(0); - } else { - test(val == 1); - test(inner); - } -} - -void r_libc_setjmp(void) { - run_test(test_setjmp); -} diff --git a/src/user/app/tests/libc/string.c b/src/user/app/tests/libc/string.c deleted file mode 100644 index 6afe350..0000000 --- a/src/user/app/tests/libc/string.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "../tests.h" -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> - -static void test_memcmp(void) { - test(0 == memcmp("some", "thing", 0)); - test(0 != memcmp("some", "thing", 1)); - test(0 != memcmp("some", "thing", 4)); - - test(0 == memcmp("test", "tennis", 0)); - test(0 == memcmp("test", "tennis", 1)); - test(0 == memcmp("test", "tennis", 2)); - test(0 != memcmp("test", "tennis", 3)); - test(0 != memcmp("test", "tennis", 4)); - test(0 != memcmp("test", "tennis", 5)); - - test(0 > memcmp("foo", "moo", 4)); - test(0 < memcmp("moo", "foo", 4)); - test(0 > memcmp("555", "654", 3)); - test(0 < memcmp("654", "555", 3)); -} - -static bool memall(const unsigned char *s, unsigned char c, size_t n) { - for (size_t i = 0; i < n; i++) - if (s[i] != c) return false; - return true; -} - -static void test_memset(void) { - const size_t buflen = 4096; - void *buf = malloc(buflen); - test(buf); - for (int i = 0; i < 257; i++) { - memset(buf, i, buflen); - test(memall(buf, i & 0xff, buflen)); - } - free(buf); -} - -static void test_memmove(void) { - const int partsize = 64; - char buf[partsize * 3]; - for (int i = 0; i < partsize * 2; i++) { - memset(buf, 0, sizeof buf); - for (int j = 0; j < partsize; j++) buf[i + j] = j; - memmove(buf + partsize, buf + i, partsize); - for (int j = 0; j < partsize; j++) test(buf[partsize + j] == j); - } -} - -static void test_strcmp(void) { - test(0 == strcmp("string", "string")); - test(0 > strcmp("str", "string")); - test(0 < strcmp("string", "str")); - - test(0 != strcmp("stress", "string")); - - test(0 != strncmp("abc", "ab", 3)); - test(0 == strncmp("abc", "ab", 2)); -} - -static void test_strtol(void) { - char *end; - test(1234 == strtol("1234", NULL, 10)); - test(1234 == strtol("+1234", NULL, 10)); - test(-1234 == strtol("-1234", NULL, 10)); - - test(1234 == strtol("1234", &end, 10)); - test(!strcmp("", end)); - test(1234 == strtol(" 1234hello", &end, 10)); - test(!strcmp("hello", end)); - - test(1234 == strtol(" 1234hello", &end, 0)); - test(!strcmp("hello", end)); - test(0xCAF3 == strtol(" 0xCaF3hello", &end, 0)); - test(!strcmp("hello", end)); - test(01234 == strtol(" 01234hello", &end, 0)); - test(!strcmp("hello", end)); -} - -static void test_strspn(void) { - test(0 == strspn("", "1234")); - test(0 == strspn("asdf", "1234")); - test(0 == strspn("a2df", "1234")); - test(2 == strspn("42df", "1234")); - test(4 == strspn("4211", "1234")); - - test(0 == strcspn("", "1234")); - test(4 == strcspn("asdf", "1234")); - test(1 == strcspn("a2df", "1234")); -} - -static void test_strtok(void) { - const char *sep = " \t"; - { - char line[] = "LINE TO BE SEPARATED"; - test(!strcmp(strtok(line, sep), "LINE")); - test(!strcmp(strtok(NULL, sep), "TO")); - test(!strcmp(strtok(NULL, sep), "BE")); - test(!strcmp(strtok(NULL, sep), "SEPARATED")); - for (int i = 0; i < 4; i++) - test(strtok(NULL, sep) == NULL); - } - { - char line[] = " LINE TO\tBE \t SEPARATED "; - test(!strcmp(strtok(line, sep), "LINE")); - test(!strcmp(strtok(NULL, sep), "TO")); - test(!strcmp(strtok(NULL, sep), "BE")); - test(!strcmp(strtok(NULL, sep), "SEPARATED")); - for (int i = 0; i < 4; i++) - test(strtok(NULL, sep) == NULL); - } -} - -void r_libc_string(void) { - run_test(test_memcmp); - run_test(test_memset); - run_test(test_memmove); - run_test(test_strcmp); - run_test(test_strtol); - run_test(test_strspn); - run_test(test_strtok); -} diff --git a/src/user/app/tests/shared/printf.c b/src/user/app/tests/shared/printf.c deleted file mode 100644 index d8df48a..0000000 --- a/src/user/app/tests/shared/printf.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "../tests.h" -#include <stdio.h> -#include <string.h> - -#pragma GCC diagnostic ignored "-Wformat-truncation" - -static void test_printf(void) { - char buf[64]; - memset(buf, '?', 64); - - /* test proper overflow handling in snprintf */ - test(13 == snprintf(buf, 15, "That's 0x%x", 0x1337)); - test(!memcmp(buf, "That's 0x1337\0??", 16)); - test(17 == snprintf(buf, 15, "%05x %05x %05x", 0, 0, 0)); - test(!memcmp(buf, "00000 00000 00\0?", 16)); - - /* all the other stuff */ - snprintf(buf, sizeof buf, "%010x", 0x1BABE); - test(!strcmp(buf, "000001babe")); - snprintf(buf, sizeof buf, "%10x", 0x1BABE); - test(!strcmp(buf, " 1babe")); - snprintf(buf, sizeof buf, "%10s", "hello"); - test(!strcmp(buf, " hello")); - - snprintf(buf, sizeof buf, "%s%%%s", "ab", "cd"); - test(!strcmp(buf, "ab%cd")); - - snprintf(buf, sizeof buf, "%05u,%05u", 1234, 56789); - test(!strcmp(buf, "01234,56789")); - - snprintf(buf, sizeof buf, "%5d,%5d", 123, 4567); - test(!strcmp(buf, " 123, 4567")); - snprintf(buf, sizeof buf, "%5d,%5d", -123, -4567); - test(!strcmp(buf, " -123,-4567")); - - snprintf(buf, sizeof buf, "%u,%d,%x", 0, 0, 0); - test(!strcmp(buf, "0,0,0")); - - /* precision */ - snprintf(buf, sizeof buf, "%5.2u,%5.2d,%5.2x", 0, 0, 0); - test(!strcmp(buf, " 00, 00, 00")); - snprintf(buf, sizeof buf, "%5.2u,%5.2d,%5.2x", 10, -10, 0x10); - test(!strcmp(buf, " 10, -10, 10")); - snprintf(buf, sizeof buf, "%5.3d", -1); - test(!strcmp(buf, " -001")); - snprintf(buf, sizeof buf, "%.5d", 123); - test(!strcmp(buf, "00123")); - - snprintf(buf, sizeof buf, "%.1s,%.10s,%.*s", "hello", "hello", 3, "hello"); - test(!strcmp(buf, "h,hello,hel")); -} - -void r_s_printf(void) { - run_test(test_printf); -} diff --git a/src/user/app/tests/shared/ringbuf.c b/src/user/app/tests/shared/ringbuf.c deleted file mode 100644 index d2a35a1..0000000 --- a/src/user/app/tests/shared/ringbuf.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "../tests.h" -#include <shared/ring.h> -#include <string.h> - -static void test_ringbuf(void) { - char backbuf[16], cmpbuf[16]; - size_t num_read = 0, num_written = 0; - uint8_t c; - - ring_t r = {backbuf, 16, 0, 0}; - - /* aliasing */ - for (size_t i = 0; i < 16; i++) { - test(ring_used(&r) == 0); - test(ring_avail(&r) == 16); - ring_put(&r, "11 bytes...", 11); - test(ring_used(&r) == 11); - test(ring_avail(&r) == 5); - - memset(cmpbuf, 0, sizeof cmpbuf); - test(ring_get(&r, cmpbuf, 16) == 11); - test(memcmp(cmpbuf, "11 bytes...", 11) == 0); - } - - test(ring_used(&r) == 0); - for (size_t i = 0; i < 7; i++) - ring_put1b(&r, num_written++); - test(ring_used(&r) == 7); - for (size_t i = 0; i < 3; i++) { - ring_get(&r, &c, 1); - test(num_read++ == c); - } - test(ring_used(&r) == 4); - - for (size_t j = 0; j < 40; j++) { - for (size_t i = 0; i < 7; i++) - ring_put1b(&r, num_written++ & 0xff); - test(ring_used(&r) == 11); - for (size_t i = 0; i < 7; i++) { - ring_get(&r, &c, 1); - test((num_read++ & 0xff) == c); - } - test(ring_used(&r) == 4); - } -} - -void r_s_ringbuf(void) { - run_test(test_ringbuf); -} diff --git a/src/user/app/tests/stress.c b/src/user/app/tests/stress.c deleted file mode 100644 index 1ef018c..0000000 --- a/src/user/app/tests/stress.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "tests.h" -#include <camellia/flags.h> -#include <camellia/syscalls.h> -#include <stdlib.h> -#include <unistd.h> - -static void run_forked(void (*fn)()) { - if (!fork()) { - fn(); - exit(0); - } else { - /* successful tests must return 0 - * TODO add a better fail msg */ - if (_sys_await() != 0) test_fail(); - } -} - - -static void stress_fork(void) { - for (size_t i = 0; i < 2048; i++) { - if (!fork()) exit(0); - _sys_await(); - } -} - -void stress_all(void) { - run_forked(stress_fork); -} diff --git a/src/user/app/tests/tests.c b/src/user/app/tests/tests.c deleted file mode 100644 index 5cba682..0000000 --- a/src/user/app/tests/tests.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "tests.h" -#include <camellia/syscalls.h> -#include <unistd.h> - -__attribute__((visibility("hidden"))) -extern char __executable_start[]; - -FILE *fail_trig; - -void run_test(void (*fn)()) { - if (!fork()) { - fn(); - _sys_filicide(); - exit(0); - } else { - /* successful tests must return 0 */ - if (_sys_await() != 0) { - test_failf("%p, base %p", (void*)((void*)fn - (void*)__executable_start), __executable_start); - } - } -} - -int forkpipe(FILE **f, hid_t *h) { - hid_t ends[2]; - if (_sys_pipe(ends, 0) < 0) { - fprintf(stderr, "couldn't create pipe\n"); - exit(1); - } - int ret = fork(); - if (!ret) { - close(ends[0]); - *f = fdopen(ends[1], "w"); - *h = -1; - } else { - close(ends[1]); - *f = NULL; - *h = ends[0]; - } - return ret; -} - -int main(void) { - hid_t reader; - if (!forkpipe(&fail_trig, &reader)) { - r_k_miscsyscall(); - r_k_fs(); - r_k_fdlimit(); - r_k_misc(); - r_k_path(); - r_k_threads(); - r_libc_esemaphore(); - r_libc_setjmp(); - r_libc_string(); - r_s_printf(); - r_s_ringbuf(); - exit(0); - } else { - for (;;) { - char buf[128]; - long ret = _sys_read(reader, buf, sizeof buf, 0); - if (ret < 0) break; - printf("\033[31mFAIL\033[0m "); - fwrite(buf, ret, 1, stdout); - printf("\n"); - } - } - return 0; -} diff --git a/src/user/app/tests/tests.h b/src/user/app/tests/tests.h deleted file mode 100644 index 5037e1a..0000000 --- a/src/user/app/tests/tests.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include <camellia/syscalls.h> -#include <stdio.h> -#include <stdlib.h> - -#define TMPFILEPATH "/tmp/.test_internal" - -void run_test(void (*fn)()); - -void r_k_fdlimit(void); -void r_k_fs(void); -void r_k_misc(void); -void r_k_miscsyscall(void); -void r_k_path(void); -void r_k_threads(void); -void r_libc_esemaphore(void); -void r_libc_setjmp(void); -void r_libc_string(void); -void r_s_printf(void); -void r_s_ringbuf(void); - -extern FILE *fail_trig; - -int forkpipe(FILE **f, hid_t *h); - -#define argify(str) str, sizeof(str) - 1 -#define test_fail() do { \ - fprintf(fail_trig, "%s():%u", __func__, __LINE__); \ - fflush(fail_trig); \ - exit(0); \ -} while (0) -#define test_failf(fmt, ...) do { \ - fprintf(fail_trig, "%s():%u " fmt, __func__, __LINE__, __VA_ARGS__); \ - fflush(fail_trig); \ - exit(0); \ -} while (0) -#define test(cond) if (!(cond)) test_fail(); |