diff options
Diffstat (limited to 'test/test_writer.c')
-rw-r--r-- | test/test_writer.c | 133 |
1 files changed, 113 insertions, 20 deletions
diff --git a/test/test_writer.c b/test/test_writer.c index 7e2386be..23ac222c 100644 --- a/test/test_writer.c +++ b/test/test_writer.c @@ -16,6 +16,8 @@ #undef NDEBUG +#include "failing_allocator.h" + #include "serd/serd.h" #include <assert.h> @@ -28,23 +30,112 @@ static void test_writer_new(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); - SerdBuffer buffer = {NULL, 0}; + SerdBuffer buffer = {serd_world_allocator(world), NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); assert(!serd_writer_new(world, SERD_TURTLE, 0u, env, &output, 0)); + serd_env_free(env); serd_world_free(world); +} + +static void +test_new_failed_alloc(void) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + SerdWorld* const world = serd_world_new(&allocator.base); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); + SerdBuffer buffer = {&allocator.base, NULL, 0}; + SerdOutputStream output = serd_open_output_buffer(&buffer); + const size_t n_world_allocs = allocator.n_allocations; + + // Successfully allocate a writer to count the number of allocations + SerdWriter* const writer = + serd_writer_new(world, SERD_TURTLE, 0u, env, &output, 1); + + assert(writer); + + // Test that each allocation failing is handled gracefully + const size_t n_new_allocs = allocator.n_allocations - n_world_allocs; + for (size_t i = 0; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + assert(!serd_writer_new(world, SERD_TURTLE, 0u, env, &output, 1)); + } + + serd_writer_free(writer); + serd_env_free(env); + serd_world_free(world); +} + +static void +test_write_failed_alloc(void) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + SerdWorld* world = serd_world_new(&allocator.base); + SerdNodes* nodes = serd_world_nodes(world); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); + SerdBuffer buffer = {&allocator.base, NULL, 0}; + SerdOutputStream output = serd_open_output_buffer(&buffer); + + const SerdNode* s = + serd_nodes_uri(nodes, SERD_STRING("http://example.org/s")); + + const SerdNode* p1 = + serd_nodes_uri(nodes, SERD_STRING("http://example.org/p")); + + const SerdNode* p2 = serd_nodes_uri( + nodes, SERD_STRING("http://example.org/dramatically/longer/predicate")); + + const SerdNode* o = serd_nodes_blank(nodes, SERD_STRING("o")); + + const size_t n_setup_allocs = allocator.n_allocations; + + // Successfully write a statement to count the number of allocations + SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0u, env, &output, 1); + const SerdSink* sink = serd_writer_sink(writer); + assert(writer); + assert(sink); + assert(!serd_sink_write(sink, 0u, s, p1, o, NULL)); + assert(!serd_sink_write(sink, 0u, s, p2, o, NULL)); + const size_t n_new_allocs = allocator.n_allocations - n_setup_allocs; + + serd_writer_free(writer); + + // Test that each allocation failing is handled gracefully + for (size_t i = 0; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + + if ((writer = serd_writer_new(world, SERD_TURTLE, 0u, env, &output, 1))) { + sink = serd_writer_sink(writer); + + const SerdStatus st1 = serd_sink_write(sink, 0u, s, p1, o, NULL); + const SerdStatus st2 = serd_sink_write(sink, 0u, s, p2, o, NULL); + + assert(st1 == SERD_BAD_ALLOC || st1 == SERD_BAD_WRITE || + st2 == SERD_BAD_ALLOC || st2 == SERD_BAD_WRITE); + + serd_writer_free(writer); + } + } + + serd_close_output(&output); serd_env_free(env); + serd_buffer_close(&buffer); + serd_free(NULL, buffer.buf); + + serd_world_free(world); } static void test_write_bad_event(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); - SerdBuffer buffer = {NULL, 0}; + SerdBuffer buffer = {NULL, NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0u, env, &output, 1); @@ -60,7 +151,7 @@ test_write_bad_event(void) assert(out); assert(!strcmp(out, "")); - serd_free(out); + serd_free(NULL, buffer.buf); serd_writer_free(writer); serd_env_free(env); @@ -70,10 +161,10 @@ test_write_bad_event(void) static void test_write_long_literal(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); SerdNodes* nodes = serd_world_nodes(world); SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); - SerdBuffer buffer = {NULL, 0}; + SerdBuffer buffer = {NULL, NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0u, env, &output, 1); @@ -106,7 +197,7 @@ test_write_long_literal(void) "\t<http://example.org/p> \"\"\"hello \"\"\\\"world\"\"\\\"!\"\"\" .\n"; assert(!strcmp(out, expected)); - serd_free(out); + serd_free(NULL, buffer.buf); serd_world_free(world); } @@ -126,7 +217,7 @@ null_sink(const void* const buf, static void test_writer_stack_overflow(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); SerdNodes* nodes = serd_world_nodes(world); SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); @@ -178,7 +269,7 @@ test_strict_write(void) { static const char* path = "serd_strict_write_test.ttl"; - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); SerdNodes* nodes = serd_world_nodes(world); SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); @@ -231,7 +322,7 @@ faulty_sink(const void* const buf, static void test_write_error(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); SerdNodes* nodes = serd_world_nodes(world); SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); @@ -277,7 +368,7 @@ test_write_error(void) static void test_write_empty_syntax(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); SerdNodes* nodes = serd_world_nodes(world); SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); @@ -290,7 +381,7 @@ test_write_empty_syntax(void) const SerdNode* o = serd_nodes_uri(nodes, SERD_STRING("http://example.org/o")); - SerdBuffer buffer = {NULL, 0}; + SerdBuffer buffer = {NULL, NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); SerdWriter* writer = @@ -305,7 +396,7 @@ test_write_empty_syntax(void) assert(out); assert(strlen(out) == 0); - serd_free(out); + serd_free(NULL, buffer.buf); serd_writer_free(writer); serd_close_output(&output); @@ -316,7 +407,7 @@ test_write_empty_syntax(void) static void test_write_bad_uri(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); SerdNodes* nodes = serd_world_nodes(world); SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); @@ -328,7 +419,7 @@ test_write_bad_uri(void) const SerdNode* rel = serd_nodes_uri(nodes, SERD_STRING("rel")); - SerdBuffer buffer = {NULL, 0}; + SerdBuffer buffer = {NULL, NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); SerdWriter* writer = @@ -343,7 +434,7 @@ test_write_bad_uri(void) assert(st == SERD_BAD_ARG); serd_close_output(&output); - serd_free(buffer.buf); + serd_free(NULL, buffer.buf); serd_writer_free(writer); serd_close_output(&output); serd_env_free(env); @@ -353,10 +444,10 @@ test_write_bad_uri(void) static void check_pname_escape(const char* const lname, const char* const expected) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); SerdNodes* nodes = serd_world_nodes(world); SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); - SerdBuffer buffer = {NULL, 0}; + SerdBuffer buffer = {NULL, NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0u, env, &output, 1); @@ -389,7 +480,7 @@ check_pname_escape(const char* const lname, const char* const expected) char* out = (char*)buffer.buf; assert(!strcmp(out, expected)); - serd_free(out); + serd_free(NULL, buffer.buf); free(uri); serd_world_free(world); @@ -430,6 +521,8 @@ int main(void) { test_writer_new(); + test_new_failed_alloc(); + test_write_failed_alloc(); test_write_bad_event(); test_write_long_literal(); test_writer_stack_overflow(); |