/* * Copyright (c) Microsoft Corporation. * Licensed under the MIT license. */ #include #include #include #include #include #include #include #include /*===================================================================================================================* * System Calls in demi/libos.h * *===================================================================================================================*/ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnonnull" /** * @brief Issues an invalid call to demi_socket(). */ static bool inval_socket(void) { int *qd = NULL; int domain = -1; int type = -1; int protocol = -1; return (demi_socket(qd, domain, type, protocol) != 0); } /** * @brief Issues an invalid call to demi_listen(). */ static bool inval_listen(void) { int qd = -1; int backlog = -1; return (demi_listen(qd, backlog) != 0); } /** * @brief Issues an invalid call to demi_bind(). */ static bool inval_bind(void) { int qd = -1; struct sockaddr *saddr = NULL; socklen_t size = 0; return (demi_bind(qd, saddr, size) != 0); } /** * @brief Issues an invalid call to demi_accept(). */ static bool inval_accept(void) { demi_qtoken_t *qt = NULL; int sockqd = -1; return (demi_accept(qt, sockqd) != 0); } /** * @brief Issues an invalid call to demi_connect(). */ static bool inval_connect(void) { demi_qtoken_t *qt = NULL; int qd = -1; struct sockaddr *saddr = NULL; socklen_t size = -1; return (demi_connect(qt, qd, saddr, size) != 0); } /** * @brief Issues an invalid call to demi_close(). */ static bool inval_close(void) { int qd = -1; return (demi_close(qd) != 0); } /** * @brief Issues an invalid call to demi_push(). */ static bool inval_push(void) { demi_qtoken_t *qt = NULL; int qd = -1; demi_sgarray_t *sga = NULL; return (demi_push(qt, qd, sga) != 0); } /** * @brief Issues an invalid call to demi_pushto(). */ static bool inval_pushto(void) { demi_qtoken_t *qt = NULL; int qd = -1; demi_sgarray_t *sga = NULL; struct sockaddr *saddr = NULL; socklen_t size = -1; return (demi_pushto(qt, qd, sga, saddr, size) != 0); } /** * @brief Issues an invalid call to demi_pop(). */ static bool inval_pop(void) { demi_qtoken_t *qt = NULL; int qd = -1; return (demi_pop(qt, qd) != 0); } /** * @brief Issues an invalid call to demi_setsockopt(). */ static bool inval_setsockopt(void) { int qd = -1; int level = -1; int optname = -1; const void *optval = NULL; socklen_t optlen = 0; return (demi_setsockopt(qd, level, optname, optval, optlen) != 0); } /** * @brief Issues an invalid call to demi_getsockopt(). */ static bool inval_getsockopt(void) { int qd = -1; int level = -1; int optname = -1; void *optval = NULL; socklen_t *optlen = NULL; return (demi_getsockopt(qd, level, optname, optval, optlen) != 0); } /* * @brief Issues an invalid call to getpeername(). */ static bool inval_getpeername(void) { int qd = -1; return (demi_getpeername(qd, NULL, NULL) != 0); } /*===================================================================================================================* * System Calls in demi/sga.h * *===================================================================================================================*/ /** * @brief Issues an invalid call to demi_sgaalloc(). */ static bool inval_sgaalloc(void) { size_t len = 0; demi_sgarray_t sga = demi_sgaalloc(len); return (sga.sga_buf == NULL); } /** * @brief Issues an invalid call to demi_sgafree(). */ static bool inval_sgafree(void) { demi_sgarray_t *sga = NULL; return (demi_sgafree(sga) != 0); } /*===================================================================================================================* * System Calls in demi/wait.h * *===================================================================================================================*/ /** * @brief Issues an invalid system call to demi_wait(). */ static bool inval_wait(void) { demi_qresult_t *qr = NULL; demi_qtoken_t qt = -1; struct timespec *timeout = NULL; return (demi_wait(qr, qt, timeout) != 0); } /** * @brief Issues an invalid system call to demi_wait_any(). */ static bool inval_wait_any(void) { demi_qresult_t *qr = NULL; int *ready_offset = NULL; demi_qtoken_t *qts = NULL; int num_qts = -1; struct timespec *timeout = NULL; return (demi_wait_any(qr, ready_offset, qts, num_qts, timeout) != 0); } #pragma GCC diagnostic pop /*===================================================================================================================* * main() * *===================================================================================================================*/ /** * @brief Tests Descriptor */ struct test { bool (*fn)(void); /**< Test Function */ const char *name; /**< Test Name */ }; /** * @brief Tests for system calls in demi/libos.h */ static struct test tests_libos[] = {{inval_socket, "invalid demi_socket()"}, {inval_accept, "invalid demi_accept()"}, {inval_bind, "invalid demi_bind()"}, {inval_close, "invalid_demi_close()"}, {inval_connect, "invalid demi_connect()"}, {inval_listen, "invalid demi_listen()"}, {inval_pop, "invalid demi_pop()"}, {inval_push, "invalid demi_push()"}, {inval_pushto, "invalid demi_pushto()"}, {inval_getpeername, "invalid demi_getpeername()"}, {inval_setsockopt, "invalid demi_setsockopt()"}, {inval_getsockopt, "invalid demi_getsockopt()}"}}; /** * @brief Tests for system calls in demi/sga.h */ static struct test tests_sga[] = {{inval_sgaalloc, "invalid demi_sgaalloc()"}, {inval_sgafree, "invalid demi_sgafree()"}}; /** * @brief Tests for system calls in demi/wait.h */ static struct test tests_wait[] = {{inval_wait, "invalid demi_wait()"}, {inval_wait_any, "invalid demi_wait_any()"}}; /** * @brief Drives the application. * * This system-level test issues invalid calls to all system calls in Demikernel. * Overall, this test ensures the following points: * - All system calls of Demikernel are callable from a C application. * - All invalid system calls fail. * * @param argc Argument count (unused). * @param argv Argument vector (unused). * * @return On successful completion EXIT_SUCCESS is returned. */ int main(int argc, char *const argv[]) { ((void)argc); ((void)argv); /* This shall never fail. */ const struct demi_args args = { .argc = argc, .argv = argv, .callback = NULL, }; assert(demi_init(&args) == 0); /* System calls in demi/libos.h */ for (size_t i = 0; i < sizeof(tests_libos) / sizeof(struct test); i++) { if (tests_libos[i].fn() == true) fprintf(stderr, "test result: passed %s\n", tests_libos[i].name); else { fprintf(stderr, "test result: FAILED %s\n", tests_libos[i].name); return (EXIT_FAILURE); } } /* System calls in demi/sga.h */ for (size_t i = 0; i < sizeof(tests_sga) / sizeof(struct test); i++) { if (tests_sga[i].fn() == true) fprintf(stderr, "test result: passed %s\n", tests_sga[i].name); else { fprintf(stderr, "test result: FAILED %s\n", tests_sga[i].name); return (EXIT_FAILURE); } } /* System calls in demi/wait.h */ for (size_t i = 0; i < sizeof(tests_wait) / sizeof(struct test); i++) { if (tests_wait[i].fn() == true) fprintf(stderr, "test result: passed %s\n", tests_wait[i].name); else { fprintf(stderr, "test result: FAILED %s\n", tests_wait[i].name); return (EXIT_FAILURE); } } return (EXIT_SUCCESS); }