diff options
Diffstat (limited to 'src/lib-index/test-mail-index-write.c')
-rw-r--r-- | src/lib-index/test-mail-index-write.c | 151 |
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); +} |