diff options
Diffstat (limited to 'test/test_canon.c')
-rw-r--r-- | test/test_canon.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/test/test_canon.c b/test/test_canon.c new file mode 100644 index 00000000..1e4dc24c --- /dev/null +++ b/test/test_canon.c @@ -0,0 +1,108 @@ +/* + Copyright 2021 David Robillard <d@drobilla.net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#undef NDEBUG + +#include "failing_allocator.h" +#include "serd/serd.h" + +#include <assert.h> +#include <stddef.h> + +static SerdStatus +ignore_event(void* handle, const SerdEvent* event) +{ + (void)handle; + (void)event; + return SERD_SUCCESS; +} + +static void +test_new_failed_alloc(void) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + SerdWorld* const world = serd_world_new(&allocator.base); + SerdNodes* const nodes = serd_nodes_new(&allocator.base); + + SerdSink* target = serd_sink_new(world, NULL, ignore_event, NULL); + const size_t n_setup_allocs = allocator.n_allocations; + + // Successfully allocate a canon to count the number of allocations + SerdSink* canon = serd_canon_new(world, target, 0u); + assert(canon); + + // Test that each allocation failing is handled gracefully + const size_t n_new_allocs = allocator.n_allocations - n_setup_allocs; + for (size_t i = 0; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + assert(!serd_canon_new(world, target, 0u)); + } + + serd_sink_free(canon); + serd_sink_free(target); + serd_nodes_free(nodes); + serd_world_free(world); +} + +static void +test_write_failed_alloc(void) +{ + static const SerdStringView s_string = SERD_STRING("http://example.org/s"); + static const SerdStringView p_string = SERD_STRING("http://example.org/p"); + static const SerdStringView o_string = SERD_STRING("012.340"); + static const SerdStringView xsd_float = + SERD_STRING("http://www.w3.org/2001/XMLSchema#float"); + + SerdFailingAllocator allocator = serd_failing_allocator(); + + SerdWorld* const world = serd_world_new(&allocator.base); + SerdNodes* const nodes = serd_nodes_new(&allocator.base); + const SerdNode* const s = serd_nodes_uri(nodes, s_string); + const SerdNode* const p = serd_nodes_uri(nodes, p_string); + const SerdNode* const o = + serd_nodes_literal(nodes, o_string, SERD_HAS_DATATYPE, xsd_float); + + SerdSink* target = serd_sink_new(world, NULL, ignore_event, NULL); + SerdSink* canon = serd_canon_new(world, target, 0u); + const size_t n_setup_allocs = allocator.n_allocations; + + // Successfully write statement to count the number of allocations + assert(canon); + assert(!serd_sink_write(canon, 0u, s, p, o, NULL)); + + // Test that each allocation failing is handled gracefully + const size_t n_new_allocs = allocator.n_allocations - n_setup_allocs; + for (size_t i = 0; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + + const SerdStatus st = serd_sink_write(canon, 0u, s, p, o, NULL); + assert(st == SERD_BAD_ALLOC); + } + + serd_sink_free(canon); + serd_sink_free(target); + serd_nodes_free(nodes); + serd_world_free(world); +} + +int +main(void) +{ + test_new_failed_alloc(); + test_write_failed_alloc(); + return 0; +} |