From: Kevin Day Date: Tue, 24 May 2022 04:31:18 +0000 (-0500) Subject: Update: Add unit tests for f_socket. X-Git-Tag: 0.5.10~100 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=b7dbb45c755a10c9cc8fab42d6ca899e559a31e5;p=fll Update: Add unit tests for f_socket. --- diff --git a/level_0/f_socket/data/build/dependencies-tests b/level_0/f_socket/data/build/dependencies-tests new file mode 100644 index 0000000..dea3179 --- /dev/null +++ b/level_0/f_socket/data/build/dependencies-tests @@ -0,0 +1,3 @@ +# fss-0001 + +cmocka 1.* diff --git a/level_0/f_socket/data/build/settings-mocks b/level_0/f_socket/data/build/settings-mocks new file mode 100644 index 0000000..217d78e --- /dev/null +++ b/level_0/f_socket/data/build/settings-mocks @@ -0,0 +1,73 @@ +# fss-0001 +# +# Build the project with appropriate mocks linked in via the dynamic linker's "--wrap" functionality. +# +# The -Wl,--wrap does not work across shared files. +# Therefore, this file is a work-around to inject the mocks into the library for testing purposes. +# This should exactly match the "settings" file, except for the additional "-Wl,--wrap" parts and the additional mock source file. +# +# The flags -o0 must be passed to prevent the compiler from optimizing away any functions being mocked (which results in the mock not happening and a real function being called). +# Alternatively, figure out which optimization that is disabled by -o0 and have that specific optimization disabled. +# + +build_name f_socket + +version_major 0 +version_minor 5 +version_micro 9 +version_file micro +version_target minor + +modes individual clang test +modes_default individual + +build_compiler gcc +build_compiler-clang clang +build_indexer ar +build_indexer_arguments rcs +build_language c + +build_libraries -lc +build_libraries-individual -lf_memory -lf_string + +build_sources_library socket.c ../../tests/unit/c/mock-socket.c + +build_sources_headers socket.h socket/common.h + +build_script yes +build_shared yes +build_static no + +path_headers fll/level_0 +path_library_script script +path_library_shared shared +path_library_static static + +has_path_standard yes +preserve_path_headers yes + +search_exclusive yes +search_shared yes +search_static yes + +flags -O0 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses +flags-clang -Wno-logical-op-parentheses +flags-test -fstack-protector + +flags_library -fPIC + +# Inject mocks. +flags -Wl,--wrap=accept +flags -Wl,--wrap=bind +flags -Wl,--wrap=close +flags -Wl,--wrap=connect +flags -Wl,--wrap=getsockopt +flags -Wl,--wrap=listen +flags -Wl,--wrap=recvfrom +flags -Wl,--wrap=recvmsg +flags -Wl,--wrap=sendmsg +flags -Wl,--wrap=sendto +flags -Wl,--wrap=setsockopt +flags -Wl,--wrap=shutdown +flags -Wl,--wrap=socket +flags -Wl,--wrap=socketpair diff --git a/level_0/f_socket/data/build/settings-tests b/level_0/f_socket/data/build/settings-tests new file mode 100644 index 0000000..4bb9d8f --- /dev/null +++ b/level_0/f_socket/data/build/settings-tests @@ -0,0 +1,53 @@ +# fss-0001 +# +# Builds a program that is links to the generated library and is executed to perform tests. +# +# Memory leaks in the test program can be checked for by running valgrind with this executable. +# + +build_name test-f_socket + +version_major 0 +version_minor 5 +version_micro 9 +version_file major +version_target major + +modes individual clang test +modes_default individual + +build_compiler gcc +build_compiler-clang clang +build_indexer ar +build_indexer_arguments rcs +build_language c + +build_libraries -lc -lcmocka +build_libraries-individual -lf_memory -lf_string -lf_type_array -lf_socket + +build_sources_program test-socket-accept.c test-socket-bind.c test-socket-bind_local.c test-socket-connect.c test-socket-create.c test-socket-create_pair.c test-socket-disconnect.c test-socket-listen.c test-socket-option_get.c test-socket-option_set.c test-socket-read.c test-socket-read_message.c test-socket-write.c test-socket-write_message.c +build_sources_program test-socket.c + +build_script no +build_shared yes +build_static no + +path_headers tests/unit/c +path_sources tests/unit/c + +has_path_standard no +preserve_path_headers yes + +search_exclusive yes +search_shared yes +search_static yes + +defines -Ibuild/includes +defines_static -Lbuild/libraries/static +defines_shared -Lbuild/libraries/shared + +flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses +flags-clang -Wno-logical-op-parentheses +flags-test -fstack-protector -Wall + +flags_program -fPIE diff --git a/level_0/f_socket/data/build/testfile b/level_0/f_socket/data/build/testfile new file mode 100644 index 0000000..ae54ea9 --- /dev/null +++ b/level_0/f_socket/data/build/testfile @@ -0,0 +1,55 @@ +# fss-0005 iki-0002 + +settings: + load_build yes + fail exit + + environment LD_LIBRARY_PATH + environment CMOCKA_XML_FILE CMOCKA_MESSAGE_OUTPUT CMOCKA_TEST_ABORT + + # Cmcka is not fully thread-safe, set this to "1" to have cmocka call abort() on a test failure. + #CMOCKA_TEST_ABORT 1 + + # One of: STDOUT, SUBUNIT, TAP, or XML. + #define CMOCKA_MESSAGE_OUTPUT STDOUT + + # When in "XML" output mode, output to this file rather than stdout. + #define CMOCKA_XML_FILE ./out.xml + +main: + build settings-mocks + build settings-tests + + operate ld_library_path + + if exists build/programs/shared/test-f_socket + shell build/programs/shared/test-f_socket + + if exists build/programs/static/test-f_socket + shell build/programs/static/test-f_socket + + if not exists build/programs/shared/test-f_socket + and not exists build/programs/static/test-f_socket + operate not_created + +not_created: + print + print 'context:"error"Failed to test due to being unable to find either a shared or static test binary to perform tests. context:"reset"' + + exit failure + +ld_library_path: + if defined environment LD_LIBRARY_PATH + and defined parameter work + define LD_LIBRARY_PATH 'build/libraries/shared:parameter:"work:value"libraries/shared:define:"LD_LIBRARY_PATH"' + + else + if defined environment LD_LIBRARY_PATH + define LD_LIBRARY_PATH 'build/libraries/shared:parameter:define:"LD_LIBRARY_PATH"' + + else + if defined parameter work + define LD_LIBRARY_PATH 'build/libraries/shared:parameter:"work:value"libraries/shared' + + else + define LD_LIBRARY_PATH build/libraries/shared diff --git a/level_0/f_socket/tests/unit/c/mock-socket.c b/level_0/f_socket/tests/unit/c/mock-socket.c new file mode 100644 index 0000000..5e35fca --- /dev/null +++ b/level_0/f_socket/tests/unit/c/mock-socket.c @@ -0,0 +1,191 @@ +#include "mock-socket.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int __wrap_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return mock_type(int); +} + +int __wrap_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return 0; +} + +int __wrap_close(int fd) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return 0; +} + +int __wrap_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return 0; +} + +int __wrap_getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return 0; +} + +int __wrap_listen(int sockfd, int backlog) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return 0; +} + +ssize_t __wrap_recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return mock_type(int); +} + +ssize_t __wrap_recvmsg(int sockfd, struct msghdr *msg, int flags) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return mock_type(int); +} + +ssize_t __wrap_sendmsg(int sockfd, const struct msghdr *msg, int flags) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return mock_type(int); +} + +ssize_t __wrap_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return mock_type(int); +} + +int __wrap_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return 0; +} + +int __wrap_shutdown(int sockfd, int how) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return 0; +} + +int __wrap_socket(int domain, int type, int protocol) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return 0; +} + +int __wrap_socketpair(int domain, int type, int protocol, int sv[2]) { + + const bool failure = mock_type(bool); + + if (failure) { + errno = mock_type(int); + + return -1; + } + + return 0; +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/mock-socket.h b/level_0/f_socket/tests/unit/c/mock-socket.h new file mode 100644 index 0000000..2c3a00a --- /dev/null +++ b/level_0/f_socket/tests/unit/c/mock-socket.h @@ -0,0 +1,50 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _MOCK__socket_h +#define _MOCK__socket_h + +// Libc includes. +#include +#include +#include +#include + +// cmocka includes. +#include + +// FLL-0 includes. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +const static int mock_errno_generic = 32767; + +int __wrap_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +int __wrap_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +int __wrap_close(int fd); +int __wrap_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +int __wrap_getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); +int __wrap_listen(int sockfd, int backlog); +ssize_t __wrap_recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); +ssize_t __wrap_recvmsg(int sockfd, struct msghdr *msg, int flags); +ssize_t __wrap_sendmsg(int sockfd, const struct msghdr *msg, int flags); +ssize_t __wrap_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); +int __wrap_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); +int __wrap_shutdown(int sockfd, int how); +int __wrap_socket(int domain, int type, int protocol); +int __wrap_socketpair(int domain, int type, int protocol, int sv[2]); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _MOCK__socket_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-accept.c b/level_0/f_socket/tests/unit/c/test-socket-accept.c new file mode 100644 index 0000000..2484cc9 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-accept.c @@ -0,0 +1,107 @@ +#include "test-socket.h" +#include "test-socket-accept.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_accept__fails(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + int errnos[] = { + EACCES, + EAGAIN, + EBADF, + EFAULT, + EHOSTDOWN, + EHOSTUNREACH, + EINTR, + EINVAL, + EMFILE, + ENETDOWN, + ENFILE, + ENETUNREACH, + ENOBUFS, + ENOMEM, + ENONET, + ENOPROTOOPT, + ENOTSOCK, + EOPNOTSUPP, + EPROTO, + EPERM, + ESOCKTNOSUPPORT, + EPROTONOSUPPORT, + ETIMEDOUT, + EWOULDBLOCK, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_block, + F_file_descriptor, + F_buffer, + F_network_client_not, + F_network_reach_client_not, + F_interrupt, + F_parameter, + F_file_descriptor_max, + F_network_not, + F_file_open_max, + F_network_reach_not, + F_buffer_not, + F_memory_not, + F_network_device_not, + F_option_not, + F_socket_not, + F_stream_not, + F_protocol, + F_prohibited, + F_supported_not, + F_protocol_not, + F_time_out, + F_block, + F_failure, + }; + + for (uint8_t i = 0; i < 25; ++i) { + + will_return(__wrap_accept, true); + will_return(__wrap_accept, errnos[i]); + + const f_status_t status = f_socket_accept(&socket, 0); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for +} + +void test__f_socket_accept__parameter_checking(void **state) { + + { + const f_status_t status = f_socket_accept(0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_accept__works(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + { + const int id = 1; + + will_return(__wrap_accept, false); + will_return(__wrap_accept, id); + + const f_status_t status = f_socket_accept(&socket, 0); + + assert_int_equal(status, F_none); + assert_int_equal(socket.id, id); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-accept.h b/level_0/f_socket/tests/unit/c/test-socket-accept.h new file mode 100644 index 0000000..030a775 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-accept.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_accept_h +#define _TEST__F_socket_accept_h + +/** + * Test that function fails. + * + * @see f_socket_accept() + */ +extern void test__f_socket_accept__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_accept() + */ +extern void test__f_socket_accept__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_accept() + */ +extern void test__f_socket_accept__works(void **state); + +#endif // _TEST__F_socket_accept_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind.c b/level_0/f_socket/tests/unit/c/test-socket-bind.c new file mode 100644 index 0000000..5e7236f --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-bind.c @@ -0,0 +1,77 @@ +#include "test-socket.h" +#include "test-socket-bind.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_bind__fails(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + int errnos[] = { + EACCES, + EADDRINUSE, + EADDRNOTAVAIL, + EFAULT, + EINVAL, + ELOOP, + ENAMETOOLONG, + ENOENT, + ENOMEM, + ENOTDIR, + ENOTSOCK, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_busy_address, + F_available_not_address, + F_buffer, + F_parameter, + F_loop, + F_string_too_large, + F_file_found_not, + F_memory_not, + F_directory_found_not, + F_socket_not, + F_failure, + }; + + for (uint8_t i = 0; i < 12; ++i) { + + will_return(__wrap_bind, true); + will_return(__wrap_bind, errnos[i]); + + const f_status_t status = f_socket_bind(&socket); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for +} + +void test__f_socket_bind__parameter_checking(void **state) { + + { + const f_status_t status = f_socket_bind(0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_bind__works(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + { + will_return(__wrap_bind, false); + + const f_status_t status = f_socket_bind(&socket); + + assert_int_equal(status, F_none); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind.h b/level_0/f_socket/tests/unit/c/test-socket-bind.h new file mode 100644 index 0000000..67d2428 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-bind.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_bind_h +#define _TEST__F_socket_bind_h + +/** + * Test that function fails. + * + * @see f_socket_bind() + */ +extern void test__f_socket_bind__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_bind() + */ +extern void test__f_socket_bind__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_bind() + */ +extern void test__f_socket_bind__works(void **state); + +#endif // _TEST__F_socket_bind_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind_local.c b/level_0/f_socket/tests/unit/c/test-socket-bind_local.c new file mode 100644 index 0000000..f5968c8 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-bind_local.c @@ -0,0 +1,113 @@ +#include "test-socket.h" +#include "test-socket-bind_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_bind_local__fails(void **state) { + + int errnos[] = { + EACCES, + EADDRINUSE, + EADDRNOTAVAIL, + EFAULT, + EINVAL, + ELOOP, + ENAMETOOLONG, + ENOENT, + ENOMEM, + ENOTDIR, + ENOTSOCK, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_busy_address, + F_available_not_address, + F_buffer, + F_parameter, + F_loop, + F_string_too_large, + F_file_found_not, + F_memory_not, + F_directory_found_not, + F_socket_not, + F_failure, + }; + + { + f_socket_t socket = f_socket_t_initialize; + struct sockaddr_un address; + + memset(&address, 0, sizeof(struct sockaddr_un)); + + address.sun_family = f_socket_domain_file_d; + + socket.address = (struct sockaddr *) &address; + + for (uint8_t i = 0; i < 12; ++i) { + + const f_status_t status = f_socket_bind_local(&socket); + + assert_int_equal(status, F_status_set_error(F_local_not)); + } // for + } + + { + f_socket_t socket = f_socket_t_initialize; + struct sockaddr_un address; + + memset(&address, 0, sizeof(struct sockaddr_un)); + + address.sun_family = f_socket_domain_file_d; + + socket.address = (struct sockaddr *) &address; + socket.domain = f_socket_domain_file_d; + + for (uint8_t i = 0; i < 12; ++i) { + + will_return(__wrap_bind, true); + will_return(__wrap_bind, errnos[i]); + + const f_status_t status = f_socket_bind_local(&socket); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for + } +} + +void test__f_socket_bind_local__parameter_checking(void **state) { + + { + const f_status_t status = f_socket_bind_local(0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_bind_local__works(void **state) { + + { + f_socket_t socket = f_socket_t_initialize; + struct sockaddr_un address; + + memset(&address, 0, sizeof(struct sockaddr_un)); + + address.sun_family = f_socket_domain_file_d; + + socket.address = (struct sockaddr *) &address; + socket.domain = f_socket_domain_file_d; + + will_return(__wrap_bind, false); + + const f_status_t status = f_socket_bind_local(&socket); + + assert_int_equal(status, F_none); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-bind_local.h b/level_0/f_socket/tests/unit/c/test-socket-bind_local.h new file mode 100644 index 0000000..f5fa5e2 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-bind_local.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_bind_local_h +#define _TEST__F_socket_bind_local_h + +/** + * Test that function fails. + * + * @see f_socket_bind_local() + */ +extern void test__f_socket_bind_local__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_bind_local() + */ +extern void test__f_socket_bind_local__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_bind_local() + */ +extern void test__f_socket_bind_local__works(void **state); + +#endif // _TEST__F_socket_bind_local_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-connect.c b/level_0/f_socket/tests/unit/c/test-socket-connect.c new file mode 100644 index 0000000..930650d --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-connect.c @@ -0,0 +1,80 @@ +#include "test-socket.h" +#include "test-socket-connect.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_connect__fails(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + int errnos[] = { + EACCES, + EADDRINUSE, + EADDRNOTAVAIL, + EAFNOSUPPORT, + EAGAIN, + EALREADY, + EBADF, + ECONNREFUSED, + EINPROGRESS, + EINTR, + EINVAL, + EISCONN, + ENETUNREACH, + ENOTSOCK, + EPERM, + EPROTONOSUPPORT, + ETIMEDOUT, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_busy_address, + F_available_not_address, + F_domain_not, + F_block, + F_complete_not, + F_file_descriptor, + F_connect_refuse, + F_progress, + F_interrupt, + F_parameter, + F_connect, + F_network_reach_not, + F_socket_not, + F_prohibited, + F_protocol_not, + F_time_out, + F_failure, + }; + + for (uint8_t i = 0; i < 17; ++i) { + + will_return(__wrap_connect, true); + will_return(__wrap_connect, errnos[i]); + + const f_status_t status = f_socket_connect(socket); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for +} + +void test__f_socket_connect__works(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + { + will_return(__wrap_connect, false); + + const f_status_t status = f_socket_connect(socket); + + assert_int_equal(status, F_none); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-connect.h b/level_0/f_socket/tests/unit/c/test-socket-connect.h new file mode 100644 index 0000000..1ecd4cc --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-connect.h @@ -0,0 +1,27 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_connect_h +#define _TEST__F_socket_connect_h + +/** + * Test that function fails. + * + * @see f_socket_connect() + */ +extern void test__f_socket_connect__fails(void **state); + +/** + * Test that function works. + * + * @see f_socket_connect() + */ +extern void test__f_socket_connect__works(void **state); + +#endif // _TEST__F_socket_connect_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-create.c b/level_0/f_socket/tests/unit/c/test-socket-create.c new file mode 100644 index 0000000..3cad44b --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-create.c @@ -0,0 +1,74 @@ +#include "test-socket.h" +#include "test-socket-create.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_create__fails(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + int errnos[] = { + EACCES, + EAFNOSUPPORT, + EINVAL, + EMFILE, + ENFILE, + ENOBUFS, + ENOMEM, + EPROTONOSUPPORT, + ESOCKTNOSUPPORT, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_domain_not, + F_parameter, + F_file_descriptor_max, + F_file_open_max, + F_buffer_not, + F_memory_not, + F_protocol_not, + F_type_not, + F_failure, + }; + + for (uint8_t i = 0; i < 10; ++i) { + + will_return(__wrap_socket, true); + will_return(__wrap_socket, errnos[i]); + + const f_status_t status = f_socket_create(&socket); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for +} + +void test__f_socket_create__parameter_checking(void **state) { + + { + const f_status_t status = f_socket_create(0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_create__works(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + { + + will_return(__wrap_socket, false); + + const f_status_t status = f_socket_create(&socket); + + assert_int_equal(status, F_none); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-create.h b/level_0/f_socket/tests/unit/c/test-socket-create.h new file mode 100644 index 0000000..3113409 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-create.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_create_h +#define _TEST__F_socket_create_h + +/** + * Test that function fails. + * + * @see f_socket_create() + */ +extern void test__f_socket_create__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_create() + */ +extern void test__f_socket_create__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_create() + */ +extern void test__f_socket_create__works(void **state); + +#endif // _TEST__F_socket_create_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-create_pair.c b/level_0/f_socket/tests/unit/c/test-socket-create_pair.c new file mode 100644 index 0000000..caf5850 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-create_pair.c @@ -0,0 +1,87 @@ +#include "test-socket.h" +#include "test-socket-create_pair.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_create_pair__fails(void **state) { + + int id_1 = 1; + int id_2 = 2; + + int errnos[] = { + EACCES, + EAFNOSUPPORT, + EINVAL, + EMFILE, + ENFILE, + ENOBUFS, + ENOMEM, + EPROTONOSUPPORT, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_domain_not, + F_parameter, + F_file_descriptor_max, + F_file_open_max, + F_buffer_not, + F_memory_not, + F_protocol_not, + F_failure, + }; + + for (uint8_t i = 0; i < 9; ++i) { + + will_return(__wrap_socketpair, true); + will_return(__wrap_socketpair, errnos[i]); + + const f_status_t status = f_socket_create_pair(0, 0, 0, &id_1, &id_2); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for +} + +void test__f_socket_create_pair__parameter_checking(void **state) { + + int id = 0; + + { + const f_status_t status = f_socket_create_pair(0, 0, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_create_pair(0, 0, 0, &id, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_create_pair(0, 0, 0, 0, &id); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_create_pair__works(void **state) { + + int id_1 = 1; + int id_2 = 2; + + { + will_return(__wrap_socketpair, false); + + const f_status_t status = f_socket_create_pair(0, 0, 0, &id_1, &id_2); + + assert_int_equal(status, F_none); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-create_pair.h b/level_0/f_socket/tests/unit/c/test-socket-create_pair.h new file mode 100644 index 0000000..8fb8fe2 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-create_pair.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_create_pair_h +#define _TEST__F_socket_create_pair_h + +/** + * Test that function fails. + * + * @see f_socket_create_pair() + */ +extern void test__f_socket_create_pair__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_create_pair() + */ +extern void test__f_socket_create_pair__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_create_pair() + */ +extern void test__f_socket_create_pair__works(void **state); + +#endif // _TEST__F_socket_create_pair_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-disconnect.c b/level_0/f_socket/tests/unit/c/test-socket-disconnect.c new file mode 100644 index 0000000..79d20a5 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-disconnect.c @@ -0,0 +1,210 @@ +#include "test-socket.h" +#include "test-socket-disconnect.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_disconnect__fails_for_close_fast(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + int errnos[] = { + EBADF, + EDQUOT, + EINTR, + EINVAL, + EIO, + ENOTCONN, + ENOTSOCK, + ENOSPC, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_status_set_error(F_file_descriptor), + F_status_set_error(F_filesystem_quota_block), + F_status_set_error(F_interrupt), + F_status_set_error(F_value), + F_status_set_error(F_input_output), + F_connect_not, + F_status_set_error(F_socket_not), + F_status_set_error(F_parameter), + F_status_set_error(F_failure), + }; + + for (uint8_t i = 0; i < 9; ++i) { + + socket.id = 1; + + will_return(__wrap_close, true); + will_return(__wrap_close, errnos[i]); + + const f_status_t status = f_socket_disconnect(&socket, f_socket_close_fast_e); + + assert_int_equal(status, statuss[i]); + + if (errnos[i] != EBADF) { + assert_int_equal(socket.id, -1); + } + } // for +} + +void test__f_socket_disconnect__fails_for_close_read(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + int errnos[] = { + EBADF, + EDQUOT, + EINTR, + EINVAL, + EIO, + ENOTCONN, + ENOTSOCK, + ENOSPC, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_status_set_error(F_file_descriptor), + F_status_set_error(F_filesystem_quota_block), + F_status_set_error(F_interrupt), + F_status_set_error(F_value), + F_status_set_error(F_input_output), + F_connect_not, + F_status_set_error(F_socket_not), + F_status_set_error(F_parameter), + F_status_set_error(F_failure), + }; + + for (uint8_t i = 0; i < 9; ++i) { + + socket.id = 1; + + will_return(__wrap_shutdown, true); + will_return(__wrap_shutdown, errnos[i]); + + const f_status_t status = f_socket_disconnect(&socket, f_socket_close_read_e); + + assert_int_equal(status, statuss[i]); + assert_int_equal(socket.id, 1); + } // for +} + +void test__f_socket_disconnect__fails_for_close_unknown(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + { + socket.id = 1; + + const f_status_t status = f_socket_disconnect(&socket, 100); + + assert_int_equal(status, F_status_set_error(F_supported_not)); + assert_int_equal(socket.id, 1); + } +} + +void test__f_socket_disconnect__fails_for_close_write(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + int errnos[] = { + EBADF, + EDQUOT, + EINTR, + EINVAL, + EIO, + ENOTCONN, + ENOTSOCK, + ENOSPC, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_status_set_error(F_file_descriptor), + F_status_set_error(F_filesystem_quota_block), + F_status_set_error(F_interrupt), + F_status_set_error(F_value), + F_status_set_error(F_input_output), + F_connect_not, + F_status_set_error(F_socket_not), + F_status_set_error(F_parameter), + F_status_set_error(F_failure), + }; + + for (uint8_t i = 0; i < 9; ++i) { + + socket.id = 1; + + will_return(__wrap_shutdown, true); + will_return(__wrap_shutdown, errnos[i]); + + const f_status_t status = f_socket_disconnect(&socket, f_socket_close_write_e); + + assert_int_equal(status, statuss[i]); + assert_int_equal(socket.id, 1); + } // for +} + +void test__f_socket_disconnect__parameter_checking(void **state) { + + { + const f_status_t status = f_socket_disconnect(0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_disconnect__works_for_close_fast(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + { + socket.id = 1; + + will_return(__wrap_close, false); + + const f_status_t status = f_socket_disconnect(&socket, f_socket_close_fast_e); + + assert_int_equal(status, F_none); + assert_int_equal(socket.id, -1); + } +} + +void test__f_socket_disconnect__works_for_close_read(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + { + socket.id = 1; + + will_return(__wrap_shutdown, false); + + const f_status_t status = f_socket_disconnect(&socket, f_socket_close_read_e); + + assert_int_equal(status, F_none); + assert_int_equal(socket.id, 1); + } +} + +void test__f_socket_disconnect__works_for_close_write(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + { + socket.id = 1; + + will_return(__wrap_shutdown, false); + + const f_status_t status = f_socket_disconnect(&socket, f_socket_close_write_e); + + assert_int_equal(status, F_none); + assert_int_equal(socket.id, 1); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-disconnect.h b/level_0/f_socket/tests/unit/c/test-socket-disconnect.h new file mode 100644 index 0000000..024ec6d --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-disconnect.h @@ -0,0 +1,69 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_disconnect_h +#define _TEST__F_socket_disconnect_h + +/** + * Test that function fails for f_socket_close_fast_e. + * + * @see f_socket_disconnect() + */ +extern void test__f_socket_disconnect__fails_for_close_fast(void **state); + +/** + * Test that function fails for f_socket_close_read_e. + * + * @see f_socket_disconnect() + */ +extern void test__f_socket_disconnect__fails_for_close_read(void **state); + +/** + * Test that function fails for an arbitrary unknown close value. + * + * @see f_socket_disconnect() + */ +extern void test__f_socket_disconnect__fails_for_close_unknown(void **state); + +/** + * Test that function fails for f_socket_close_write_e. + * + * @see f_socket_disconnect() + */ +extern void test__f_socket_disconnect__fails_for_close_write(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_disconnect() + */ +extern void test__f_socket_disconnect__parameter_checking(void **state); + +/** + * Test that function works for f_socket_close_fast_e. + * + * @see f_socket_disconnect() + */ +extern void test__f_socket_disconnect__works_for_close_fast(void **state); + +/** + * Test that function works for f_socket_close_read_e. + * + * @see f_socket_disconnect() + */ +extern void test__f_socket_disconnect__works_for_close_read(void **state); + +/** + * Test that function works for f_socket_close_write_e. + * + * @see f_socket_disconnect() + */ +extern void test__f_socket_disconnect__works_for_close_write(void **state); + +#endif // _TEST__F_socket_disconnect_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-listen.c b/level_0/f_socket/tests/unit/c/test-socket-listen.c new file mode 100644 index 0000000..f8cdc04 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-listen.c @@ -0,0 +1,63 @@ +#include "test-socket.h" +#include "test-socket-listen.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_listen__fails(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + int errnos[] = { + EADDRINUSE, + EBADF, + ENOTSOCK, + EOPNOTSUPP, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_busy_address, + F_file_descriptor, + F_socket_not, + F_supported_not, + F_failure, + }; + + for (uint8_t i = 0; i < 5; ++i) { + + will_return(__wrap_listen, true); + will_return(__wrap_listen, errnos[i]); + + const f_status_t status = f_socket_listen(&socket, 0); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for +} + +void test__f_socket_listen__parameter_checking(void **state) { + + { + const f_status_t status = f_socket_listen(0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_listen__works(void **state) { + + f_socket_t socket = f_socket_t_initialize; + + { + will_return(__wrap_listen, false); + + const f_status_t status = f_socket_listen(&socket, 0); + + assert_int_equal(status, F_none); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-listen.h b/level_0/f_socket/tests/unit/c/test-socket-listen.h new file mode 100644 index 0000000..a8a5db3 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-listen.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_listen_h +#define _TEST__F_socket_listen_h + +/** + * Test that function fails. + * + * @see f_socket_listen() + */ +extern void test__f_socket_listen__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_listen() + */ +extern void test__f_socket_listen__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_listen() + */ +extern void test__f_socket_listen__works(void **state); + +#endif // _TEST__F_socket_listen_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-option_get.c b/level_0/f_socket/tests/unit/c/test-socket-option_get.c new file mode 100644 index 0000000..484fce8 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-option_get.c @@ -0,0 +1,109 @@ +#include "test-socket.h" +#include "test-socket-option_get.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_option_get__fails(void **state) { + + f_socket_t socket = f_socket_t_initialize; + int value = 0; + socklen_t length = 0; + + int errnos[] = { + EBADF, + EFAULT, + EINVAL, + ENOTSOCK, + ENOPROTOOPT, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_file_descriptor, + F_buffer, + F_value, + F_socket_not, + F_option_not, + F_failure, + }; + + for (uint8_t i = 0; i < 6; ++i) { + + will_return(__wrap_getsockopt, true); + will_return(__wrap_getsockopt, errnos[i]); + + const f_status_t status = f_socket_option_get(&socket, 0, 0, (void *) &value, &length); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for +} + +void test__f_socket_option_get__parameter_checking(void **state) { + + f_socket_t socket = f_socket_t_initialize; + int value = 0; + socklen_t length = 0; + + { + const f_status_t status = f_socket_option_get(0, 0, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_option_get(&socket, 0, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_option_get(&socket, 0, 0, (void *) &value, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_option_get(&socket, 0, 0, 0, &length); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_option_get(0, 0, 0, (void *) &value, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_option_get(0, 0, 0, (void *) &value, &length); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_option_get(0, 0, 0, 0, &length); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_option_get__works(void **state) { + + f_socket_t socket = f_socket_t_initialize; + int value = 0; + socklen_t length = 0; + + { + will_return(__wrap_getsockopt, false); + + const f_status_t status = f_socket_option_get(&socket, 0, 0, (void *) &value, &length); + + assert_int_equal(status, F_none); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-option_get.h b/level_0/f_socket/tests/unit/c/test-socket-option_get.h new file mode 100644 index 0000000..d2b3bc0 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-option_get.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_option_get_h +#define _TEST__F_socket_option_get_h + +/** + * Test that function fails. + * + * @see f_socket_option_get() + */ +extern void test__f_socket_option_get__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_option_get() + */ +extern void test__f_socket_option_get__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_option_get() + */ +extern void test__f_socket_option_get__works(void **state); + +#endif // _TEST__F_socket_option_get_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-option_set.c b/level_0/f_socket/tests/unit/c/test-socket-option_set.c new file mode 100644 index 0000000..699ced3 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-option_set.c @@ -0,0 +1,82 @@ +#include "test-socket.h" +#include "test-socket-option_set.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_option_set__fails(void **state) { + + f_socket_t socket = f_socket_t_initialize; + int value = 0; + + int errnos[] = { + EBADF, + EFAULT, + EINVAL, + ENOTSOCK, + ENOPROTOOPT, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_file_descriptor, + F_buffer, + F_value, + F_socket_not, + F_option_not, + F_failure, + }; + + for (uint8_t i = 0; i < 6; ++i) { + + will_return(__wrap_setsockopt, true); + will_return(__wrap_setsockopt, errnos[i]); + + const f_status_t status = f_socket_option_set(&socket, 0, 0, (void *) &value, 0); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for +} + +void test__f_socket_option_set__parameter_checking(void **state) { + + f_socket_t socket = f_socket_t_initialize; + int value = 0; + + { + const f_status_t status = f_socket_option_set(0, 0, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_option_set(&socket, 0, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_option_set(0, 0, 0, (void *) &value, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_option_set__works(void **state) { + + f_socket_t socket = f_socket_t_initialize; + int value = 0; + + { + will_return(__wrap_setsockopt, false); + + const f_status_t status = f_socket_option_set(&socket, 0, 0, (void *) &value, 0); + + assert_int_equal(status, F_none); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-option_set.h b/level_0/f_socket/tests/unit/c/test-socket-option_set.h new file mode 100644 index 0000000..e838df6 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-option_set.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_option_set_h +#define _TEST__F_socket_option_set_h + +/** + * Test that function fails. + * + * @see f_socket_option_set() + */ +extern void test__f_socket_option_set__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_option_set() + */ +extern void test__f_socket_option_set__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_option_set() + */ +extern void test__f_socket_option_set__works(void **state); + +#endif // _TEST__F_socket_option_set_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-read.c b/level_0/f_socket/tests/unit/c/test-socket-read.c new file mode 100644 index 0000000..f79b184 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-read.c @@ -0,0 +1,113 @@ +#include "test-socket.h" +#include "test-socket-read.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_read__fails(void **state) { + + f_socket_t socket = f_socket_t_initialize; + char *buffer = "test"; + size_t length = 0; + + int errnos[] = { + EACCES, + EAGAIN, + EALREADY, + EBADF, + ECONNREFUSED, + ECONNRESET, + EDESTADDRREQ, + EFAULT, + EINTR, + EINVAL, + ENOMEM, + ENOTCONN, + ENOTSOCK, + EOPNOTSUPP, + EPERM, + EPIPE, + ETIMEDOUT, + EWOULDBLOCK, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_block, + F_complete_not, + F_file_descriptor, + F_connect_refuse, + F_connect_reset, + F_address_not, + F_buffer, + F_interrupt, + F_parameter, + F_memory_not, + F_connect_not, + F_socket_not, + F_option_not, + F_prohibited, + F_pipe, + F_time_out, + F_block, + F_failure, + }; + + for (uint8_t i = 0; i < 19; ++i) { + + will_return(__wrap_recvfrom, true); + will_return(__wrap_recvfrom, errnos[i]); + + const f_status_t status = f_socket_read(&socket, 0, (void *) buffer, &length); + + assert_int_equal(status, F_status_set_error(statuss[i])); + assert_int_equal(length, 0); + } // for +} + +void test__f_socket_read__parameter_checking(void **state) { + + f_socket_t socket = f_socket_t_initialize; + char *buffer = "test"; + + { + const f_status_t status = f_socket_read(0, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_read(&socket, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_read(0, 0, buffer, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_read__works(void **state) { + + f_socket_t socket = f_socket_t_initialize; + char *buffer = "test"; + size_t length = 0; + + { + will_return(__wrap_recvfrom, false); + will_return(__wrap_recvfrom, 1); + + const f_status_t status = f_socket_read(&socket, 0, (void *) buffer, &length); + + assert_int_equal(status, F_none); + assert_int_equal(length, 1); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-read.h b/level_0/f_socket/tests/unit/c/test-socket-read.h new file mode 100644 index 0000000..d22a4bf --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-read.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_read_h +#define _TEST__F_socket_read_h + +/** + * Test that function fails. + * + * @see f_socket_read() + */ +extern void test__f_socket_read__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_read() + */ +extern void test__f_socket_read__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_read() + */ +extern void test__f_socket_read__works(void **state); + +#endif // _TEST__F_socket_read_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-read_message.c b/level_0/f_socket/tests/unit/c/test-socket-read_message.c new file mode 100644 index 0000000..015738a --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-read_message.c @@ -0,0 +1,118 @@ +#include "test-socket.h" +#include "test-socket-read_message.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_read_message__fails(void **state) { + + f_socket_t socket = f_socket_t_initialize; + struct msghdr header; + size_t length = 0; + + memset(&header, 0, sizeof(struct msghdr)); + + int errnos[] = { + EACCES, + EAGAIN, + EALREADY, + EBADF, + ECONNREFUSED, + ECONNRESET, + EDESTADDRREQ, + EFAULT, + EINTR, + EINVAL, + ENOMEM, + ENOTCONN, + ENOTSOCK, + EOPNOTSUPP, + EPERM, + EPIPE, + ETIMEDOUT, + EWOULDBLOCK, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_block, + F_complete_not, + F_file_descriptor, + F_connect_refuse, + F_connect_reset, + F_address_not, + F_buffer, + F_interrupt, + F_parameter, + F_memory_not, + F_connect_not, + F_socket_not, + F_option_not, + F_prohibited, + F_pipe, + F_time_out, + F_block, + F_failure, + }; + + for (uint8_t i = 0; i < 19; ++i) { + + will_return(__wrap_recvmsg, true); + will_return(__wrap_recvmsg, errnos[i]); + + const f_status_t status = f_socket_read_message(&socket, 0, &header, &length); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for +} + +void test__f_socket_read_message__parameter_checking(void **state) { + + f_socket_t socket = f_socket_t_initialize; + struct msghdr header; + + memset(&header, 0, sizeof(struct msghdr)); + + { + const f_status_t status = f_socket_read_message(0, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_read_message(&socket, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_read_message(0, 0, &header, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_read_message__works(void **state) { + + f_socket_t socket = f_socket_t_initialize; + struct msghdr header; + size_t length = 0; + + memset(&header, 0, sizeof(struct msghdr)); + + { + will_return(__wrap_recvmsg, false); + will_return(__wrap_recvmsg, 1); + + const f_status_t status = f_socket_read_message(&socket, 0, &header, &length); + + assert_int_equal(status, F_none); + assert_int_equal(length, 1); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-read_message.h b/level_0/f_socket/tests/unit/c/test-socket-read_message.h new file mode 100644 index 0000000..ccfb1a4 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-read_message.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_read_message_h +#define _TEST__F_socket_read_message_h + +/** + * Test that function fails. + * + * @see f_socket_read_message() + */ +extern void test__f_socket_read_message__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_read_message() + */ +extern void test__f_socket_read_message__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_read_message() + */ +extern void test__f_socket_read_message__works(void **state); + +#endif // _TEST__F_socket_read_message_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-write.c b/level_0/f_socket/tests/unit/c/test-socket-write.c new file mode 100644 index 0000000..fdc34d7 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-write.c @@ -0,0 +1,119 @@ +#include "test-socket.h" +#include "test-socket-write.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_write__fails(void **state) { + + f_socket_t socket = f_socket_t_initialize; + char *buffer = "test"; + size_t length = 0; + + int errnos[] = { + EACCES, + EAGAIN, + EALREADY, + EBADF, + ECONNREFUSED, + ECONNRESET, + EDESTADDRREQ, + EFAULT, + EINTR, + EINVAL, + EISCONN, + EMSGSIZE, + ENOBUFS, + ENOMEM, + ENOTCONN, + ENOTSOCK, + EOPNOTSUPP, + EPERM, + EPIPE, + ETIMEDOUT, + EWOULDBLOCK, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_block, + F_complete_not, + F_file_descriptor, + F_connect_refuse, + F_connect_reset, + F_address_not, + F_buffer, + F_interrupt, + F_parameter, + F_connect, + F_size, + F_buffer_not, + F_memory_not, + F_connect_not, + F_socket_not, + F_option_not, + F_prohibited, + F_pipe, + F_time_out, + F_block, + F_failure, + }; + + for (uint8_t i = 0; i < 22; ++i) { + + will_return(__wrap_sendto, true); + will_return(__wrap_sendto, errnos[i]); + + const f_status_t status = f_socket_write(&socket, 0, buffer, &length); + + assert_int_equal(status, F_status_set_error(statuss[i])); + assert_int_equal(length, 0); + } // for +} + +void test__f_socket_write__parameter_checking(void **state) { + + f_socket_t socket = f_socket_t_initialize; + char *buffer = "test"; + + { + const f_status_t status = f_socket_write(0, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_write(&socket, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_write(0, 0, buffer, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_write__works(void **state) { + + f_socket_t socket = f_socket_t_initialize; + char *buffer = "test"; + size_t length = 0; + + { + will_return(__wrap_sendto, false); + will_return(__wrap_sendto, 1); + + const f_status_t status = f_socket_write(&socket, 0, buffer, &length); + + assert_int_equal(status, F_none); + assert_int_equal(length, 1); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-write.h b/level_0/f_socket/tests/unit/c/test-socket-write.h new file mode 100644 index 0000000..95dd4db --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-write.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_write_h +#define _TEST__F_socket_write_h + +/** + * Test that function fails. + * + * @see f_socket_write() + */ +extern void test__f_socket_write__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_write() + */ +extern void test__f_socket_write__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_write() + */ +extern void test__f_socket_write__works(void **state); + +#endif // _TEST__F_socket_write_h diff --git a/level_0/f_socket/tests/unit/c/test-socket-write_message.c b/level_0/f_socket/tests/unit/c/test-socket-write_message.c new file mode 100644 index 0000000..df6c30a --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-write_message.c @@ -0,0 +1,124 @@ +#include "test-socket.h" +#include "test-socket-write_message.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_socket_write_message__fails(void **state) { + + f_socket_t socket = f_socket_t_initialize; + struct msghdr header; + size_t length = 0; + + memset(&header, 0, sizeof(struct msghdr)); + + int errnos[] = { + EACCES, + EAGAIN, + EALREADY, + EBADF, + ECONNREFUSED, + ECONNRESET, + EDESTADDRREQ, + EFAULT, + EINTR, + EINVAL, + EISCONN, + EMSGSIZE, + ENOBUFS, + ENOMEM, + ENOTCONN, + ENOTSOCK, + EOPNOTSUPP, + EPERM, + EPIPE, + ETIMEDOUT, + EWOULDBLOCK, + mock_errno_generic, + }; + + f_status_t statuss[] = { + F_access_denied, + F_block, + F_complete_not, + F_file_descriptor, + F_connect_refuse, + F_connect_reset, + F_address_not, + F_buffer, + F_interrupt, + F_parameter, + F_connect, + F_size, + F_buffer_not, + F_memory_not, + F_connect_not, + F_socket_not, + F_option_not, + F_prohibited, + F_pipe, + F_time_out, + F_block, + F_failure, + }; + + for (uint8_t i = 0; i < 22; ++i) { + + will_return(__wrap_sendmsg, true); + will_return(__wrap_sendmsg, errnos[i]); + + const f_status_t status = f_socket_write_message(&socket, 0, &header, &length); + + assert_int_equal(status, F_status_set_error(statuss[i])); + } // for +} + +void test__f_socket_write_message__parameter_checking(void **state) { + + f_socket_t socket = f_socket_t_initialize; + struct msghdr header; + + memset(&header, 0, sizeof(struct msghdr)); + + { + const f_status_t status = f_socket_write_message(0, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_write_message(&socket, 0, 0, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } + + { + const f_status_t status = f_socket_write_message(0, 0, &header, 0); + + assert_int_equal(status, F_status_set_error(F_parameter)); + } +} + +void test__f_socket_write_message__works(void **state) { + + f_socket_t socket = f_socket_t_initialize; + struct msghdr header; + size_t length = 0; + + memset(&header, 0, sizeof(struct msghdr)); + + { + will_return(__wrap_sendmsg, false); + will_return(__wrap_sendmsg, 1); + + const f_status_t status = f_socket_write_message(&socket, 0, &header, &length); + + assert_int_equal(status, F_none); + assert_int_equal(length, 1); + } +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket-write_message.h b/level_0/f_socket/tests/unit/c/test-socket-write_message.h new file mode 100644 index 0000000..5e15469 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket-write_message.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_write_message_h +#define _TEST__F_socket_write_message_h + +/** + * Test that function fails. + * + * @see f_socket_write_message() + */ +extern void test__f_socket_write_message__fails(void **state); + +/** + * Test that parameter checking works as expected. + * + * @see f_socket_write_message() + */ +extern void test__f_socket_write_message__parameter_checking(void **state); + +/** + * Test that function works. + * + * @see f_socket_write_message() + */ +extern void test__f_socket_write_message__works(void **state); + +#endif // _TEST__F_socket_write_message_h diff --git a/level_0/f_socket/tests/unit/c/test-socket.c b/level_0/f_socket/tests/unit/c/test-socket.c new file mode 100644 index 0000000..820723e --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket.c @@ -0,0 +1,91 @@ +#include "test-socket.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int setup(void **state) { + + return 0; +} + +int setdown(void **state) { + + errno = 0; + + return 0; +} + +int main(void) { + + const struct CMUnitTest tests[] = { + cmocka_unit_test(test__f_socket_accept__fails), + cmocka_unit_test(test__f_socket_accept__works), + + cmocka_unit_test(test__f_socket_bind__fails), + cmocka_unit_test(test__f_socket_bind__works), + + cmocka_unit_test(test__f_socket_bind_local__fails), + cmocka_unit_test(test__f_socket_bind_local__works), + + cmocka_unit_test(test__f_socket_connect__fails), + cmocka_unit_test(test__f_socket_connect__works), + + cmocka_unit_test(test__f_socket_create__fails), + cmocka_unit_test(test__f_socket_create__works), + + cmocka_unit_test(test__f_socket_create_pair__fails), + cmocka_unit_test(test__f_socket_create_pair__works), + + cmocka_unit_test(test__f_socket_disconnect__fails_for_close_fast), + cmocka_unit_test(test__f_socket_disconnect__fails_for_close_read), + cmocka_unit_test(test__f_socket_disconnect__fails_for_close_unknown), + cmocka_unit_test(test__f_socket_disconnect__fails_for_close_write), + cmocka_unit_test(test__f_socket_disconnect__works_for_close_fast), + cmocka_unit_test(test__f_socket_disconnect__works_for_close_read), + cmocka_unit_test(test__f_socket_disconnect__works_for_close_write), + + cmocka_unit_test(test__f_socket_listen__fails), + cmocka_unit_test(test__f_socket_listen__works), + + cmocka_unit_test(test__f_socket_option_get__fails), + cmocka_unit_test(test__f_socket_option_get__works), + + cmocka_unit_test(test__f_socket_option_set__fails), + cmocka_unit_test(test__f_socket_option_set__works), + + cmocka_unit_test(test__f_socket_read__fails), + cmocka_unit_test(test__f_socket_read__works), + + cmocka_unit_test(test__f_socket_read_message__fails), + cmocka_unit_test(test__f_socket_read_message__works), + + cmocka_unit_test(test__f_socket_write__fails), + cmocka_unit_test(test__f_socket_write__works), + + cmocka_unit_test(test__f_socket_write_message__fails), + cmocka_unit_test(test__f_socket_write_message__works), + + #ifndef _di_level_0_parameter_checking_ + cmocka_unit_test(test__f_socket_accept__parameter_checking), + cmocka_unit_test(test__f_socket_bind__parameter_checking), + cmocka_unit_test(test__f_socket_bind_local__parameter_checking), + cmocka_unit_test(test__f_socket_create__parameter_checking), + cmocka_unit_test(test__f_socket_create_pair__parameter_checking), + cmocka_unit_test(test__f_socket_disconnect__parameter_checking), + cmocka_unit_test(test__f_socket_listen__parameter_checking), + cmocka_unit_test(test__f_socket_option_get__parameter_checking), + cmocka_unit_test(test__f_socket_option_set__parameter_checking), + cmocka_unit_test(test__f_socket_read__parameter_checking), + cmocka_unit_test(test__f_socket_read_message__parameter_checking), + cmocka_unit_test(test__f_socket_write__parameter_checking), + cmocka_unit_test(test__f_socket_write_message__parameter_checking), + #endif // _di_level_0_parameter_checking_ + }; + + return cmocka_run_group_tests(tests, setup, setdown); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_socket/tests/unit/c/test-socket.h b/level_0/f_socket/tests/unit/c/test-socket.h new file mode 100644 index 0000000..7fa47c1 --- /dev/null +++ b/level_0/f_socket/tests/unit/c/test-socket.h @@ -0,0 +1,85 @@ +/** + * FLL - Level 0 + * + * Project: Socket + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + * + * Test the socket project. + */ +#ifndef _TEST__F_socket_h +#define _TEST__F_socket_h + +// Libc includes. +#include +#include +#include +#include + +// cmocka includes. +#include + +// FLL-0 includes. +#include + +// Mock includes. +#include "mock-socket.h" + +// Test includes. +#include "test-socket-accept.h" +#include "test-socket-bind.h" +#include "test-socket-bind_local.h" +#include "test-socket-connect.h" +#include "test-socket-create.h" +#include "test-socket-create_pair.h" +#include "test-socket-disconnect.h" +#include "test-socket-listen.h" +#include "test-socket-option_get.h" +#include "test-socket-option_set.h" +#include "test-socket-read.h" +#include "test-socket-read_message.h" +#include "test-socket-write.h" +#include "test-socket-write_message.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform any setup operations. + * + * @param state + * The test state. + * + * @return + * The status of this function, where 0 means success. + */ +extern int setup(void **state); + +/** + * Peform any setdown operations. + * + * @param state + * The test state. + * + * @return + * The status of this function, where 0 means success. + */ +extern int setdown(void **state); + +/** + * Run all tests. + * + * @return + * The final result of the tests. + * + * @see cmocka_run_group_tests() + * @see cmocka_unit_test() + */ +extern int main(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _TEST__F_socket_h