diff options
Diffstat (limited to 'test/test_reader.c')
-rw-r--r-- | test/test_reader.c | 106 |
1 files changed, 97 insertions, 9 deletions
diff --git a/test/test_reader.c b/test/test_reader.c index 80d9533b..095f736e 100644 --- a/test/test_reader.c +++ b/test/test_reader.c @@ -16,6 +16,8 @@ #undef NDEBUG +#include "failing_allocator.h" + #include "serd/serd.h" #include <assert.h> @@ -33,6 +35,89 @@ count_statements(void* handle, const SerdEvent* event) return SERD_SUCCESS; } +static void +test_new_failed_alloc(void) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + FILE* const temp = tmpfile(); + assert(temp); + + fprintf(temp, "_:s <http://example.org/p> _:o .\n"); + fflush(temp); + fseek(temp, 0L, SEEK_SET); + + SerdWorld* world = serd_world_new(&allocator.base); + size_t ignored = 0u; + SerdSink* sink = serd_sink_new(world, &ignored, count_statements, NULL); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); + + // Successfully allocate a reader to count the number of allocations + const size_t n_world_allocs = allocator.n_allocations; + SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0u, env, sink, 4096); + assert(reader); + + // 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_reader_new(world, SERD_TURTLE, 0u, env, sink, 4096)); + } + + serd_reader_free(reader); + serd_env_free(env); + serd_sink_free(sink); + serd_world_free(world); + fclose(temp); +} + +static void +test_start_failed_alloc(void) +{ + SerdFailingAllocator allocator = serd_failing_allocator(); + + FILE* const temp = tmpfile(); + assert(temp); + + fprintf(temp, "_:s <http://example.org/p> _:o .\n"); + fflush(temp); + fseek(temp, 0L, SEEK_SET); + + SerdWorld* world = serd_world_new(&allocator.base); + size_t ignored = 0u; + SerdSink* sink = serd_sink_new(world, &ignored, count_statements, NULL); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); + SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0u, env, sink, 4096); + + assert(reader); + + SerdInputStream in = serd_open_input_stream( + (SerdReadFunc)fread, (SerdErrorFunc)ferror, NULL, temp); + + // Successfully start a new read to count the number of allocations + const size_t n_setup_allocs = allocator.n_allocations; + assert(serd_reader_start(reader, &in, NULL, 4096) == SERD_SUCCESS); + + // Test that each allocation failing is handled gracefully + const size_t n_new_allocs = allocator.n_allocations - n_setup_allocs; + assert(!serd_reader_finish(reader)); + for (size_t i = 0; i < n_new_allocs; ++i) { + allocator.n_remaining = i; + + in = serd_open_input_stream( + (SerdReadFunc)fread, (SerdErrorFunc)ferror, NULL, temp); + + SerdStatus st = serd_reader_start(reader, &in, NULL, 4096); + assert(st == SERD_BAD_ALLOC); + } + + serd_reader_free(reader); + serd_env_free(env); + serd_sink_free(sink); + serd_world_free(world); + fclose(temp); +} + SERD_PURE_FUNC static size_t prepare_test_read(void* buf, size_t size, size_t nmemb, void* stream) @@ -58,7 +143,7 @@ prepare_test_error(void* stream) static void test_prepare_error(void) { - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); size_t n_statements = 0; FILE* const f = tmpfile(); @@ -93,7 +178,7 @@ test_prepare_error(void) static void test_read_string(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); size_t n_statements = 0; SerdSink* sink = serd_sink_new(world, &n_statements, count_statements, NULL); @@ -196,7 +281,7 @@ test_read_eof_by_page(void) fflush(temp); fseek(temp, 0L, SEEK_SET); - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); size_t ignored = 0u; SerdSink* sink = serd_sink_new(world, &ignored, count_statements, NULL); SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); @@ -224,7 +309,7 @@ test_read_eof_by_page(void) static void test_read_eof_by_byte(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); size_t ignored = 0u; SerdSink* sink = serd_sink_new(world, &ignored, count_statements, NULL); SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); @@ -252,7 +337,7 @@ test_read_eof_by_byte(void) static void test_read_chunks(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); size_t n_statements = 0; FILE* const f = tmpfile(); static const char null = 0; @@ -324,12 +409,13 @@ test_read_chunks(void) static void test_read_empty(void) { - SerdWorld* const world = serd_world_new(); + SerdWorld* const world = serd_world_new(NULL); size_t n_statements = 0; FILE* const f = tmpfile(); SerdSink* const sink = serd_sink_new(world, &n_statements, count_statements, NULL); + assert(sink); SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); @@ -377,7 +463,7 @@ check_cursor(void* handle, const SerdEvent* event) static void test_error_cursor(void) { - SerdWorld* world = serd_world_new(); + SerdWorld* world = serd_world_new(NULL); bool called = false; SerdSink* sink = serd_sink_new(world, &called, check_cursor, NULL); SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); @@ -391,7 +477,7 @@ test_error_cursor(void) "<http://example.org/s> <http://example.org/p> " "<http://example.org/o> ."; - SerdNode* const string_name = serd_new_string(SERD_STRING("string")); + SerdNode* const string_name = serd_new_string(NULL, SERD_STRING("string")); const char* position = string; SerdInputStream in = serd_open_input_string(&position); @@ -402,7 +488,7 @@ test_error_cursor(void) assert(called); assert(!serd_close_input(&in)); - serd_node_free(string_name); + serd_node_free(NULL, string_name); serd_reader_free(reader); serd_env_free(env); serd_sink_free(sink); @@ -412,6 +498,8 @@ test_error_cursor(void) int main(void) { + test_new_failed_alloc(); + test_start_failed_alloc(); test_prepare_error(); test_read_string(); test_read_eof_by_page(); |