lib

morphux C utility library
Log | Files | Refs | Submodules | README | LICENSE | git clone https://git.ne02ptzero.me/git/lib

commit 2798ebae9cc659e482442e3d120c4ee1f3966f9a
parent 64bc83890178c71e4cf5ba9f14ec5ad4ce027b2f
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Fri,  3 Mar 2017 14:15:16 +0100

Add(Tests for m_log):

Now can trigger syscall / external function fail

Diffstat:
MMakefile | 8+++++---
Ainc/fail_test.h | 38++++++++++++++++++++++++++++++++++++++
Minc/m_args.h | 1+
Minc/m_infos.h | 1+
Minc/m_list.h | 1+
Minc/m_print.h | 1+
Minc/morphux.h | 2++
Msrc/m_print.c | 84++++++++++++++++++++++++++++++++++++++++----------------------------------------
Asrc/test.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/test.h | 1+
Mtests/test_print.c | 227++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
11 files changed, 371 insertions(+), 93 deletions(-)

diff --git a/Makefile b/Makefile @@ -24,9 +24,9 @@ OBJS = $(SRCS:%.c=%.o) OSTYPE = $(shell uname) ifeq ($(OSTYPE), Linux) -COVFLAGS = "-Wall -Wextra -Wno-unused-result -I inc/ -std=c99 -g -O0 -coverage -lgcov" +COVFLAGS = "-Wall -Wextra -Wno-unused-result -I inc/ -std=c99 -g -O0 -coverage -lgcov -DCOMPILE_WITH_TEST" else ifeq ($(OSTYPE), Darwin) -COVFLAGS = "-Wall -Wextra -Wno-unused-result -I inc/ -std=c99 -g -O0 -coverage" +COVFLAGS = "-Wall -Wextra -Wno-unused-result -I inc/ -std=c99 -g -O0 -coverage -DCOMPILE_WITH_TEST" endif all: $(NAME) @@ -35,7 +35,8 @@ $(NAME): $(OBJS) $(LIB) $(LFLAGS) $(NAME) $(OBJS) check: all - make -C tests check + $(MAKE) fclean all CFLAGS="$(CFLAGS) -DCOMPILE_WITH_TEST" + make -C tests re check doc: doxygen docs/doxyfile @@ -43,6 +44,7 @@ doc: coverage: $(MAKE) fclean all CFLAGS=$(COVFLAGS) make -C tests coverage check + rm src/test.gc* gcov -o src/ $(SRCS) clean: diff --git a/inc/fail_test.h b/inc/fail_test.h @@ -0,0 +1,38 @@ +/*********************************** LICENSE **********************************\ +* Copyright 2017 Morphux * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +\******************************************************************************/ + +#ifdef COMPILE_WITH_TEST +# ifndef M_FAIL_TEST_H +# define M_FAIL_TEST_H + +# define malloc(x) fl_malloc(x) +# define write(fd, ptr, len) fl_write(fd, ptr, len) +# define read(fd, ptr, len) fl_read(fd, ptr, len) +# define close(fd) fl_close(fd) + +void *fl_malloc(size_t alloc); +ssize_t fl_write(int fd, const void *ptr, size_t len); +ssize_t fl_read(int fd, void *ptr, size_t len); +int fl_close(int fd); + +void set_malloc_fail(int val); +void set_write_fail(int val); +void set_read_fail(int val); +void set_close_fail(int val); + + +# endif /* M_FAIL_TEST_H */ +#endif /* COMPILE_WITH_TEST */ diff --git a/inc/m_args.h b/inc/m_args.h @@ -22,6 +22,7 @@ # include <m_types.h> # include <m_print.h> # include <m_infos.h> +# include <morphux.h> typedef struct s_args { /** diff --git a/inc/m_infos.h b/inc/m_infos.h @@ -19,6 +19,7 @@ # include <stdio.h> # include <string.h> +# include <morphux.h> # define INFOS_G_LEN_MAX 150 diff --git a/inc/m_list.h b/inc/m_list.h @@ -21,6 +21,7 @@ # include <stdlib.h> /* malloc */ # include <assert.h> /* assert */ # include <string.h> /* mem{cpy,move,cmp} */ +# include <morphux.h> /* Linked list */ typedef struct s_list { diff --git a/inc/m_print.h b/inc/m_print.h @@ -27,6 +27,7 @@ # include <unistd.h> # include <stdbool.h> # include <m_types.h> +# include <morphux.h> # define M_LOG_NONE (1 << 0) # define M_LOG_FORCE (1 << 2) diff --git a/inc/morphux.h b/inc/morphux.h @@ -26,4 +26,6 @@ # include <m_list.h> # include <m_test.h> +# include <fail_test.h> + #endif /* MORPHUX_H */ diff --git a/src/m_print.c b/src/m_print.c @@ -1,18 +1,18 @@ /*********************************** LICENSE **********************************\ -* Copyright 2017 Morphux * -* * -* Licensed under the Apache License, Version 2.0 (the "License"); * -* you may not use this file except in compliance with the License. * -* You may obtain a copy of the License at * -* * -* http://www.apache.org/licenses/LICENSE-2.0 * -* * -* Unless required by applicable law or agreed to in writing, software * -* distributed under the License is distributed on an "AS IS" BASIS, * -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * -* See the License for the specific language governing permissions and * -* limitations under the License. * -\******************************************************************************/ + * Copyright 2017 Morphux * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); * + * you may not use this file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + \******************************************************************************/ #include <m_print.h> @@ -29,7 +29,7 @@ static u8_t g_log_flags = M_LOG_NONE; * will be written in the log file. */ bool m_init_log(const char *file, u8_t flags) { - u8_t open_flags = O_CREAT; + u32_t open_flags = O_CREAT | O_WRONLY | O_ASYNC; int fd; if (flags & M_LOG_TRUNC) { @@ -37,8 +37,8 @@ bool m_init_log(const char *file, u8_t flags) { } else { open_flags |= O_APPEND; } - fd = open(file, open_flags, 0655); - if (fd != 0) { + fd = open(file, open_flags, 0662); + if (fd != -1) { if (flags & M_LOG_FORCE) g_log_flags |= M_LOG_FORCE; g_log_fd = fd; @@ -72,19 +72,19 @@ static bool m_log_v(const char *str, va_list ap) { * \note Support printf format */ void m_panic(const char *str, ...) { - va_list ap; + va_list ap; - va_start(ap, str); + va_start(ap, str); if (g_log_flags & M_LOG_FORCE) { m_log_v(str, ap); } else { - write(2, "\033[0;31m> \033[0m", 13); - vfprintf(stderr, str, ap); - if (str[strlen(str) - 1] != '\n') - fprintf(stderr, "\n"); + write(2, "\033[0;31m> \033[0m", 13); + vfprintf(stderr, str, ap); + if (str[strlen(str) - 1] != '\n') + fprintf(stderr, "\n"); } - va_end(ap); - exit(1); + va_end(ap); + exit(1); } /*! @@ -92,18 +92,18 @@ void m_panic(const char *str, ...) { * \note Support printf format */ void m_error(const char *str, ...) { - va_list ap; + va_list ap; - va_start(ap, str); + va_start(ap, str); if (g_log_flags & M_LOG_FORCE) { m_log_v(str, ap); } else { - write(2, "\033[0;31m> \033[0m", 13); - vfprintf(stderr, str, ap); - if (str[strlen(str) - 1] != '\n') - fprintf(stderr, "\n"); + write(2, "\033[0;31m> \033[0m", 13); + vfprintf(stderr, str, ap); + if (str[strlen(str) - 1] != '\n') + fprintf(stderr, "\n"); } - va_end(ap); + va_end(ap); } /*! @@ -111,16 +111,16 @@ void m_error(const char *str, ...) { * \note Support printf format */ void m_warning(const char *str, ...) { - va_list ap; + va_list ap; - va_start(ap, str); + va_start(ap, str); if (g_log_flags & M_LOG_FORCE) { m_log_v(str, ap); } else { - write(2, "\033[0;31m> \033[0m", 13); - vfprintf(stderr, str, ap); + write(2, "\033[0;31m> \033[0m", 13); + vfprintf(stderr, str, ap); } - va_end(ap); + va_end(ap); } /*! @@ -128,16 +128,16 @@ void m_warning(const char *str, ...) { * \note Support printf format */ void m_info(const char *str, ...) { - va_list ap; + va_list ap; - va_start(ap, str); + va_start(ap, str); if (g_log_flags & M_LOG_FORCE) { m_log_v(str, ap); } else { - write(1, "\033[0;34m> \033[0m", 13); - vprintf(str, ap); + write(1, "\033[0;34m> \033[0m", 13); + vprintf(str, ap); } - va_end(ap); + va_end(ap); } /*! diff --git a/src/test.c b/src/test.c @@ -0,0 +1,100 @@ +/*********************************** LICENSE **********************************\ +* Copyright 2017 Morphux * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +\******************************************************************************/ + +#ifdef COMPILE_WITH_TEST +# include <stdlib.h> +# include <sys/types.h> +# include <fcntl.h> +# include <unistd.h> + +/* Real functions */ +static void *(*real_malloc)(size_t) = &malloc; +static ssize_t (*real_write)(int, const void *, size_t) = &write; +static ssize_t (*real_read)(int, void *, size_t) = &read; +static int (*real_close)(int) = &close; + +# include <fail_test.h> + +static int g_malloc_fail = -1; +static int g_write_fail = -1; +static int g_read_fail = -1; +static int g_close_fail = -1; + +void *fl_malloc(size_t alloc) { + if (g_malloc_fail == -1) + return real_malloc(alloc); + if (g_malloc_fail == 0) { + g_malloc_fail = -1; + return NULL; + } + g_malloc_fail--; + return real_malloc(alloc); +} + +ssize_t fl_write(int fd, const void *ptr, size_t len) { + if (g_write_fail == -1) + return real_write(fd, ptr, len); + if (g_write_fail == 0) { + g_write_fail = -1; + return -1; + } + g_write_fail--; + return real_write(fd, ptr, len); +} + +ssize_t fl_read(int fd, void *ptr, size_t len) { + if (g_read_fail == -1) + return real_read(fd, ptr, len); + if (g_read_fail == 0) { + g_read_fail = -1; + return -1; + } + g_read_fail--; + return real_read(fd, ptr, len); +} + +int fl_close(int fd) { + if (g_close_fail == -1) + return real_close(fd); + if (g_close_fail == 0) { + g_close_fail = -1; + return -1; + } + g_close_fail--; + return real_close(fd); +} + +void set_malloc_fail(int val) { + if (g_malloc_fail == -1) + g_malloc_fail = val; +} + +void set_write_fail(int val) { + if (g_write_fail == -1) + g_write_fail = val; +} + +void set_read_fail(int val) { + if (g_read_fail == -1) + g_read_fail = val; +} + +void set_close_fail(int val) { + if (g_close_fail == -1) + g_close_fail = val; +} + +#endif /* COMPILE_WITH_TEST */ diff --git a/tests/test.h b/tests/test.h @@ -1,5 +1,6 @@ #ifndef TEST_H # define TEST_H +# define COMPILE_WITH_TEST # include <morphux.h> # include <unistd.h> diff --git a/tests/test_print.c b/tests/test_print.c @@ -1,68 +1,199 @@ #include "test.h" TEST(print_info) { - int st, fd[2]; - pid_t pid; + int st, fd[2]; + pid_t pid; - pipe(fd); - if ((pid = fork()) == 0) { - DUP_ALL_OUTPUTS(fd); - m_info("Test"); - exit(0); - } else { - WAIT_AND_CLOSE(pid, st, fd); - } - return TEST_SUCCESS; + pipe(fd); + if ((pid = fork()) == 0) { + DUP_ALL_OUTPUTS(fd); + m_info("Test"); + exit(0); + } else { + WAIT_AND_CLOSE(pid, st, fd); + } + return TEST_SUCCESS; } TEST(print_warning) { - int st, fd[2]; - pid_t pid; + int st, fd[2]; + pid_t pid; - pipe(fd); - if ((pid = fork()) == 0) { - DUP_ALL_OUTPUTS(fd); - m_warning("Test"); - exit(0); - } else { - WAIT_AND_CLOSE(pid, st, fd); - } - return TEST_SUCCESS; + pipe(fd); + if ((pid = fork()) == 0) { + DUP_ALL_OUTPUTS(fd); + m_warning("Test"); + exit(0); + } else { + WAIT_AND_CLOSE(pid, st, fd); + } + return TEST_SUCCESS; } TEST(print_error) { - int st, fd[2]; - pid_t pid; + int st, fd[2]; + pid_t pid; - pipe(fd); - if ((pid = fork()) == 0) { - DUP_ALL_OUTPUTS(fd); - m_error("Test"); - exit(0); - } else { - WAIT_AND_CLOSE(pid, st, fd); - } - return TEST_SUCCESS; + pipe(fd); + if ((pid = fork()) == 0) { + DUP_ALL_OUTPUTS(fd); + m_error("Test"); + exit(0); + } else { + WAIT_AND_CLOSE(pid, st, fd); + } + return TEST_SUCCESS; } TEST(print_panic) { - int st, fd[2]; - pid_t pid; + int st, fd[2]; + pid_t pid; - pipe(fd); - if ((pid = fork()) == 0) { - DUP_ALL_OUTPUTS(fd); - m_panic("Test"); - exit(0); - } else { - WAIT_AND_CLOSE(pid, st, fd); - } - return TEST_SUCCESS; + pipe(fd); + if ((pid = fork()) == 0) { + DUP_ALL_OUTPUTS(fd); + m_panic("Test"); + exit(0); + } else { + WAIT_AND_CLOSE(pid, st, fd); + } + return TEST_SUCCESS; } +TEST(print_log_err) { + TEST_ASSERT(m_log("Balec/20") == false, "Return is wrong"); + return TEST_SUCCESS; +} + +#define TEST_LOG_FN "/tmp/lib_test.log" + +TEST(print_log_init) { + TEST_ASSERT(m_init_log(TEST_LOG_FN, M_LOG_NONE) == true, "Return is wrong"); + return TEST_SUCCESS; +} + +TEST(print_log_1) { + TEST_ASSERT(m_log("Test %d", 123) == true, "Return is wrong"); + int fd = open(TEST_LOG_FN, O_RDONLY); + char buf[8]; + + TEST_ASSERT(fd != 0, "Can't open the log file"); + TEST_ASSERT(read(fd, buf, 8) == 8, "Read return is wrong"); + TEST_ASSERT(memcmp(buf, "Test 123", 8) == 0, "Content of the file is wrong"); + return TEST_SUCCESS; +} + +TEST(print_clean_log_1) { + set_close_fail(0); + TEST_ASSERT(m_clean_log() == false, "Return is wrong"); + return TEST_SUCCESS; +} + +TEST(print_clean_log_2) { + TEST_ASSERT(m_clean_log() == true, "Return is wrong"); + return TEST_SUCCESS; +} + +TEST(print_clean_log_3) { + TEST_ASSERT(m_clean_log() == true, "Return is wrong"); + return TEST_SUCCESS; +} + +TEST(print_log_init_2) { + TEST_ASSERT(m_init_log(TEST_LOG_FN, M_LOG_FORCE | M_LOG_TRUNC) == true, "Return is wrong"); + TEST_ASSERT(m_clean_log() == true, "Return is wrong"); + return TEST_SUCCESS; +} + +TEST(print_log_init_err) { + TEST_ASSERT(m_init_log("/nonsense/path", M_LOG_NONE) == false, "Return is wrong"); + return TEST_SUCCESS; +} + +TEST(print_log_minfo) { + TEST_ASSERT(m_init_log(TEST_LOG_FN, M_LOG_FORCE | M_LOG_TRUNC) == true, "Return is wrong"); + m_info("Test 123"); + + int fd = open(TEST_LOG_FN, O_RDONLY); + char buf[8]; + + TEST_ASSERT(fd != 0, "Can't open the log file"); + TEST_ASSERT(read(fd, buf, 8) == 8, "Read return is wrong"); + TEST_ASSERT(memcmp(buf, "Test 123", 8) == 0, "Content of the file is wrong"); + TEST_ASSERT(m_clean_log() == true, "Return is wrong"); + return TEST_SUCCESS; +} + +TEST(print_log_mwarning) { + TEST_ASSERT(m_init_log(TEST_LOG_FN, M_LOG_FORCE | M_LOG_TRUNC) == true, "Return is wrong"); + m_warning("Test 123"); + + int fd = open(TEST_LOG_FN, O_RDONLY); + char buf[8]; + + TEST_ASSERT(fd != 0, "Can't open the log file"); + TEST_ASSERT(read(fd, buf, 8) == 8, "Read return is wrong"); + TEST_ASSERT(memcmp(buf, "Test 123", 8) == 0, "Content of the file is wrong"); + TEST_ASSERT(m_clean_log() == true, "Return is wrong"); + return TEST_SUCCESS; +} + +TEST(print_log_merror) { + TEST_ASSERT(m_init_log(TEST_LOG_FN, M_LOG_FORCE | M_LOG_TRUNC) == true, "Return is wrong"); + m_error("Test 123"); + + int fd = open(TEST_LOG_FN, O_RDONLY); + char buf[8]; + + TEST_ASSERT(fd != 0, "Can't open the log file"); + TEST_ASSERT(read(fd, buf, 8) == 8, "Read return is wrong"); + TEST_ASSERT(memcmp(buf, "Test 123", 8) == 0, "Content of the file is wrong"); + TEST_ASSERT(m_clean_log() == true, "Return is wrong"); + return TEST_SUCCESS; +} + + +TEST(print_log_mpanic) { + TEST_ASSERT(m_init_log(TEST_LOG_FN, M_LOG_FORCE | M_LOG_TRUNC) == true, "Return is wrong"); + + int st, p_fd[2]; + pid_t pid; + + pipe(p_fd); + if ((pid = fork()) == 0) { + DUP_ALL_OUTPUTS(p_fd); + m_panic("Test 123"); + } else { + WAIT_AND_CLOSE(pid, st, p_fd); + } + + int fd = open(TEST_LOG_FN, O_RDONLY); + char buf[8]; + + TEST_ASSERT(fd != 0, "Can't open the log file"); + TEST_ASSERT(read(fd, buf, 8) == 8, "Read return is wrong"); + TEST_ASSERT(memcmp(buf, "Test 123", 8) == 0, "Content of the file is wrong"); + TEST_ASSERT(m_clean_log() == true, "Return is wrong"); + return TEST_SUCCESS; +} + + + void register_print_tests(void) { - reg_test("mprint", print_info); - reg_test("mprint", print_warning); - reg_test("mprint", print_error); - reg_test("mprint", print_panic); + reg_test("mprint", print_info); + reg_test("mprint", print_warning); + reg_test("mprint", print_error); + reg_test("mprint", print_panic); + reg_test("mprint", print_log_err); + reg_test("mprint", print_log_init); + reg_test("mprint", print_log_1); + reg_test("mprint", print_clean_log_1); + reg_test("mprint", print_clean_log_2); + reg_test("mprint", print_clean_log_3); + reg_test("mprint", print_log_init_2); + reg_test("mprint", print_log_init_err); + reg_test("mprint", print_log_minfo); + reg_test("mprint", print_log_mwarning); + reg_test("mprint", print_log_merror); + reg_test("mprint", print_log_mpanic); }