test-mail-index.c (dovecot-2.3.16) | : | test-mail-index.c (dovecot-2.3.17) | ||
---|---|---|---|---|
skipping to change at line 43 | skipping to change at line 43 | |||
/* The 2nd index's log head also doesn't have any extra references. | /* The 2nd index's log head also doesn't have any extra references. | |||
Check that it doesn't crash. */ | Check that it doesn't crash. */ | |||
test_assert(mail_transaction_log_find_file(index2->log, 3, FALSE, &file, &reason) == 0); | test_assert(mail_transaction_log_find_file(index2->log, 3, FALSE, &file, &reason) == 0); | |||
mail_index_view_close(&view); | mail_index_view_close(&view); | |||
test_mail_index_deinit(&index); | test_mail_index_deinit(&index); | |||
test_mail_index_deinit(&index2); | test_mail_index_deinit(&index2); | |||
test_end(); | test_end(); | |||
} | } | |||
static void | ||||
test_mail_index_new_extension_rotate_write(struct mail_index *index2, | ||||
uint32_t uid) | ||||
{ | ||||
struct mail_index_view *view2; | ||||
struct mail_index_transaction *trans; | ||||
uint32_t hdr_ext_id, rec_ext_id, file_seq, seq, rec_ext = 0x12345678; | ||||
uoff_t file_offset; | ||||
/* Rotate the index in the index */ | ||||
test_assert(mail_transaction_log_sync_lock(index2->log, "test", | ||||
&file_seq, &file_offset) == 0) | ||||
; | ||||
mail_index_write(index2, TRUE, "test"); | ||||
mail_transaction_log_sync_unlock(index2->log, "test"); | ||||
/* Write a new extension header to the 2nd index. */ | ||||
hdr_ext_id = mail_index_ext_register(index2, "test", | ||||
sizeof(hdr_ext_id), 0, 0); | ||||
rec_ext_id = mail_index_ext_register(index2, "test-rec", 0, | ||||
sizeof(uint32_t), sizeof(uint32_t)); | ||||
view2 = mail_index_view_open(index2); | ||||
trans = mail_index_transaction_begin(view2, | ||||
MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); | ||||
mail_index_update_header_ext(trans, hdr_ext_id, 0, | ||||
&hdr_ext_id, sizeof(hdr_ext_id)); | ||||
mail_index_append(trans, uid, &seq); | ||||
mail_index_update_ext(trans, seq, rec_ext_id, &rec_ext, NULL); | ||||
test_assert(mail_index_transaction_commit(&trans) == 0); | ||||
mail_index_view_close(&view2); | ||||
} | ||||
static void test_mail_index_new_extension_sync(struct mail_index_view *view) | ||||
{ | ||||
struct mail_index_view_sync_ctx *sync_ctx; | ||||
struct mail_index_view_sync_rec sync_rec; | ||||
bool delayed_expunges; | ||||
test_assert(mail_index_refresh(view->index) == 0); | ||||
sync_ctx = mail_index_view_sync_begin(view, | ||||
MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES); | ||||
test_assert(!mail_index_view_sync_next(sync_ctx, &sync_rec)); | ||||
test_assert(mail_index_view_sync_commit(&sync_ctx, &delayed_expunges) == | ||||
0); | ||||
} | ||||
static void test_mail_index_new_extension(void) | ||||
{ | ||||
struct mail_index *index, *index2; | ||||
struct mail_index_view *view, *view2; | ||||
struct mail_index_transaction *trans; | ||||
uint32_t seq, rec_ext_id, rec_ext = 0x12345678; | ||||
test_begin("mail index new extension"); | ||||
index = test_mail_index_init(); | ||||
index2 = test_mail_index_open(); | ||||
view = mail_index_view_open(index); | ||||
rec_ext_id = mail_index_ext_register(index, "test-rec", 0, | ||||
sizeof(uint32_t), sizeof(uint32_t)); | ||||
/* Save two mails */ | ||||
uint32_t uid_validity = 123456; | ||||
trans = mail_index_transaction_begin(view, | ||||
MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); | ||||
mail_index_update_header(trans, | ||||
offsetof(struct mail_index_header, uid_validity), | ||||
&uid_validity, sizeof(uid_validity), TRUE); | ||||
mail_index_append(trans, 1, &seq); | ||||
mail_index_update_ext(trans, seq, rec_ext_id, &rec_ext, NULL); | ||||
mail_index_append(trans, 2, &seq); | ||||
mail_index_update_ext(trans, seq, rec_ext_id, &rec_ext, NULL); | ||||
test_assert(mail_index_transaction_commit(&trans) == 0); | ||||
/* refresh indexes and view */ | ||||
test_assert(mail_index_refresh(index2) == 0); | ||||
mail_index_view_close(&view); | ||||
view = mail_index_view_open(index); | ||||
/* Expunge the mail in the 2nd index */ | ||||
view2 = mail_index_view_open(index2); | ||||
trans = mail_index_transaction_begin(view2, | ||||
MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); | ||||
mail_index_expunge(trans, 1); | ||||
test_assert(mail_index_transaction_commit(&trans) == 0); | ||||
mail_index_view_close(&view2); | ||||
/* Sync the first view without expunges */ | ||||
test_mail_index_new_extension_sync(view); | ||||
for (unsigned int i = 0; i < 3; i++) | ||||
test_mail_index_new_extension_rotate_write(index2, 3 + i); | ||||
/* Sync the first view. It needs to generate the missing view. */ | ||||
test_expect_error_string("generating missing logs"); | ||||
test_mail_index_new_extension_sync(view); | ||||
test_expect_no_more_errors(); | ||||
test_assert(mail_index_get_header(view)->messages_count == 5); | ||||
/* Make sure the extensions records are still there. | ||||
Note that this works, because the extensions are looked up from the | ||||
newly refreshed index, not the old index. */ | ||||
for (seq = 1; seq <= 5; seq++) { | ||||
const void *data; | ||||
bool expunged; | ||||
mail_index_lookup_ext(view, seq, rec_ext_id, &data, &expunged); | ||||
test_assert_idx(memcmp(data, &rec_ext, sizeof(rec_ext)) == 0, seq | ||||
); | ||||
} | ||||
/* Once more rotate and write using the new extension */ | ||||
test_mail_index_new_extension_rotate_write(index2, 6); | ||||
/* Make sure the first view understands the new extension by ID */ | ||||
test_mail_index_new_extension_sync(view); | ||||
mail_index_view_close(&view); | ||||
test_mail_index_deinit(&index); | ||||
test_mail_index_deinit(&index2); | ||||
test_end(); | ||||
} | ||||
int main(void) | int main(void) | |||
{ | { | |||
static void (*const test_functions[])(void) = { | static void (*const test_functions[])(void) = { | |||
test_mail_index_rotate, | test_mail_index_rotate, | |||
test_mail_index_new_extension, | ||||
NULL | NULL | |||
}; | }; | |||
return test_run(test_functions); | return test_run(test_functions); | |||
} | } | |||
End of changes. 2 change blocks. | ||||
0 lines changed or deleted | 122 lines changed or added |