diff options
author | Vivien Kraus <vivien@planete-kraus.eu> | 2023-04-29 22:40:54 +0200 |
---|---|---|
committer | Vivien Kraus <vivien@planete-kraus.eu> | 2023-05-10 00:01:17 +0200 |
commit | 49686dd0c18bc8474f312f3e265c4467bd548628 (patch) | |
tree | b6f313afbf06932c7f5e06c45f0bed6f4379a9b2 /src | |
parent | 7ae97c9c9c9bab8e8406cdc5dbc61c5c4d4603a5 (diff) |
Check many concurrent updates for the append-only file.
Diffstat (limited to 'src')
-rw-r--r-- | src/libdisfluid/disfluid-tests.h | 145 | ||||
-rw-r--r-- | src/libdisfluid/main.c | 19 |
2 files changed, 164 insertions, 0 deletions
diff --git a/src/libdisfluid/disfluid-tests.h b/src/libdisfluid/disfluid-tests.h index 50b5a9f..9cb41d9 100644 --- a/src/libdisfluid/disfluid-tests.h +++ b/src/libdisfluid/disfluid-tests.h @@ -5,6 +5,11 @@ struct disfluid_tests_report; static inline char *run_tests (size_t *n_tests, size_t *n_errors); +static inline int test_append_init (int *fd, char **filename); +static inline int test_append_hello (const char *filename, size_t *n_before, + size_t *n_after); +static inline int test_append_count (const char *filename, size_t *n); + # include <check.h> # include "disfluid-trie-node.h" @@ -735,4 +740,144 @@ run_tests (size_t *n_tests, size_t *n_errors) return result; } +static inline int +test_append_init (int *fd, char **filename) +{ + ensure_init (); + int error = 0; + *fd = -1; + *filename = NULL; + static const char model[] = "/tmp/disfluid-test-append-XXXXXX"; + if (ALLOC_N (*filename, strlen (model) + 1) < 0) + { + error = -2; + goto cleanup; + } + strcpy (*filename, model); + *fd = mkstemp (*filename); + if (*fd == -1) + { + error = -1; + FREE (*filename); + goto cleanup; + } + static const char *magic_data = "disfluid appendt"; + const string_desc_t magic = { + ._data = (char *) magic_data, + ._nbytes = strlen (magic_data) + }; + if (ao_file_prepare (*fd, magic) < 0) + { + error = -1; + goto cleanup; + } +cleanup: + if (error != 0) + { + FREE (*filename); + if (*fd >= 0) + { + close (*fd); + *fd = -1; + } + } + return error; +} + +static inline int +test_append_hello (const char *filename, size_t *n_before, size_t *n_after) +{ + ensure_init (); + if (test_append_count (filename, n_before) < 0) + { + return -1; + } + int file = open (filename, O_RDWR); + int error = 0; + if (file == -1) + { + return -1; + } + size_t top; + if (ao_file_lock_for_writing (file, &top) < 0) + { + error = -1; + goto cleanup; + } + static const char *hello_data = "Hello!"; + const string_desc_t hello = { + ._nbytes = strlen (hello_data), + ._data = (char *) hello_data + }; + if (ao_file_push_data (file, hello, &top) < 0) + { + error = -1; + goto cleanup; + } + if (ao_file_commit_transaction (file) < 0) + { + error = -1; + goto cleanup; + } +cleanup: + close (file); + if (error == 0) + { + if (test_append_count (filename, n_after) < 0) + { + return -1; + } + if (n_before >= n_after) + { + return -1; + } + } + return error; +} + +static inline int +test_append_count (const char *filename, size_t *n) +{ + ensure_init (); + *n = 0; + size_t top; + int error = 0; + int file = open (filename, O_RDWR); + if (file == -1) + { + return -1; + } + if (ao_file_read_top (file, &top) < 0) + { + error = -1; + goto cleanup; + } + if (top % strlen ("Hello!") != 0) + { + error = -2; + goto cleanup; + } + while (top != 0) + { + char data[6]; + assert (sizeof (data) == strlen ("Hello!")); + string_desc_t next = {._nbytes = sizeof (data),._data = data }; + if (ao_file_read (file, top, next) < 0) + { + error = -2; + goto cleanup; + } + if (memcmp (data, "Hello!", sizeof (data)) != 0) + { + error = -2; + goto cleanup; + } + top -= sizeof (data); + *n += 1; + } +cleanup: + close (file); + return error; +} + #endif /* DISFLUID_TESTS_INCLUDED */ diff --git a/src/libdisfluid/main.c b/src/libdisfluid/main.c index dbe7cfb..3a6c5e3 100644 --- a/src/libdisfluid/main.c +++ b/src/libdisfluid/main.c @@ -64,6 +64,25 @@ disfluid_run_tests (size_t *n_tests, size_t *n_errors) return run_tests (n_tests, n_errors); } +int +disfluid_test_append_init (int *fd, char **filename) +{ + return test_append_init (fd, filename); +} + +int +disfluid_test_append_hello (const char *filename, size_t *n_before, + size_t *n_after) +{ + return test_append_hello (filename, n_before, n_after); +} + +int +disfluid_test_append_count (const char *filename, size_t *n) +{ + return test_append_count (filename, n); +} + size_t disfluid_count_authors (void) { |