summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVivien Kraus <vivien@planete-kraus.eu>2023-04-29 22:40:54 +0200
committerVivien Kraus <vivien@planete-kraus.eu>2023-05-10 00:01:17 +0200
commit49686dd0c18bc8474f312f3e265c4467bd548628 (patch)
treeb6f313afbf06932c7f5e06c45f0bed6f4379a9b2 /src
parent7ae97c9c9c9bab8e8406cdc5dbc61c5c4d4603a5 (diff)
Check many concurrent updates for the append-only file.
Diffstat (limited to 'src')
-rw-r--r--src/libdisfluid/disfluid-tests.h145
-rw-r--r--src/libdisfluid/main.c19
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)
{