* test
This commit is contained in:
Tezc 2021-02-19 05:20:07 +03:00 committed by GitHub
parent 2944a7cc4f
commit ab8abe49f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 297 additions and 119 deletions

View File

@ -279,6 +279,7 @@ size_t __wrap_strlen(const char *s)
} }
bool fail_vsnprintf; bool fail_vsnprintf;
int fail_vsnprintf_value = -1;
int fail_vsnprintf_at = -1; int fail_vsnprintf_at = -1;
extern int __real_vsnprintf(char *str, size_t size, const char *format, extern int __real_vsnprintf(char *str, size_t size, const char *format,
va_list ap); va_list ap);
@ -289,7 +290,7 @@ int __wrap_vsnprintf(char *str, size_t size, const char *format, va_list ap)
return __real_vsnprintf(str, size, format, ap); return __real_vsnprintf(str, size, format, ap);
} }
return -1; return fail_vsnprintf_value;
} }
void fail_test() void fail_test()
@ -456,6 +457,36 @@ void fail_test()
fail_vsnprintf_at = -1; fail_vsnprintf_at = -1;
fail_realloc = false; fail_realloc = false;
sc_buf_init(&buf, 3);
fail_vsnprintf_at = 2;
fail_vsnprintf_value = 1000000;
sc_buf_put_text(&buf, "test");
assert(sc_buf_valid(&buf) == false);
sc_buf_term(&buf);
sc_buf_init(&buf, 3);
fail_vsnprintf_at = 2;
fail_vsnprintf_value = -1;
sc_buf_put_text(&buf, "test");
assert(sc_buf_valid(&buf) == false);
sc_buf_term(&buf);
sc_buf_init(&buf, 3);
fail_vsnprintf_at = 2;
fail_vsnprintf_value = 1000000;
sc_buf_put_fmt(&buf, "%s", "test");
assert(sc_buf_valid(&buf) == false);
sc_buf_term(&buf);
fail_vsnprintf_value = -1;
fail_vsnprintf_at = -1;
fail_realloc = false;
sc_buf_init(&buf, 3);
sc_buf_put_text(&buf, "test");
assert(sc_buf_valid(&buf) == true);
sc_buf_term(&buf);
} }
#else #else
void fail_test() void fail_test()

View File

@ -739,7 +739,7 @@ void sc_buf_put_text(struct sc_buf *buf, const char *fmt, ...)
rc = vsnprintf((char *) sc_buf_wbuf(buf) - offset, quota, fmt, args); rc = vsnprintf((char *) sc_buf_wbuf(buf) - offset, quota, fmt, args);
va_end(args); va_end(args);
if (rc < 0 || (uint32_t) rc >= quota) { if (rc < 0 || (uint32_t) rc >= sc_buf_quota(buf)) {
sc_buf_set_wpos(buf, 0); sc_buf_set_wpos(buf, 0);
buf->error = SC_BUF_OOM; buf->error = SC_BUF_OOM;
return; return;

View File

@ -38,7 +38,7 @@ if(SC_BUILD_TEST)
target_link_options(${PROJECT_NAME}_test PRIVATE target_link_options(${PROJECT_NAME}_test PRIVATE
-Wl,--wrap=fprintf,--wrap=vfprintf,--wrap=fopen,--wrap=localtime_r -Wl,--wrap=fprintf,--wrap=vfprintf,--wrap=fopen,--wrap=localtime_r
-Wl,--wrap=pthread_mutexattr_init,--wrap=pthread_mutex_init -Wl,--wrap=pthread_mutexattr_init,--wrap=pthread_mutex_init
-Wl,--wrap=fclose) -Wl,--wrap=fclose,--wrap=ftell)
endif () endif ()
endif () endif ()

View File

@ -160,6 +160,17 @@ FILE *__wrap_fopen(const char *filename, const char *mode)
return NULL; return NULL;
} }
bool mock_ftell = false;
extern long int __real_ftell (FILE *stream);
extern long int __wrap_ftell (FILE *stream)
{
if (mock_ftell) {
return -1;
}
return __real_ftell(stream);
}
bool mock_fclose = false; bool mock_fclose = false;
extern int __real_fclose (FILE *__stream); extern int __real_fclose (FILE *__stream);
int __wrap_fclose (FILE *__stream) int __wrap_fclose (FILE *__stream)
@ -277,6 +288,10 @@ void fail_test(void)
mock_fopen = true; mock_fopen = true;
assert(sc_log_set_file("prev.txt", "current.txt") == -1); assert(sc_log_set_file("prev.txt", "current.txt") == -1);
mock_fopen = false; mock_fopen = false;
mock_ftell = true;
assert(sc_log_set_file("prev.txt", "current.txt") == -1);
mock_ftell = false;
assert(sc_log_set_file("prev.txt", "current.txt") == 0); assert(sc_log_set_file("prev.txt", "current.txt") == 0);
mock_localtime_r= true; mock_localtime_r= true;
assert(sc_log_error("test") == -1); assert(sc_log_error("test") == -1);

View File

@ -6,9 +6,9 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_C_EXTENSIONS OFF)
add_library( add_library(
sc_signal SHARED sc_signal SHARED
sc_signal.c sc_signal.c
sc_signal.h) sc_signal.h)
target_include_directories(sc_signal PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(sc_signal PUBLIC ${CMAKE_CURRENT_LIST_DIR})
@ -20,18 +20,18 @@ endif ()
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# --------------------- Test Configuration Start ---------------------------- # # --------------------- Test Configuration Start ---------------------------- #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
if(SC_BUILD_TEST) if (SC_BUILD_TEST)
include(CTest) include(CTest)
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
enable_testing() enable_testing()
add_executable(${PROJECT_NAME}_test signal_test.c sc_signal.c) add_executable(${PROJECT_NAME}_test signal_test.c sc_signal.c)
target_compile_options(${PROJECT_NAME}_test PRIVATE -DSC_SIZE_MAX=1400000ul) target_compile_options(${PROJECT_NAME}_test PRIVATE -DSC_SIZE_MAX=1400000ul)
check_c_source_compiles(" check_c_source_compiles("
#include <execinfo.h> #include <execinfo.h>
#include <unistd.h> #include <unistd.h>
@ -42,80 +42,84 @@ if(SC_BUILD_TEST)
return 0; return 0;
}" HAVE_BACKTRACE) }" HAVE_BACKTRACE)
FIND_LIBRARY(EXECINFO_LIBRARY NAMES execinfo) FIND_LIBRARY(EXECINFO_LIBRARY NAMES execinfo)
IF (EXECINFO_LIBRARY) IF (EXECINFO_LIBRARY)
SET(CMAKE_REQUIRED_LIBRARIES "${EXECINFO_LIBRARY}") SET(CMAKE_REQUIRED_LIBRARIES "${EXECINFO_LIBRARY}")
ENDIF(EXECINFO_LIBRARY) ENDIF (EXECINFO_LIBRARY)
if (${HAVE_BACKTRACE}) if (${HAVE_BACKTRACE})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_BACKTRACE") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_BACKTRACE")
endif () endif ()
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
"${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-omit-frame-pointer) target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-omit-frame-pointer)
target_compile_options(${PROJECT_NAME}_test PRIVATE -DSC_HAVE_WRAP -DSC_SIGNAL_TEST) target_compile_options(${PROJECT_NAME}_test PRIVATE -DSC_HAVE_WRAP -DSC_SIGNAL_TEST)
target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-builtin) target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-builtin)
endif () target_link_options(${PROJECT_NAME}_test PRIVATE -Wl,--wrap=signal)
endif ()
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR endif ()
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang" OR endif ()
"${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-omit-frame-pointer) if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang" OR
"${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
if (SANITIZER) target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-omit-frame-pointer)
target_compile_options(${PROJECT_NAME}_test PRIVATE -fsanitize=${SANITIZER})
target_link_options(${PROJECT_NAME}_test PRIVATE -fsanitize=${SANITIZER}) if (SANITIZER)
endif () target_compile_options(${PROJECT_NAME}_test PRIVATE -fsanitize=${SANITIZER})
endif () target_link_options(${PROJECT_NAME}_test PRIVATE -fsanitize=${SANITIZER})
endif ()
endif ()
add_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test) add_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test)
SET(MEMORYCHECK_COMMAND_OPTIONS SET(MEMORYCHECK_COMMAND_OPTIONS
"-q --log-fd=2 --trace-children=yes --track-origins=yes \ "-q --log-fd=2 --trace-children=yes --track-origins=yes \
--leak-check=full --show-leak-kinds=all \ --leak-check=full --show-leak-kinds=all \
--error-exitcode=255") --error-exitcode=255")
add_custom_target(valgrind_${PROJECT_NAME} ${CMAKE_COMMAND} add_custom_target(valgrind_${PROJECT_NAME} ${CMAKE_COMMAND}
-E env CTEST_OUTPUT_ON_FAILURE=1 -E env CTEST_OUTPUT_ON_FAILURE=1
${CMAKE_CTEST_COMMAND} -C $<CONFIG> ${CMAKE_CTEST_COMMAND} -C $<CONFIG>
--overwrite MemoryCheckCommandOptions=${MEMORYCHECK_COMMAND_OPTIONS} --overwrite MemoryCheckCommandOptions=${MEMORYCHECK_COMMAND_OPTIONS}
--verbose -T memcheck WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) --verbose -T memcheck WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_custom_target(check_${PROJECT_NAME} ${CMAKE_COMMAND} add_custom_target(check_${PROJECT_NAME} ${CMAKE_COMMAND}
-E env CTEST_OUTPUT_ON_FAILURE=1 -E env CTEST_OUTPUT_ON_FAILURE=1
${CMAKE_CTEST_COMMAND} -C $<CONFIG> --verbose ${CMAKE_CTEST_COMMAND} -C $<CONFIG> --verbose
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
# ----------------------- - Code Coverage Start ----------------------------- # # ------------------------- Code Coverage Start ----------------------------- #
if (${CMAKE_BUILD_TYPE} MATCHES "Coverage") if (${CMAKE_BUILD_TYPE} MATCHES "Coverage")
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
target_compile_options(${PROJECT_NAME}_test PRIVATE --coverage) target_compile_options(${PROJECT_NAME}_test PRIVATE --coverage)
target_link_libraries(${PROJECT_NAME}_test gcov) target_link_libraries(${PROJECT_NAME}_test gcov)
else () else ()
message(FATAL_ERROR "Only GCC is supported for coverage") message(FATAL_ERROR "Only GCC is supported for coverage")
endif () endif ()
endif () endif ()
add_custom_target(coverage_${PROJECT_NAME}) add_custom_target(coverage_${PROJECT_NAME})
add_custom_command( add_custom_command(
TARGET coverage_${PROJECT_NAME} TARGET coverage_${PROJECT_NAME}
COMMAND lcov --capture --directory . COMMAND lcov --capture --directory .
--output-file coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert' --output-file coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert'
COMMAND lcov --remove coverage.info '/usr/*' '*example*' '*test*' COMMAND lcov --remove coverage.info '/usr/*' '*example*' '*test*'
--output-file coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert' --output-file coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert'
COMMAND lcov --list coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert' COMMAND lcov --list coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert'
) )
add_dependencies(coverage_${PROJECT_NAME} check_${PROJECT_NAME}) add_dependencies(coverage_${PROJECT_NAME} check_${PROJECT_NAME})
# -------------------------- Code Coverage End ------------------------------ # # -------------------------- Code Coverage End ------------------------------ #
endif () endif ()
# ----------------------- Test Configuration End ---------------------------- # # ----------------------- Test Configuration End ---------------------------- #

View File

@ -40,9 +40,9 @@
#if defined(_WIN32) #if defined(_WIN32)
#include <WinSock2.h> #include <WinSock2.h>
volatile SOCKET sc_signal_shutdown_fd; volatile SOCKET sc_signal_shutdown_fd;
#else #else
volatile sig_atomic_t sc_signal_shutdown_fd; volatile sig_atomic_t sc_signal_shutdown_fd;
#endif #endif
/** /**
@ -59,14 +59,12 @@ volatile sig_atomic_t sc_signal_will_shutdown;
#define get_uint(va, size) \ #define get_uint(va, size) \
(size) == 3 ? va_arg(va, unsigned long long) : \ (size) == 3 ? va_arg(va, unsigned long long) : \
(size) == 2 ? va_arg(va, unsigned long) : \ (size) == 2 ? va_arg(va, unsigned long) : \
(size) == 1 ? va_arg(va, unsigned int) : \ va_arg(va, unsigned int)
0
#define get_int(va, size) \ #define get_int(va, size) \
(size) == 3 ? va_arg(va, long long) : \ (size) == 3 ? va_arg(va, long long) : \
(size) == 2 ? va_arg(va, long) : \ (size) == 2 ? va_arg(va, long) : \
(size) == 1 ? va_arg(va, int) : \ va_arg(va, int)
0
#define PSIZE sizeof(void *) == sizeof(unsigned long long) ? 3 : 2 #define PSIZE sizeof(void *) == sizeof(unsigned long long) ? 3 : 2
@ -248,32 +246,24 @@ LONG WINAPI sc_signal_on_fatal(PEXCEPTION_POINTERS info)
return 0; return 0;
} }
void sc_signal_std_on_fatal(int type) void sc_signal_std_on_fatal(int sig)
{ {
char buf[128]; char buf[128];
int fd = sc_signal_log_fd != -1 ? sc_signal_log_fd : _fileno(stderr); int fd = sc_signal_log_fd != -1 ? sc_signal_log_fd : _fileno(stderr);
const char *sig_str; char *sig_str = "unknown signal";
switch (type) { if (sig == SIGSEGV) {
case SIGSEGV:
sig_str = "SIGSEGV"; sig_str = "SIGSEGV";
break; } else if (sig == SIGABRT) {
case SIGABRT:
sig_str = "SIGABRT"; sig_str = "SIGABRT";
break; } else if (sig == SIGFPE) {
case SIGFPE:
sig_str = "SIGFPE"; sig_str = "SIGFPE";
break; } else if (sig == SIGILL) {
case SIGILL:
sig_str = "SIGILL"; sig_str = "SIGILL";
break;
default:
sig_str = "Unknown signal";
break;
} }
sc_signal_log(fd, buf, sizeof(buf), sc_signal_log(fd, buf, sizeof(buf),
"Fatal signal : [%s][%d], shutting down! \n", sig_str, type); "Fatal signal : [%s][%d], shutting down! \n", sig_str, sig);
_Exit(1); _Exit(1);
} }
@ -302,7 +292,7 @@ int sc_signal_init()
#else #else
// clang-format off // clang-format off
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
@ -369,22 +359,19 @@ static void sc_signal_on_shutdown(int sig)
int fd = sc_signal_log_fd != -1 ? sc_signal_log_fd : STDOUT_FILENO; int fd = sc_signal_log_fd != -1 ? sc_signal_log_fd : STDOUT_FILENO;
char buf[4096], *sig_str = "Shutdown signal"; char buf[4096], *sig_str = "Shutdown signal";
switch (sig) { if (sig == SIGINT) {
case SIGINT:
sig_str = "SIGINT"; sig_str = "SIGINT";
break; } else if (sig == SIGTERM) {
case SIGTERM:
sig_str = "SIGTERM"; sig_str = "SIGTERM";
break;
} }
sc_signal_log(fd, buf, sizeof(buf), "Received : %s, (%d) \n", sig_str, sig); sc_signal_log(fd, buf, sizeof(buf), "Received : %s, (%d) \n", sig_str, sig);
if (sc_signal_will_shutdown != 0) { if (sc_signal_will_shutdown != 0) {
sc_signal_log(fd, buf, sizeof(buf), "Forcing shut down! \n"); sc_signal_log(fd, buf, sizeof(buf), "Forcing shut down! \n");
#ifdef SC_SIGNAL_TEST #ifdef SC_SIGNAL_TEST
return; return;
#endif #endif
_Exit(1); _Exit(1);
} }
@ -397,17 +384,17 @@ static void sc_signal_on_shutdown(int sig)
sc_signal_log(fd, buf, sizeof(buf), sc_signal_log(fd, buf, sizeof(buf),
"Failed to send shutdown command, " "Failed to send shutdown command, "
"shutting down immediately! \n"); "shutting down immediately! \n");
#ifdef SC_SIGNAL_TEST #ifdef SC_SIGNAL_TEST
return; return;
#endif #endif
_Exit(1); _Exit(1);
} }
} else { } else {
sc_signal_log(fd, buf, sizeof(buf), sc_signal_log(fd, buf, sizeof(buf),
"No shutdown handler, shutting down! \n"); "No shutdown handler, shutting down! \n");
#ifdef SC_SIGNAL_TEST #ifdef SC_SIGNAL_TEST
return; return;
#endif #endif
_Exit(0); _Exit(0);
} }
@ -423,22 +410,16 @@ static void sc_signal_on_fatal(int sig, siginfo_t *info, void *context)
char buf[4096], *sig_str = "unknown signal"; char buf[4096], *sig_str = "unknown signal";
struct sigaction act; struct sigaction act;
switch (sig) { if (sig == SIGSEGV) {
case SIGSEGV:
sig_str = "SIGSEGV"; sig_str = "SIGSEGV";
break; } else if (sig == SIGABRT) {
case SIGABRT:
sig_str = "SIGABRT"; sig_str = "SIGABRT";
break; } else if (sig == SIGBUS) {
case SIGBUS:
sig_str = "SIGBUS"; sig_str = "SIGBUS";
break; } else if (sig == SIGFPE) {
case SIGFPE:
sig_str = "SIGFPE"; sig_str = "SIGFPE";
break; } else if (sig == SIGILL) {
case SIGILL:
sig_str = "SIGILL"; sig_str = "SIGILL";
break;
} }
sc_signal_log(fd, buf, sizeof(buf), "\nSignal received : [%d][%s] \n", sig, sc_signal_log(fd, buf, sizeof(buf), "\nSignal received : [%d][%s] \n", sig,
@ -493,6 +474,10 @@ int sc_signal_init()
rc &= (sigaction(SIGTERM, &action, NULL) == 0); rc &= (sigaction(SIGTERM, &action, NULL) == 0);
rc &= (sigaction(SIGINT, &action, NULL) == 0); rc &= (sigaction(SIGINT, &action, NULL) == 0);
#ifdef SC_SIGNAL_TEST
rc &= (sigaction(SIGUSR2, &action, NULL) == 0);
#endif
rc &= (sigemptyset(&action.sa_mask) == 0); rc &= (sigemptyset(&action.sa_mask) == 0);
action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO; action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
action.sa_sigaction = sc_signal_on_fatal; action.sa_sigaction = sc_signal_on_fatal;
@ -503,6 +488,10 @@ int sc_signal_init()
rc &= (sigaction(SIGFPE, &action, NULL) == 0); rc &= (sigaction(SIGFPE, &action, NULL) == 0);
rc &= (sigaction(SIGILL, &action, NULL) == 0); rc &= (sigaction(SIGILL, &action, NULL) == 0);
#ifdef SC_SIGNAL_TEST
rc &= (sigaction(SIGSYS, &action, NULL) == 0);
#endif
return rc ? 0 : -1; return rc ? 0 : -1;
} }

View File

@ -47,12 +47,24 @@ void test2()
} }
#ifdef SC_HAVE_WRAP #ifdef SC_HAVE_WRAP
#include <signal.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <wait.h> #include <wait.h>
bool fail_signal;
extern void (*__real_signal(int sig, void (*func)(int)))(int);
void (*__wrap_signal(int sig, void (*func)(int)))(int)
{
if (fail_signal) {
return SIG_ERR;
}
return __real_signal(sig, func);
}
void sig_handler(int signum) void sig_handler(int signum)
{ {
(void) signum; (void) signum;
@ -85,8 +97,11 @@ void test3()
test3x(SIGABRT); test3x(SIGABRT);
test3x(SIGBUS); test3x(SIGBUS);
test3x(SIGFPE); test3x(SIGFPE);
sc_signal_log_fd = STDOUT_FILENO;
test3x(SIGILL); test3x(SIGILL);
sc_signal_log_fd = -1;
test3x(SIGUSR1); test3x(SIGUSR1);
test3x(SIGSYS);
} }
@ -106,6 +121,7 @@ void test4x(int signal)
} }
} else { } else {
assert(sc_signal_init() == 0); assert(sc_signal_init() == 0);
sc_signal_log_fd = STDOUT_FILENO;
sc_signal_shutdown_fd = STDOUT_FILENO; sc_signal_shutdown_fd = STDOUT_FILENO;
printf("Running child \n"); printf("Running child \n");
raise(signal); raise(signal);
@ -119,6 +135,7 @@ void test4()
{ {
test4x(SIGINT); test4x(SIGINT);
test4x(SIGTERM); test4x(SIGTERM);
test4x(SIGUSR2);
} }
void test5() void test5()
@ -217,6 +234,13 @@ void test8()
} }
} }
void test9()
{
fail_signal = true;
assert(sc_signal_init() != 0);
fail_signal = false;
}
#else #else
void test3() void test3()
{ {
@ -235,6 +259,10 @@ void test7()
} }
void test8() void test8()
{ {
}
void test9()
{
} }
#endif #endif
@ -248,6 +276,7 @@ int main()
test6(); test6();
test7(); test7();
test8(); test8();
test9();
return 0; return 0;
} }

View File

@ -42,7 +42,8 @@ if(SC_BUILD_TEST)
-Wl,--wrap=close,--wrap=malloc,--wrap=realloc,--wrap=epoll_create1 -Wl,--wrap=close,--wrap=malloc,--wrap=realloc,--wrap=epoll_create1
-Wl,--wrap=setsockopt,--wrap=listen,--wrap=fcntl,--wrap=socket -Wl,--wrap=setsockopt,--wrap=listen,--wrap=fcntl,--wrap=socket
-Wl,--wrap=inet_ntop,--wrap=send,--wrap=recv,--wrap=connect -Wl,--wrap=inet_ntop,--wrap=send,--wrap=recv,--wrap=connect
-Wl,--wrap=write,--wrap=read,--wrap=epoll_ctl) -Wl,--wrap=write,--wrap=read,--wrap=epoll_ctl,--wrap=getsockopt
-Wl,--wrap=epoll_wait,--wrap=getsockname)
endif () endif ()
endif () endif ()

View File

@ -376,7 +376,7 @@ void test1()
assert(sc_sock_connect(&sock, "dsadas", "2131", NULL, "50") != 0); assert(sc_sock_connect(&sock, "dsadas", "2131", NULL, "50") != 0);
assert(sc_sock_connect(&sock, "dsadas", "2131", "s", NULL) != 0); assert(sc_sock_connect(&sock, "dsadas", "2131", "s", NULL) != 0);
assert(sc_sock_connect(&sock, "127.0.01", "2131", "100.0.0.0", NULL) != 0); assert(sc_sock_connect(&sock, "127.0.01", "2131", "100.0.0.0", NULL) != 0);
assert(sc_sock_connect(&sock, "127.0.01", "2131", NULL, "9000") != 0); assert(sc_sock_connect(&sock, "127.0.01", "2131", NULL, "9000") != 0);
sc_sock_term(&sock); sc_sock_term(&sock);
sc_sock_init(&sock, 0, false, SC_SOCK_INET); sc_sock_init(&sock, 0, false, SC_SOCK_INET);
@ -497,7 +497,7 @@ int sc_mutex_init(struct sc_mutex *mtx)
// This won't fail as long as we pass correct params. // This won't fail as long as we pass correct params.
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
assert (rc == 0); assert(rc == 0);
// May fail on OOM // May fail on OOM
rc = pthread_mutex_init(&mtx->mtx, &attr); rc = pthread_mutex_init(&mtx->mtx, &attr);
@ -634,7 +634,7 @@ int __wrap_fcntl(int fd, int cmd, ...)
if (test_done) { if (test_done) {
va_list va; va_list va;
va_start(va, cmd); va_start(va, cmd);
void* t = va_arg(va, void*); void *t = va_arg(va, void *);
return __real_fcntl(fd, cmd, t); return __real_fcntl(fd, cmd, t);
} }
@ -661,6 +661,37 @@ int __wrap_fcntl(int fd, int cmd, ...)
return -1; return -1;
} }
int fail_getsockopt;
int fail_getsockopt_result;
extern int __real_getsockopt(int fd, int level, int optname,
void *restrict optval, socklen_t *restrict optlen);
extern int __wrap_getsockopt(int fd, int level, int optname,
void *restrict optval, socklen_t *restrict optlen)
{
if (fail_getsockopt) {
*(int *) optval = fail_getsockopt_result;
return fail_getsockopt_result != 0 ? 0 : 10;
}
return __real_getsockopt(fd, level, optname, optval, optlen);
}
int fail_epoll_wait;
extern int __real_epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
extern int __wrap_epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout)
{
if (fail_epoll_wait) {
fail_epoll_wait = 0;
errno = EINTR;
return -1;
}
return __real_epoll_wait(epfd, events, maxevents, timeout);
}
int fail_socket = false; int fail_socket = false;
int __real_socket(int domain, int type, int protocol); int __real_socket(int domain, int type, int protocol);
int __wrap_socket(int domain, int type, int protocol) int __wrap_socket(int domain, int type, int protocol)
@ -768,6 +799,19 @@ int __wrap_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
return __real_epoll_ctl(epfd, op, fd, event); return __real_epoll_ctl(epfd, op, fd, event);
} }
int fail_getsockname;
int __real_getsockname (int fd, struct sockaddr * addr, socklen_t * len);
int __wrap_getsockname (int fd, struct sockaddr * addr, socklen_t * len)
{
if (fail_getsockname) {
struct sockaddr_storage* str = (struct sockaddr_storage*)addr;
str->ss_family = AF_BRIDGE;
return 0;
}
return __real_getsockname(fd, addr, len);
}
void poll_fail_test() void poll_fail_test()
{ {
bool fail; bool fail;
@ -776,6 +820,11 @@ void poll_fail_test()
struct sc_sock_poll poll; struct sc_sock_poll poll;
struct sc_sock_pipe pipe[301]; struct sc_sock_pipe pipe[301];
assert(sc_sock_poll_init(&poll) == 0);
fail_epoll_wait = 1;
assert(sc_sock_poll_wait(&poll, 10) == 0);
assert(sc_sock_poll_term(&poll) == 0);
assert(sc_sock_poll_init(&poll) == 0); assert(sc_sock_poll_init(&poll) == 0);
sc_sock_init(&sock, 0, true, AF_INET); sc_sock_init(&sock, 0, true, AF_INET);
fail_epoll_ctl = true; fail_epoll_ctl = true;
@ -1197,6 +1246,14 @@ void sock_fail_test2()
sc_sock_print(&client, NULL, 0); sc_sock_print(&client, NULL, 0);
fail_inet_ntop = INT32_MAX; fail_inet_ntop = INT32_MAX;
assert(sc_sock_term(&client) == 0); assert(sc_sock_term(&client) == 0);
char buf[128];
sc_sock_init(&client, 0, false, SC_SOCK_INET);
sc_sock_listen(&client, "127.0.0.1", "8080");
fail_getsockname = 1;
sc_sock_print(&client, buf, 128);
fail_getsockname = 0;
assert(sc_sock_term(&client) == 0);
} }
void sock_fail_test3() void sock_fail_test3()
@ -1272,6 +1329,14 @@ void sock_fail_test3()
fail_connect_err = 0; fail_connect_err = 0;
fail_connect = 0; fail_connect = 0;
assert(sc_sock_term(&client) == 0); assert(sc_sock_term(&client) == 0);
sc_sock_init(&client, 0, false, SC_SOCK_INET);
assert(sc_sock_finish_connect(&client) != 0);
fail_getsockopt = 1;
fail_getsockopt_result = -1;
assert(sc_sock_finish_connect(&client) != 0);
fail_getsockopt = 0;
sc_sock_term(&client);
} }
#else #else

View File

@ -111,7 +111,7 @@ char *sc_str_create_va(const char *fmt, va_list va)
memcpy(str->buf, tmp, str->len + 1); memcpy(str->buf, tmp, str->len + 1);
} else { } else {
va_copy(args, va); va_copy(args, va);
rc = vsnprintf(str->buf, str->len, fmt, args); rc = vsnprintf(str->buf, str->len + 1, fmt, args);
va_end(args); va_end(args);
if (rc < 0 || (uint32_t) rc > str->len) { if (rc < 0 || (uint32_t) rc > str->len) {
@ -272,7 +272,7 @@ void sc_str_token_end(char *str, char **save)
return; return;
} }
swap(str, (save != NULL && *save != NULL) ? *save : str + strlen(str)); swap(str, *save);
} }
bool sc_str_trim(char **str, const char *list) bool sc_str_trim(char **str, const char *list)

View File

@ -235,7 +235,27 @@ void test2()
fail_vsnprintf_at = -1; fail_vsnprintf_at = -1;
fail_vnsprintf_value = -1; fail_vnsprintf_value = -1;
char *x1 = sc_str_create_fmt("%s", tmp);
assert(x1 != NULL);
assert(strcmp(x1, tmp) == 0);
for (int i =0 ; i < 1499; i++) {
assert(tmp[i] == x1[i]);
}
sc_str_destroy(x1);
free(tmp); free(tmp);
x1 = NULL;
for (int i = 0; i < 4000; i++) {
sc_str_append_fmt(&x1, "%s", "x");
}
for (int i = 0; i < 4000; i++) {
assert(x1[i] == 'x');
}
assert(sc_str_len(x1) == 4000);
sc_str_destroy(x1);
} }
#endif #endif
@ -298,6 +318,30 @@ void test3()
} }
sc_str_token_end(str, &save); sc_str_token_end(str, &save);
sc_str_destroy(str); sc_str_destroy(str);
str = sc_str_create("x,x");
save = NULL;
sc_str_token_end(str, &save);
sc_str_destroy(str);
str = sc_str_create("x,x");
save = NULL;
while ((token = sc_str_token_begin(str, &save, ",")) != NULL) {
assert(strcmp(token, "x") == 0);
break;
}
sc_str_token_end(str, &save);
sc_str_destroy(str);
str = sc_str_create("x,x");
save = NULL;
while ((token = sc_str_token_begin(str, &save, ",")) != NULL) {
assert(strcmp(token, "x") == 0);
break;
}
sc_str_token_end(str, &save);
sc_str_token_end(str, &save);
sc_str_destroy(str);
} }
void test4() void test4()
@ -360,7 +404,7 @@ void test4()
} }
} }
sc_str_token_end(str, NULL); sc_str_token_end(str, &save);
assert(strcmp(str, "tk1;tk2-tk3 tk4 tk5*tk6") == 0); assert(strcmp(str, "tk1;tk2-tk3 tk4 tk5*tk6") == 0);
sc_str_destroy(str); sc_str_destroy(str);