diff options
| author | peter <peter@pmikkelsen.com> | 2026-08-20 20:54:43 +0000 |
|---|---|---|
| committer | peter <peter@pmikkelsen.com> | 2026-08-20 20:54:43 +0000 |
| commit | 86feda786f115cb4468957f00b8968b986ed7c54 (patch) | |
| tree | 31228cf73674178764cd6376d483e76212181707 | |
| parent | f5d445afa10ed7ba03b0ea9a5274f11904220700 (diff) | |
Get full coverage of aplwc-repl.
This required wrapping malloc so that it can fail under our control.
FossilOrigin-Name: a27ccb5f02994393a518419bae15fd26ff0016c734d96350ae2137a1d3c0937c
| -rw-r--r-- | CMakeLists.txt | 32 | ||||
| -rw-r--r-- | src/bin/aplwc_repl.h | 23 | ||||
| -rw-r--r-- | src/bin/main.c | 19 | ||||
| -rw-r--r-- | src/bin/util.c | 17 | ||||
| -rw-r--r-- | src/bin/wrappers.c | 40 | ||||
| -rw-r--r-- | src/include/aplwc.h | 2 | ||||
| -rw-r--r-- | src/include/aplwc_macros.h | 20 | ||||
| -rw-r--r-- | src/lib/aplwc_internal.h | 16 | ||||
| -rw-r--r-- | src/lib/main.c | 4 | ||||
| -rw-r--r-- | tests/aplwc_errstr.c | 4 | ||||
| -rw-r--r-- | tests/aplwc_new.c | 4 | ||||
| -rwxr-xr-x | tools/checkcov | 6 |
12 files changed, 149 insertions, 38 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index c0e8af0..18aaeb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,8 @@ target_link_libraries(aplwc PRIVATE common) add_executable(aplwc-repl src/bin/main.c + src/bin/util.c + src/bin/wrappers.c ) target_link_libraries(aplwc-repl PRIVATE common aplwc) @@ -67,4 +69,34 @@ foreach(source ${TEST_SOURCES}) add_test(NAME "${name}" COMMAND "${test_bin}") endforeach() +add_test(NAME "aplwc-repl-tiny" COMMAND "aplwc-repl") +set_tests_properties("aplwc-repl-tiny" PROPERTIES + ENVIRONMENT "APLWC_MEM=16" + WILL_FAIL TRUE +) + +add_test(NAME "aplwc-repl-emptyvar" COMMAND "aplwc-repl") +set_tests_properties("aplwc-repl-emptyvar" PROPERTIES + ENVIRONMENT "APLWC_MEM=" +) + +add_test(NAME "aplwc-repl-badvar" COMMAND "aplwc-repl") +set_tests_properties("aplwc-repl-badvar" PROPERTIES + ENVIRONMENT "APLWC_MEM=1M" +) + add_test(NAME "aplwc-repl" COMMAND "aplwc-repl") + +set(REQUIRED_MALLOCS 1) +foreach(i RANGE 0 ${REQUIRED_MALLOCS}) + set(name "aplwc-repl-${i}-${REQUIRED_MALLOCS}") + add_test(NAME "${name}" COMMAND "aplwc-repl") + set_tests_properties("${name}" PROPERTIES + ENVIRONMENT "APLWC_MALLOC_FAIL_AFTER=${i}" + ) + if(NOT i EQUAL ${REQUIRED_MALLOCS} AND NOT CMAKE_BUILD_TYPE STREQUAL "Release") + set_tests_properties("${name}" PROPERTIES + WILL_FAIL TRUE + ) + endif() +endforeach() diff --git a/src/bin/aplwc_repl.h b/src/bin/aplwc_repl.h new file mode 100644 index 0000000..c189b77 --- /dev/null +++ b/src/bin/aplwc_repl.h @@ -0,0 +1,23 @@ +#ifndef APLWC_REPL_H +#define APLWC_REPL_H + +#include <assert.h> +#include <limits.h> +#include <stdint.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <aplwc.h> +#include <aplwc_macros.h> + +/* util.c */ +unsigned long getenv_ulong(const char *, unsigned long); + +/* wrappers.c */ +void *wrapped_malloc(size_t); +void wrapped_free(void *); +#define malloc(size) wrapped_malloc(size) +#define free(ptr) wrapped_free(ptr) + +#endif /* APLWC_REPL_H */ diff --git a/src/bin/main.c b/src/bin/main.c index 2538248..80b2ee0 100644 --- a/src/bin/main.c +++ b/src/bin/main.c @@ -1,6 +1,5 @@ #include <stdio.h> -#include <stdlib.h> -#include <aplwc.h> +#include "aplwc_repl.h" int main(void) @@ -8,24 +7,24 @@ main(void) struct aplwc *aplwc; uint8_t *data; int ret; + size_t memsize; - data = malloc(APLWC_MIN_MEM); + memsize = getenv_ulong("APLWC_MEM", APLWC_MIN_MEM); + + data = malloc(memsize); if(data == NULL){ fprintf(stderr, "Couldn't allocate memory\n"); return 1; } - ret = aplwc_new(&aplwc, data, APLWC_MIN_MEM); + ret = aplwc_new(&aplwc, data, memsize); if(ret){ - fprintf(stderr, "Couldn't create new aplwc instance: %s\n", aplwc_errstr(aplwc)); + fprintf(stderr, "Couldn't create new aplwc instance: %s\n", aplwc_errstr_rc(ret)); + free(data); return 1; } - ret = aplwc_destroy(aplwc); - if(ret){ - fprintf(stderr, "Couldn't destroy the aplwc instance: %s\n", aplwc_errstr(aplwc)); - return 1; - } + aplwc_destroy(aplwc); free(data); diff --git a/src/bin/util.c b/src/bin/util.c new file mode 100644 index 0000000..c8218fd --- /dev/null +++ b/src/bin/util.c @@ -0,0 +1,17 @@ +#include "aplwc_repl.h" + +unsigned long +getenv_ulong(const char *name, unsigned long def) +{ + unsigned long ret, parsed; + char *env, *p; + + ret = def; + env = getenv(name); + if((env != NULL) && (strlen(env) > 0)){ + parsed = strtoul(env, &p, 10); + if((*p) == 0) + ret = parsed; + } + return ret; +} diff --git a/src/bin/wrappers.c b/src/bin/wrappers.c new file mode 100644 index 0000000..18e179a --- /dev/null +++ b/src/bin/wrappers.c @@ -0,0 +1,40 @@ +#include "aplwc_repl.h" + +static uint64_t malloc_count = 0; + +static uint64_t +malloc_fail_after(void) +{ +#if APLWC_BUILD_TYPE_RELEASE + return UINT64_MAX; +#else + static int setup; + static uint64_t count, count_rec; + + if(!setup){ + setup = 1; + count = getenv_ulong("APLWC_MALLOC_FAIL_AFTER", ULONG_MAX); + count_rec = malloc_fail_after(); + assert(ALWAYS(count == count_rec)); + } + + return count; +#endif +} + +#undef malloc +void * +wrapped_malloc(size_t size) +{ + if(malloc_count++ >= malloc_fail_after()) + return NULL; + else + return malloc(size); +} + +#undef free +void +wrapped_free(void *ptr) +{ + free(ptr); +} diff --git a/src/include/aplwc.h b/src/include/aplwc.h index 9905411..d4d101c 100644 --- a/src/include/aplwc.h +++ b/src/include/aplwc.h @@ -14,7 +14,7 @@ enum aplwc_rc { struct aplwc; enum aplwc_rc aplwc_new(struct aplwc **, uint8_t *, size_t); -enum aplwc_rc aplwc_destroy(struct aplwc *); +void aplwc_destroy(struct aplwc *); const char *aplwc_errstr_rc(enum aplwc_rc); const char *aplwc_errstr(struct aplwc *); diff --git a/src/include/aplwc_macros.h b/src/include/aplwc_macros.h new file mode 100644 index 0000000..cf05803 --- /dev/null +++ b/src/include/aplwc_macros.h @@ -0,0 +1,20 @@ +#ifndef APLWC_MACROS_H +#define APLWC_MACROS_H + +#define UNUSED_PARAMETER(arg) ((void)arg) + +#define NELEM(x) (sizeof(x)/sizeof(x[0])) + +#if APLWC_BUILD_TYPE_DEBUG + #define ALWAYS(x) ((x) ? 1 : (assert(0), 0)) + #define NEVER(x) ((x) ? (assert(0), 1) : 0) +#elif APLWC_BUILD_TYPE_RELEASE + #define ALWAYS(x) (X) + #define NEVER(X) (X) +#elif APLWC_BUILD_TYPE_COVERAGE + #define ALWAYS(x) (1) + #define NEVER(x) (0) +#endif + + +#endif /* APLWC_MACROS_H */ diff --git a/src/lib/aplwc_internal.h b/src/lib/aplwc_internal.h index 97a89ba..52ecd2e 100644 --- a/src/lib/aplwc_internal.h +++ b/src/lib/aplwc_internal.h @@ -2,26 +2,12 @@ #define APLWC_INTERNAL_H #include <aplwc.h> - -#define UNUSED_PARAMETER(arg) ((void)arg) +#include <aplwc_macros.h> #define RETURN_ERROR(aplwcp, rc, msg) do{ \ return ((aplwc)->last_error = (rc)); \ }while(0) -#define NELEM(x) (sizeof(x)/sizeof(x[0])) - -#if APLWC_BUILD_TYPE_DEBUG - #define ALWAYS(x) ((x) ? 1 : (assert(0), 0)) - #define NEVER(x) ((x) ? (assert(0), 1) : 0) -#elif APLWC_BUILD_TYPE_RELEASE - #define ALWAYS(x) (X) - #define NEVER(X) (X) -#elif APLWC_BUILD_TYPE_COVERAGE - #define ALWAYS(x) (1) - #define NEVER(x) (0) -#endif - #include <assert.h> #include <stdalign.h> #include <stdbool.h> diff --git a/src/lib/main.c b/src/lib/main.c index d44d6de..f7cbe7d 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -15,13 +15,11 @@ aplwc_new(struct aplwc **p, uint8_t *data, size_t size) return APLWC_OK; } -enum aplwc_rc +void aplwc_destroy(struct aplwc *p) { if(p) memory_free_aplwc(&p->memory, p); - - return APLWC_OK; } const char * diff --git a/tests/aplwc_errstr.c b/tests/aplwc_errstr.c index 0a3b2ad..0efb777 100644 --- a/tests/aplwc_errstr.c +++ b/tests/aplwc_errstr.c @@ -26,9 +26,7 @@ main(void) if(strcmp(err, "(unable to produce error string)") != 0) return 1; - ret = aplwc_destroy(aplwc); - if(ret) - return 1; + aplwc_destroy(aplwc); ret = aplwc_new(&aplwc, data, 0); if(ret == 0) diff --git a/tests/aplwc_new.c b/tests/aplwc_new.c index 1931c3c..55e742f 100644 --- a/tests/aplwc_new.c +++ b/tests/aplwc_new.c @@ -19,9 +19,7 @@ main(void) if(j >= APLWC_MIN_MEM) return 1; } - ret = aplwc_destroy(aplwc); - if(ret) - return 1; + aplwc_destroy(aplwc); } } diff --git a/tools/checkcov b/tools/checkcov index 32e30d7..3d9fedf 100755 --- a/tools/checkcov +++ b/tools/checkcov @@ -4,8 +4,8 @@ cd build/$1 case "$1" in Coverage) - rm -rf CMakeFiles/aplwc.dir/src/* - rm -rf CMakeFiles/aplwc-repl.dir/src/* + rm -rf CMakeFiles/aplwc.dir/src/lib/* + rm -rf CMakeFiles/aplwc-repl.dir/src/bin/* ;; *) ;; @@ -22,7 +22,7 @@ case "$1" in ;; esac -gcov -tg CMakeFiles/aplwc.dir/src/*.gcno CMakeFiles/aplwc-repl.dir/src/*.gcno | awk ' +gcov -tg CMakeFiles/aplwc.dir/src/lib/*.gcno CMakeFiles/aplwc-repl.dir/src/bin/*.gcno | awk ' BEGIN { FS=":" } |