summaryrefslogtreecommitdiffstats
path: root/src/lib-index/test-mail-index-write.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib-index/test-mail-index-write.c')
-rw-r--r--src/lib-index/test-mail-index-write.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/lib-index/test-mail-index-write.c b/src/lib-index/test-mail-index-write.c
new file mode 100644
index 0000000..88eaa4a
--- /dev/null
+++ b/src/lib-index/test-mail-index-write.c
@@ -0,0 +1,151 @@
+/* Copyright (c) 2020 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "test-common.h"
+#include "mail-index-private.h"
+#include "mail-transaction-log-private.h"
+
+#define TEST_INDEX_FNAME ".test.index.write"
+#define TEST_INDEXID 123456
+#define LOG_FILE1_HEAD_OFFSET 200
+
+static bool expect_index_rewrite;
+static bool rotate_fail;
+
+static struct mail_transaction_log_file log_file = {
+ .hdr = {
+ .indexid = TEST_INDEXID,
+ .file_seq = 1,
+ },
+};
+static struct mail_transaction_log_file log_file2 = {
+ .hdr = {
+ .indexid = TEST_INDEXID,
+ .file_seq = 2,
+ .prev_file_seq = 1,
+ .prev_file_offset = LOG_FILE1_HEAD_OFFSET,
+ },
+};
+
+void mail_index_set_error(struct mail_index *index ATTR_UNUSED,
+ const char *fmt ATTR_UNUSED, ...)
+{
+}
+
+void mail_index_set_syscall_error(struct mail_index *index ATTR_UNUSED,
+ const char *function)
+{
+ i_error("%s() failed: %m", function);
+}
+
+void mail_index_file_set_syscall_error(struct mail_index *index ATTR_UNUSED,
+ const char *filepath,
+ const char *function)
+{
+ i_error("%s(%s) failed: %m", function, filepath);
+}
+
+int mail_index_create_tmp_file(struct mail_index *index ATTR_UNUSED,
+ const char *path_prefix, const char **path_r)
+{
+ const char *path;
+ int fd;
+
+ test_assert(expect_index_rewrite);
+
+ path = *path_r = t_strconcat(path_prefix, ".tmp", NULL);
+ fd = open(path, O_RDWR|O_CREAT, 0600);
+ if (fd == -1) {
+ i_error("creat() failed: %m");
+ return -1;
+ }
+ return fd;
+}
+
+int mail_index_move_to_memory(struct mail_index *index ATTR_UNUSED)
+{
+ return -1;
+}
+
+int mail_transaction_log_rotate(struct mail_transaction_log *log, bool reset)
+{
+ i_assert(!reset);
+
+ if (rotate_fail)
+ return -1;
+
+ log_file.next = &log_file2;
+ log->head = &log_file2;
+ return 0;
+}
+
+static void test_mail_index_write(void)
+{
+ struct mail_transaction_log log = {
+ .head = &log_file,
+ .files = &log_file,
+ };
+ struct mail_index_record_map rec_map = {
+ .records_count = 0,
+ };
+ buffer_t hdr_copy;
+ struct mail_index_map map = {
+ .hdr = {
+ .indexid = TEST_INDEXID,
+ .log_file_seq = 1,
+ .log_file_tail_offset = 100,
+ .log_file_head_offset = LOG_FILE1_HEAD_OFFSET,
+ },
+ .hdr_copy_buf = &hdr_copy,
+ .rec_map = &rec_map,
+ };
+ buffer_create_from_const_data(&hdr_copy, &map.hdr, sizeof(map.hdr));
+ struct mail_index index = {
+ .event = event_create(NULL),
+ .log = &log,
+ .map = &map,
+ .dir = ".",
+ .fd = -1,
+ .indexid = TEST_INDEXID,
+ .filepath = TEST_INDEX_FNAME,
+ .log_sync_locked = TRUE,
+ };
+
+ test_begin("test_mail_index_write()");
+
+ /* test failed rotation, no index rewrite */
+ rotate_fail = TRUE;
+ expect_index_rewrite = FALSE;
+ test_assert(!index.reopen_main_index);
+ index.fd = 1; /* anything but -1 */
+ mail_index_write(&index, TRUE, "testing");
+ test_assert(log.head == log.files);
+ test_assert(index.reopen_main_index);
+
+ /* test failed rotation, with index rewrite */
+ expect_index_rewrite = TRUE;
+ index.reopen_main_index = FALSE;
+ index.fd = -1;
+ mail_index_write(&index, TRUE, "testing");
+ test_assert(log.head == log.files);
+ test_assert(!index.reopen_main_index);
+
+ /* test successful rotation, with index rewrite */
+ rotate_fail = FALSE;
+ mail_index_write(&index, TRUE, "testing");
+ test_assert(log.head != log.files && log.head == &log_file2);
+ test_assert(!index.reopen_main_index);
+
+ event_unref(&index.event);
+ i_unlink(TEST_INDEX_FNAME);
+ test_end();
+}
+
+int main(void)
+{
+ static void (*const test_functions[])(void) = {
+ test_mail_index_write,
+ NULL
+ };
+ return test_run(test_functions);
+}