diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib-index/test-mail-cache-common.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/lib-index/test-mail-cache-common.c b/src/lib-index/test-mail-cache-common.c new file mode 100644 index 0000000..ee34c04 --- /dev/null +++ b/src/lib-index/test-mail-cache-common.c @@ -0,0 +1,166 @@ +/* Copyright (c) 2020 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "test-common.h" +#include "test-mail-cache.h" + +static const struct mail_cache_field cache_field_foo = { + .name = "foo", + .type = MAIL_CACHE_FIELD_STRING, + .decision = MAIL_CACHE_DECISION_YES, +}; +static const struct mail_cache_field cache_field_bar = { + .name = "bar", + .type = MAIL_CACHE_FIELD_STRING, + .decision = MAIL_CACHE_DECISION_YES, +}; +static const struct mail_cache_field cache_field_baz = { + .name = "baz", + .type = MAIL_CACHE_FIELD_STRING, + .decision = MAIL_CACHE_DECISION_YES, +}; + +void test_mail_cache_init(struct mail_index *index, + struct test_mail_cache_ctx *ctx_r) +{ + i_zero(ctx_r); + ctx_r->index = index; + ctx_r->cache = index->cache; + ctx_r->view = mail_index_view_open(index); + + ctx_r->cache_field = cache_field_foo; + ctx_r->cache_field2 = cache_field_bar; + ctx_r->cache_field3 = cache_field_baz; + /* Try to use different file_field_maps for different index instances + by randomizing the registration order. This only works for the 2nd + index that is opened, because the initial cache is always created + with all cache fields in the same order. */ + if (i_rand_limit(2) == 0) { + mail_cache_register_fields(ctx_r->cache, &ctx_r->cache_field, 1); + mail_cache_register_fields(ctx_r->cache, &ctx_r->cache_field2, 1); + mail_cache_register_fields(ctx_r->cache, &ctx_r->cache_field3, 1); + } else { + mail_cache_register_fields(ctx_r->cache, &ctx_r->cache_field3, 1); + mail_cache_register_fields(ctx_r->cache, &ctx_r->cache_field2, 1); + mail_cache_register_fields(ctx_r->cache, &ctx_r->cache_field, 1); + } +} + +void test_mail_cache_deinit(struct test_mail_cache_ctx *ctx) +{ + if (ctx->view != NULL) + mail_index_view_close(&ctx->view); + test_mail_index_close(&ctx->index); +} + +unsigned int test_mail_cache_get_purge_count(struct test_mail_cache_ctx *ctx) +{ + const struct mail_cache_header *hdr = ctx->cache->hdr; + + return hdr->file_seq - hdr->indexid; +} + +void test_mail_cache_index_sync(struct test_mail_cache_ctx *ctx) +{ + struct mail_index_sync_ctx *sync_ctx; + struct mail_index_view *view; + struct mail_index_transaction *trans; + struct mail_index_sync_rec sync_rec; + + test_assert(mail_index_sync_begin(ctx->index, &sync_ctx, + &view, &trans, 0) == 1); + while (mail_index_sync_next(sync_ctx, &sync_rec)) { + if (sync_rec.type == MAIL_INDEX_SYNC_TYPE_EXPUNGE) { + /* we're a bit kludgily assuming that there's only + one UID and also that uid==seq */ + mail_index_expunge(trans, sync_rec.uid1); + } + } + test_assert(mail_index_sync_commit(&sync_ctx) == 0); +} + +void test_mail_cache_view_sync(struct test_mail_cache_ctx *ctx) +{ + struct mail_index_view_sync_ctx *sync_ctx; + struct mail_index_view_sync_rec sync_rec; + bool delayed_expunges; + + sync_ctx = mail_index_view_sync_begin(ctx->view, MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT); + while (mail_index_view_sync_next(sync_ctx, &sync_rec)) ; + test_assert(mail_index_view_sync_commit(&sync_ctx, &delayed_expunges) == 0); +} + +void test_mail_cache_purge(void) +{ + struct test_mail_cache_ctx ctx; + + test_mail_cache_init(test_mail_index_open(), &ctx); + test_assert(mail_cache_purge(ctx.cache, (uint32_t)-1, "test") == 0); + test_mail_cache_deinit(&ctx); +} + +void test_mail_cache_add_mail(struct test_mail_cache_ctx *ctx, + unsigned int cache_field_idx, + const char *cache_data) +{ + const struct mail_index_header *hdr = mail_index_get_header(ctx->view); + struct mail_index_transaction *trans; + struct mail_index_view *updated_view; + struct mail_cache_view *cache_view; + struct mail_cache_transaction_ctx *cache_trans; + uint32_t seq, uid_validity = 12345; + + trans = mail_index_transaction_begin(ctx->view, 0); + updated_view = mail_index_transaction_open_updated_view(trans); + cache_view = mail_cache_view_open(ctx->cache, updated_view); + cache_trans = mail_cache_get_transaction(cache_view, trans); + + if (hdr->uid_validity == 0) { + mail_index_update_header(trans, + offsetof(struct mail_index_header, uid_validity), + &uid_validity, sizeof(uid_validity), TRUE); + } + + mail_index_append(trans, hdr->next_uid, &seq); + if (cache_field_idx != UINT_MAX) { + mail_cache_add(cache_trans, seq, cache_field_idx, + cache_data, strlen(cache_data)); + } + test_assert(mail_index_transaction_commit(&trans) == 0); + mail_index_view_close(&updated_view); + mail_cache_view_close(&cache_view); + + /* View needs to have the latest changes before purge transaction + is created. */ + test_mail_cache_view_sync(ctx); +} + +void test_mail_cache_add_field(struct test_mail_cache_ctx *ctx, uint32_t seq, + unsigned int cache_field_idx, + const char *cache_data) +{ + struct mail_index_transaction *trans; + struct mail_cache_view *cache_view; + struct mail_cache_transaction_ctx *cache_trans; + + cache_view = mail_cache_view_open(ctx->cache, ctx->view); + trans = mail_index_transaction_begin(ctx->view, 0); + cache_trans = mail_cache_get_transaction(cache_view, trans); + mail_cache_add(cache_trans, seq, cache_field_idx, + cache_data, strlen(cache_data)); + test_assert(mail_index_transaction_commit(&trans) == 0); + mail_cache_view_close(&cache_view); +} + +void test_mail_cache_update_day_first_uid7(struct test_mail_cache_ctx *ctx, + uint32_t first_new_uid) +{ + struct mail_index_transaction *trans; + + trans = mail_index_transaction_begin(ctx->view, 0); + mail_index_update_header(trans, + offsetof(struct mail_index_header, day_first_uid[7]), + &first_new_uid, sizeof(first_new_uid), FALSE); + test_assert(mail_index_transaction_commit(&trans) == 0); + test_mail_cache_view_sync(ctx); +} |