diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/meson.build | 39 | ||||
-rw-r--r-- | test/test_digest.c | 3 | ||||
-rw-r--r-- | test/test_filesystem.c | 20 | ||||
-rw-r--r-- | test/test_hash.c | 29 | ||||
-rw-r--r-- | test/test_string_view.c | 118 | ||||
-rw-r--r-- | test/test_thread.c | 9 | ||||
-rw-r--r-- | test/test_tree.c | 4 |
7 files changed, 196 insertions, 26 deletions
diff --git a/test/meson.build b/test/meson.build index 15f449c..96fe455 100644 --- a/test/meson.build +++ b/test/meson.build @@ -1,4 +1,4 @@ -# Copyright 2020-2023 David Robillard <d@drobilla.net> +# Copyright 2020-2024 David Robillard <d@drobilla.net> # SPDX-License-Identifier: 0BSD OR ISC if not meson.is_subproject() and get_option('lint') @@ -23,6 +23,40 @@ if not meson.is_subproject() and get_option('lint') suite: 'data', ) endif + + # Check code formatting + clang_format = find_program('clang-format', required: false) + if clang_format.found() + test( + 'format', + clang_format, + args: ['--Werror', '--dry-run'] + c_headers + sources, + suite: 'code', + ) + endif + + # Check code with cppcheck + if not meson.is_subproject() + cppcheck = find_program('cppcheck', required: false) + if cppcheck.found() + compdb_path = join_paths(zix_build_root, 'compile_commands.json') + test( + 'cppcheck', + cppcheck, + args: [ + '--check-level=exhaustive', + '--enable=warning,style,performance,portability', + '--error-exitcode=1', + '--project=' + compdb_path, + '--suppress=constParameterCallback', + '--suppress=constParameterPointer', + '--suppress=unreadVariable', + '-q', + ], + suite: 'code', + ) + endif + endif endif # Set warning suppression flags specific to tests @@ -51,6 +85,7 @@ sequential_tests = { 'hash': {'': []}, 'path': {'': []}, 'status': {'': []}, + 'string_view': {'': []}, 'tree': { '': [], '_seed': ['8', '314159'], @@ -103,7 +138,7 @@ foreach test, cases : sequential_tests endforeach endforeach -# Test multi-threaded +# Test multi-threaded if thread_dep.found() foreach test, cases : threaded_tests sources = common_test_sources + files('test_@0@.c'.format(test)) diff --git a/test/test_digest.c b/test/test_digest.c index 7e7e77a..7228f86 100644 --- a/test/test_digest.c +++ b/test/test_digest.c @@ -116,7 +116,8 @@ test_digest_aligned(void) } } -ZIX_PURE_FUNC int +ZIX_PURE_FUNC +int main(void) { test_digest32(); diff --git a/test/test_filesystem.c b/test/test_filesystem.c index 4a1ad4f..e6180fb 100644 --- a/test/test_filesystem.c +++ b/test/test_filesystem.c @@ -162,15 +162,17 @@ test_file_type(void) const socklen_t addr_len = sizeof(struct sockaddr_un); struct sockaddr_un* const addr = (struct sockaddr_un*)calloc(1, addr_len); - addr->sun_family = AF_UNIX; - strncpy(addr->sun_path, file_path, sizeof(addr->sun_path) - 1); - - const int fd = bind(sock, (struct sockaddr*)addr, addr_len); - if (fd >= 0) { - assert(zix_file_type(file_path) == ZIX_FILE_TYPE_SOCKET); - assert(!zix_remove(file_path)); - close(fd); - } + if (strlen(file_path) < sizeof(addr->sun_path)) { + addr->sun_family = AF_UNIX; + strncpy(addr->sun_path, file_path, sizeof(addr->sun_path) - 1); + + const int fd = bind(sock, (struct sockaddr*)addr, addr_len); + if (fd >= 0) { + assert(zix_file_type(file_path) == ZIX_FILE_TYPE_SOCKET); + assert(!zix_remove(file_path)); + close(fd); + } + } // otherwise, TMPDIR is oddly long, skip test close(sock); free(addr); diff --git a/test/test_hash.c b/test/test_hash.c index b1de72a..3d3ca95 100644 --- a/test/test_hash.c +++ b/test/test_hash.c @@ -47,21 +47,24 @@ test_fail(TestState* const state, const char* fmt, ...) return EXIT_FAILURE; } -ZIX_PURE_FUNC static const char* +ZIX_PURE_FUNC +static const char* identity(const char* record) { return record; } /// Decent hash function using zix_digest (murmur2) -ZIX_PURE_FUNC static size_t +ZIX_PURE_FUNC +static size_t decent_string_hash(const char* const str) { return zix_digest(0U, str, strlen(str)); } /// Terrible hash function from K&R first edition -ZIX_PURE_FUNC static size_t +ZIX_PURE_FUNC +static size_t terrible_string_hash(const char* str) { size_t hash = 0U; @@ -74,7 +77,8 @@ terrible_string_hash(const char* str) return hash; } -ZIX_PURE_FUNC static size_t +ZIX_PURE_FUNC +static size_t string_hash_aligned(const char* const str) { size_t length = strlen(str); @@ -83,19 +87,22 @@ string_hash_aligned(const char* const str) return zix_digest_aligned(0U, str, length); } -ZIX_PURE_FUNC static size_t +ZIX_PURE_FUNC +static size_t string_hash32(const char* const str) { return (size_t)zix_digest32(0U, str, strlen(str)); } -ZIX_PURE_FUNC static size_t +ZIX_PURE_FUNC +static size_t string_hash64(const char* const str) { return (size_t)zix_digest64(0U, str, strlen(str)); } -ZIX_PURE_FUNC static size_t +ZIX_PURE_FUNC +static size_t string_hash32_aligned(const char* const str) { size_t length = strlen(str); @@ -106,7 +113,8 @@ string_hash32_aligned(const char* const str) #if UINTPTR_MAX >= UINT64_MAX -ZIX_PURE_FUNC static size_t +ZIX_PURE_FUNC +static size_t string_hash64_aligned(const char* const str) { size_t length = strlen(str); @@ -135,7 +143,7 @@ stress_with(ZixAllocator* const allocator, static const size_t string_length = 15; char* const buffer = (char*)calloc(1, n_elems * (string_length + 1)); - char** const strings = state.strings = (char**)calloc(sizeof(char*), n_elems); + char** const strings = state.strings = (char**)calloc(n_elems, sizeof(char*)); state.buffer = buffer; state.strings = strings; ENSURE(&state, buffer && state.strings, "Failed to allocate strings\n"); @@ -290,7 +298,8 @@ stress(ZixAllocator* const allocator, const size_t n_elems) } /// Identity hash function for numeric strings for explicitly hitting cases -ZIX_PURE_FUNC static size_t +ZIX_PURE_FUNC +static size_t identity_index_hash(const char* const str) { return strtoul(str, NULL, 10); diff --git a/test/test_string_view.c b/test/test_string_view.c new file mode 100644 index 0000000..52b824d --- /dev/null +++ b/test/test_string_view.c @@ -0,0 +1,118 @@ +// Copyright 2021-2024 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#undef NDEBUG + +#include "failing_allocator.h" + +#include "zix/string_view.h" + +#include <assert.h> +#include <string.h> + +static void +test_static_init(void) +{ + static const ZixStringView a = ZIX_STATIC_STRING("a"); + static const ZixStringView ab = ZIX_STATIC_STRING("ab"); + + assert(a.length == 1U); + assert(a.data); + assert(a.data[0] == 'a'); + assert(a.data[1] == '\0'); + + assert(ab.length == 2U); + assert(ab.data[0] == 'a'); + assert(ab.data[1] == 'b'); + assert(ab.data[2] == '\0'); +} + +static void +test_empty(void) +{ + const ZixStringView empty = zix_empty_string(); + + assert(!empty.length); + assert(empty.data); + assert(empty.data[0] == '\0'); +} + +static void +test_string(void) +{ + const ZixStringView nodata = zix_string(NULL); + const ZixStringView empty = zix_string(""); + + assert(!nodata.length); + assert(nodata.data); + assert(nodata.data[0] == '\0'); + + assert(!empty.length); + assert(empty.data); + assert(empty.data[0] == '\0'); +} + +static void +test_equals(void) +{ + static const char* const prefix_str = "prefix"; + + const ZixStringView prefix = zix_string(prefix_str); + const ZixStringView pre = zix_substring(prefix_str, 3U); + const ZixStringView fix = zix_substring(prefix_str + 3U, 3U); + const ZixStringView suffix1 = zix_substring("suffix_1", 6U); + const ZixStringView suffix2 = zix_substring("suffix_2", 6U); + + assert(prefix.length == 6U); + assert(pre.length == 3U); + assert(fix.length == 3U); + assert(suffix1.length == 6U); + assert(suffix2.length == 6U); + + assert(zix_string_view_equals(prefix, zix_string("prefix"))); + assert(zix_string_view_equals(pre, zix_string("pre"))); + assert(zix_string_view_equals(fix, zix_string("fix"))); + assert(zix_string_view_equals(suffix1, zix_string("suffix"))); + assert(zix_string_view_equals(suffix2, zix_string("suffix"))); + + assert(zix_string_view_equals(prefix, prefix)); + assert(zix_string_view_equals(suffix1, suffix2)); + + assert(!zix_string_view_equals(prefix, pre)); + assert(!zix_string_view_equals(pre, prefix)); + assert(!zix_string_view_equals(pre, fix)); + assert(!zix_string_view_equals(fix, prefix)); + assert(!zix_string_view_equals(suffix1, prefix)); + assert(!zix_string_view_equals(prefix, suffix1)); +} + +static void +test_copy(void) +{ + static const ZixStringView orig = ZIX_STATIC_STRING("string"); + + ZixFailingAllocator allocator = zix_failing_allocator(); + + // Copying a string takes exactly one allocation + allocator.n_remaining = 1U; + + char* const copy = zix_string_view_copy(&allocator.base, orig); + assert(copy); + assert(!strcmp(copy, "string")); + zix_free(&allocator.base, copy); + + // Check that allocation failure is handled gracefully + allocator.n_remaining = 0U; + assert(!zix_string_view_copy(&allocator.base, orig)); +} + +int +main(void) +{ + test_static_init(); + test_empty(); + test_string(); + test_equals(); + test_copy(); + return 0; +} diff --git a/test/test_thread.c b/test/test_thread.c index 8cfc9f4..09edde6 100644 --- a/test/test_thread.c +++ b/test/test_thread.c @@ -3,6 +3,7 @@ #undef NDEBUG +#include "zix/status.h" #include "zix/thread.h" #include <assert.h> @@ -32,8 +33,12 @@ main(int argc, char** argv) SharedData data = {argc + (int)strlen(argv[0]), 0}; - assert(!zix_thread_create(&thread, 128, thread_func, &data)); - assert(!zix_thread_join(thread)); + ZixStatus st = zix_thread_create(&thread, 128, thread_func, &data); + assert(!st); + + st = zix_thread_join(thread); + assert(!st); + assert(data.output == data.input * 7); return 0; diff --git a/test/test_tree.c b/test/test_tree.c index 5f093d3..fae6d85 100644 --- a/test/test_tree.c +++ b/test/test_tree.c @@ -21,7 +21,7 @@ #include <stdlib.h> #include <time.h> -static uintptr_t seed = 1; +static size_t seed = 1; static int int_cmp(const void* a, const void* b, const void* ZIX_UNUSED(user_data)) @@ -237,7 +237,7 @@ main(int argc, char** argv) if (argc > 2) { seed = strtoul(argv[2], NULL, 10); } else { - seed = (uintptr_t)time(NULL); + seed = (size_t)time(NULL); } } |