Mercurial > lbo > hg > ylisp
changeset 31:57fb1b70b990
build: Enhance coverage and valgrind targets.
By directly collecting the test executable names.
Also increase coverage in src/base/str
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Tue, 20 Aug 2019 19:47:46 +0200 |
parents | 656efbd10859 |
children | 53ae0f7d8aa1 |
files | CMakeLists.txt coverage.sh src/CMakeLists.txt src/base/CMakeLists.txt src/base/str.c src/base/str.h src/base/str_test.c valgrind.sh |
diffstat | 8 files changed, 95 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Tue Aug 20 19:23:28 2019 +0200 +++ b/CMakeLists.txt Tue Aug 20 19:47:46 2019 +0200 @@ -12,6 +12,14 @@ ADD_COMPILE_OPTIONS(-g -O0) endif () +SET_PROPERTY(GLOBAL PROPERTY YALL_TESTS "") +FUNCTION(YADD_TEST test_executable_name) + GET_PROPERTY(OLD_LIST GLOBAL PROPERTY YALL_TESTS) + SET_PROPERTY(GLOBAL PROPERTY YALL_TESTS "${OLD_LIST} ${CMAKE_CURRENT_BINARY_DIR}/${test_executable_name}") + ADD_TEST(NAME "${test_executable_name}_ctest" COMMAND "./${test_executable_name}") +ENDFUNCTION(YADD_TEST) + + INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) @@ -29,7 +37,14 @@ ADD_CUSTOM_TARGET(doxygen ALL COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} VERBATIM) endif () +GET_PROPERTY(ALL_TEST_EXECUTABLES GLOBAL PROPERTY YALL_TESTS) ADD_CUSTOM_TARGET(coverage - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/coverage.sh ${YALL_TESTS} + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/coverage.sh ${ALL_TEST_EXECUTABLES} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) +ADD_CUSTOM_TARGET(valgrind + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/valgrind.sh ${ALL_TEST_EXECUTABLES} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} +) + +MESSAGE("${ALL_TEST_EXECUTABLES}")
--- a/coverage.sh Tue Aug 20 19:23:28 2019 +0200 +++ b/coverage.sh Tue Aug 20 19:47:46 2019 +0200 @@ -1,5 +1,6 @@ #!/bin/bash +# Expects a list of test executables as arguments. # Run this from the build directory using `make coverage`. set -e @@ -7,11 +8,12 @@ KCOV="kcov" KCOV_ARGS="--exclude-pattern=/usr/src,/usr/include,/usr/lib,_test.c" -TESTS=`find . -name \*_test -executable -and -not -type l` -TESTS_BASENAME=`find . -name \*_test -and -executable -and -not -type l -exec /bin/basename {} \;` +TESTS=$@ +TESTS_BASENAME=`basename -a $TESTS` for BINARY in $TESTS; do $KCOV $KCOV_ARGS . $BINARY done $KCOV --merge --report $KCOV_ARGS . $TESTS_BASENAME +xdg-open kcov-merged/index.html
--- a/src/CMakeLists.txt Tue Aug 20 19:23:28 2019 +0200 +++ b/src/CMakeLists.txt Tue Aug 20 19:47:46 2019 +0200 @@ -14,4 +14,4 @@ # Atom test. ADD_EXECUTABLE(atom_test atom_test.c) TARGET_LINK_LIBRARIES(atom_test core gcov) -ADD_TEST(NAME atom_test_t COMMAND ./atom_test) +YADD_TEST(atom_test)
--- a/src/base/CMakeLists.txt Tue Aug 20 19:23:28 2019 +0200 +++ b/src/base/CMakeLists.txt Tue Aug 20 19:47:46 2019 +0200 @@ -11,9 +11,9 @@ # str test. ADD_EXECUTABLE(str_test str_test.c) TARGET_LINK_LIBRARIES(str_test base gcov) -ADD_TEST(NAME str_test_t COMMAND ./str_test) +YADD_TEST(str_test) # vec test. ADD_EXECUTABLE(vec_test vec_test.c) TARGET_LINK_LIBRARIES(vec_test base gcov) -ADD_TEST(NAME vec_test_t COMMAND ./vec_test) +YADD_TEST(vec_test)
--- a/src/base/str.c Tue Aug 20 19:23:28 2019 +0200 +++ b/src/base/str.c Tue Aug 20 19:47:46 2019 +0200 @@ -14,12 +14,11 @@ void ystr_set_owned(ystr_t *s, char *src) { if (src == NULL) { - memset(s, 0, sizeof(ystr_t)); + ystr_destroy(s); return; } // Free previous memory. - if (!ystr_is_inline(s)) - ystr_destroy(s); + ystr_destroy(s); size_t len = strlen(src) + 1; s->inner.big.len = len; s->inner.big.cap = len; @@ -29,9 +28,7 @@ void ystr_set(ystr_t *s, const char *src) { if (src == NULL) { - if (!ystr_is_inline(s)) - ystr_destroy(s); - memset(s, 0, sizeof(ystr_t)); + ystr_destroy(s); return; } ystr_set_n(s, src, strlen(src)); @@ -171,7 +168,7 @@ if (written >= YSTR_BUILD_BUF_SIZE) { char *buf2 = calloc(written + 1, sizeof(char)); va_start(args, fmt); - vsnprintf(buf, written + 1, fmt, args); + vsnprintf(buf2, written + 1, fmt, args); va_end(args); ystr_t fmtd;
--- a/src/base/str.h Tue Aug 20 19:23:28 2019 +0200 +++ b/src/base/str.h Tue Aug 20 19:47:46 2019 +0200 @@ -108,7 +108,8 @@ void ystr_resize(ystr_t *s, size_t new); /** - * @brief Append a C string to string, with possible formatting directives. + * @brief Append a C string to string, with possible formatting directives like + * printf. */ void ystr_build(ystr_t *s, const char *fmt, ...);
--- a/src/base/str_test.c Tue Aug 20 19:23:28 2019 +0200 +++ b/src/base/str_test.c Tue Aug 20 19:47:46 2019 +0200 @@ -18,7 +18,7 @@ assert(5 == ystr_len(&str)); ystr_set(&str2, "short, too"); - assert(str.inner.big.size == 0); // is inline. + assert(str2.inner.big.size == 0); // is inline. ystr_destroy(&str); ystr_destroy(&str2); @@ -28,9 +28,18 @@ void test_str_set_owned() { ystr_t str; ystr_init(&str, NULL); - char *s = strdup("Hello"); + + char* s = strdup("Hello"); ystr_set_owned(&str, s); assert(s == ystr_str(&str)); + + ystr_set_owned(&str, NULL); + assert(0 == ystr_cmp_str(&str, "")); + + ystr_set(&str, "a very long string that is not inlined"); + char* owned = strdup("short but external"); + ystr_set_owned(&str, owned); + ystr_destroy(&str); } @@ -39,6 +48,9 @@ ystr_init(&str, "ab"); ystr_init(&str2, "ab"); assert(0 == ystr_cmp(&str, &str2)); + + ystr_set_n(&str, NULL, 0); + assert(0 == ystr_cmp_str(&str, "")); } void test_str_at() { @@ -68,24 +80,53 @@ ystr_init(&s2, "abcdefghijklmnop"); ystr_init(&s3, "0123"); + ystr_append(&s1, &s3); + assert(0 == ystr_cmp_str(&s1, "xyz0123")); + ystr_append(&s1, &s2); - assert(0 == ystr_cmp_str(&s1, "xyzabcdefghijklmnop")); + assert(0 == ystr_cmp_str(&s1, "xyz0123abcdefghijklmnop")); ystr_append(&s1, &s3); - assert(0 == ystr_cmp_str(&s1, "xyzabcdefghijklmnop0123")); + assert(0 == ystr_cmp_str(&s1, "xyz0123abcdefghijklmnop0123")); ystr_append(&s1, &s3); - assert(0 == ystr_cmp_str(&s1, "xyzabcdefghijklmnop01230123")); + assert(0 == ystr_cmp_str(&s1, "xyz0123abcdefghijklmnop01230123")); - ystr_set(&s1, "xyz"); - ystr_build(&s1, " hello %s %d", "world", 13); - assert(0 == ystr_cmp_str(&s1, "xyz hello world 13")); + ystr_set(&s1, NULL); + assert(0 == ystr_cmp_str(&s1, "")); ystr_destroy(&s1); ystr_destroy(&s2); ystr_destroy(&s3); } +void test_str_build() { + ystr_t s1; + ystr_init(&s1, "xyz"); + + ystr_build(&s1, " hello %s %d", "world", 13); + assert(0 == ystr_cmp_str(&s1, "xyz hello world 13")); + + ystr_set(&s1, "initial string."); + + // Generated with `base64 -w0 /dev/urandom | head -c 130` + const char* long_string = + "qBf7NDxInwVb5kqYTtF3B7gxl5VXBtAcy7uFZQjAtcP08YqB2IqK45rKxGZltcaxnV" + "adUH" + "hvHDVy/nVt4THu605d7R2icW917w1OZ9ZhRvD02ixP+FvRospdFokx4aav3f"; + ystr_build(&s1, " Hello. Now we try a long string: %s\n", long_string); + + const char* wants = + "initial string. Hello. Now we try a long string: " + "qBf7NDxInwVb5kqYTtF3B7gxl5VXBtAcy7uFZQjAtcP08YqB2IqK45rKxGZltcaxnVadUH" + "hvHDVy/nVt4THu605d7R2icW917w1OZ9ZhRvD02ixP+FvRospdFokx4aav3f\n"; + puts(wants); + puts(ystr_str(&s1)); + assert(0 == ystr_cmp_str(&s1, wants)); + + ystr_destroy(&s1); +} + void test_string_split() { ystr_t str; yvec_t parts; @@ -123,13 +164,15 @@ ystr_destroy(&s); } -int main(int argc, char **argv) { +int main(int argc, char** argv) { + // Use `make valgrind` to check that all memory is freed by str_test. test_inline_string(); test_str_set_owned(); test_str_set(); test_str_at(); test_str_cmp(); test_str_append(); + test_str_build(); test_string_split(); test_string_resize(); return 0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/valgrind.sh Tue Aug 20 19:47:46 2019 +0200 @@ -0,0 +1,14 @@ +#!/bin/bash + +# Expects a list of test executables as arguments. +# Run this using `make valgrind` from the build directory. + +VALGRIND=valgrind +VALGRIND_ARGS="--leak-check=full --track-origins=yes" + +TESTS=$@ + +for BINARY in $TESTS; do + echo "Running valgrind on ${BINARY}" + $VALGRIND $VALGRIND_ARGS $BINARY +done