bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2017-2018 Dovecot authors, see the included COPYING file */
6610dc505a7053e6d52e79cc865e845f44901f4cTimo Sirainenstatic void test_init_storage(struct mail_storage *storage_r)
6610dc505a7053e6d52e79cc865e845f44901f4cTimo Sirainenstatic void test_deinit_storage(struct mail_storage *storage)
6610dc505a7053e6d52e79cc865e845f44901f4cTimo Sirainen if (array_is_created(&storage->error_stack)) {
6610dc505a7053e6d52e79cc865e845f44901f4cTimo Sirainen i_assert(array_count(&storage->error_stack) == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* try a regular error */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_set_error(&storage, MAIL_ERROR_PERM, "error1");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "error1") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "error1") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* set the error to itself */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_set_error(&storage, MAIL_ERROR_PARAMS,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_get_last_error(&storage, &mail_error));
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "error1") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "error1") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* clear the error - asking for it afterwards is a bug */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "BUG: Unknown internal error") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "BUG: Unknown internal error") == 0);
fe7a56906e8bdf6e42cc981b4a62e31bac4a30f4Timo Sirainen /* set internal error in preparation for the next test */
fe7a56906e8bdf6e42cc981b4a62e31bac4a30f4Timo Sirainen mail_storage_set_critical(&storage, "critical0");
fe7a56906e8bdf6e42cc981b4a62e31bac4a30f4Timo Sirainen test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
fe7a56906e8bdf6e42cc981b4a62e31bac4a30f4Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical0") == 0);
fe7a56906e8bdf6e42cc981b4a62e31bac4a30f4Timo Sirainen /* internal error without specifying what it is. this needs to clear
fe7a56906e8bdf6e42cc981b4a62e31bac4a30f4Timo Sirainen the previous internal error. */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strstr(mail_storage_get_last_internal_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* proper internal error */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_set_critical(&storage, "critical1");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical1") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* use it in the following internal error */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_expect_error_string("critical2: critical1");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_set_critical(&storage, "critical2: %s",
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_get_last_internal_error(&storage, &mail_error));
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical2: critical1") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* use the previous non-internal error as part of the internal error */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_expect_error_string("critical3: "MAIL_ERRSTR_CRITICAL_MSG);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_set_critical(&storage, "critical3: %s",
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_get_last_error(&storage, &mail_error));
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen errstr = mail_storage_get_last_internal_error(&storage, &mail_error);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strncmp(errstr, "critical3: ", 11) == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strstr(errstr+11, MAIL_ERRSTR_CRITICAL_MSG) != NULL);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* clear the error again and check that all is as expected */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "BUG: Unknown internal error") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "BUG: Unknown internal error") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* use internal error as a regular error (although that really
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen shouldn't be done) */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_set_critical(&storage, "critical4");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_set_error(&storage, MAIL_ERROR_PARAMS,
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_get_last_internal_error(&storage, &mail_error));
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "critical4") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical4") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainenstatic void test_mail_storage_last_error_push_pop(void)
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_begin("mail_storage_last_error_push/pop()");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* regular error 1 */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_set_error(&storage, MAIL_ERROR_PERM, "regular error 1");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* critical error 1 */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_set_critical(&storage, "critical error 1");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* regular error 2 */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_set_error(&storage, MAIL_ERROR_PARAMS, "regular error 2");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* critical error 2 */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen mail_storage_set_critical(&storage, "critical error 2");
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* -- clear all errors -- */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* critical error 2 pop */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical error 2") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* regular error 2 pop */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "regular error 2") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "regular error 2") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* critical error 1 pop */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical error 1") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen /* regular error 1 pop */
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "regular error 1") == 0);
55ca77c6ae6a081cdf6cc4dd515959afb9840da9Timo Sirainen test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "regular error 1") == 0);
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomistatic void test_mail_init(struct test_mail_storage_ctx *ctx)
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi ctx->mail_home = p_strdup_printf(ctx->pool, "%s/.test-dir%s/", path_buf,
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi if (unlink_directory(ctx->mail_home, UNLINK_DIRECTORY_FLAG_RMDIR, &error) < 0 &&
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi i_warning("unlink_directory(%s) failed: %s", ctx->mail_home, error);
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi ctx->storage_service = mail_storage_service_init(master_service, NULL,
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomistatic void test_mail_deinit(struct test_mail_storage_ctx *ctx)
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi mail_storage_service_deinit(&ctx->storage_service);
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi if (unlink_directory(ctx->mail_home, UNLINK_DIRECTORY_FLAG_RMDIR,
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi i_error("unlink_directory(%s) failed: %s", ctx->mail_home, error);
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomistatic int test_mail_init_user(const char *user, const char *driver,
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi const char *const *extra_input,
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi home = t_strdup_printf("%s%s", ctx->mail_home, user);
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi t_strdup_printf("mail=%s:~/%s", driver, driver_opts),
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi "postmaster_address=postmaster@localhost",
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi "namespace=inbox",
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi t_strdup_printf("namespace/inbox/separator=%s", sep),
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi if (unlink_directory(home, UNLINK_DIRECTORY_FLAG_RMDIR, &error) < 0)
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi i_assert(mkdir_parents(home, S_IRWXU)==0 || errno == EEXIST);
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi array_append(&opts, default_input, N_ELEMENTS(default_input));
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi if (mail_storage_service_lookup_next(ctx->storage_service, &input,
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi i_error("mail_storage_service_lookup_next(%s) failed: %s",
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi#define test_mail_init_maildir_user(user) test_mail_init_user(user,"maildir","",NULL)
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomistatic void test_mail_deinit_user(struct test_mail_storage_ctx *ctx)
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi mail_storage_service_user_unref(&ctx->service_user);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomitest_mailbox_verify_name_one(struct mailbox_verify_test_cases *test_case,
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_case->list_sep, mailbox_list_get_hierarchy_sep(ns->list));
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi i_debug("Failed test for mailbox %s: %s", test_case->box, error);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi /* Cannot rename to INBOX */
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi struct mailbox *src = mailbox_alloc(ns->list, "RENAME", 0);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi /* check if the mailbox exists */
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi if (ret != 0) {
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_case->list_sep, mailbox_list_get_hierarchy_sep(ns->list));
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi i_debug("Failed test for mailbox %s: %s", test_case->box, error);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomitest_mailbox_verify_name_continue(struct mailbox_verify_test_cases *test_cases,
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi (test_cases[i].ns_sep != mail_namespace_get_sep(ns))) ||
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_cases[i].list_sep != mailbox_list_get_hierarchy_sep(ns->list)))
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_mailbox_verify_name_one(&test_cases[i], ns, i);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomistatic void test_mailbox_verify_name_driver_slash(const char *driver,
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi "namespace=subspace",
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi if (test_mail_init_user("testuser", driver, driver_opts, "/", ns2, ctx) < 0)
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_mailbox_verify_name_continue(test_cases, N_ELEMENTS(test_cases), ctx);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomistatic void test_mailbox_verify_name_driver_dot(const char *driver,
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi "namespace=subspace",
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi if (test_mail_init_user("testuser", driver, driver_opts, ".", ns2, ctx) < 0)
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_mailbox_verify_name_continue(test_cases, N_ELEMENTS(test_cases), ctx);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi { "maildir LAYOUT=INDEX", "maildir", ":LAYOUT=INDEX" },
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi { "sdbox LAYOUT=INDEX", "sdbox", ":LAYOUT=INDEX" },
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi { "mdbox LAYOUT=INDEX", "mdbox", ":LAYOUT=INDEX" },
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi for(unsigned int i = 0; i < N_ELEMENTS(test_cases); i++) T_BEGIN {
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_begin(t_strdup_printf("mailbox_verify_name (%s SEP=.)", test_cases[i].name));
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_mailbox_verify_name_driver_dot(test_cases[i].driver, test_cases[i].opts, &ctx);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_begin(t_strdup_printf("mailbox_verify_name (%s SEP=/)", test_cases[i].name));
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_mailbox_verify_name_driver_slash(test_cases[i].driver, test_cases[i].opts, &ctx);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomistatic void test_mailbox_list_maildir_continue(struct test_mail_storage_ctx *ctx)
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_mailbox_verify_name_continue(test_cases, N_ELEMENTS(test_cases), ctx);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomistatic void test_mailbox_list_maildir_init(struct test_mail_storage_ctx *ctx,
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi "namespace=subspace",
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi t_strdup_printf("namespace/subspace/separator=%s", sep),
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi t_strdup_printf("namespace/subspace/prefix=SubSpace%s", sep),
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi if (test_mail_init_user("testuser", "maildir", driver_opts, sep, ns2, ctx) < 0)
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi struct mailbox *box = mailbox_alloc(ns->list, "SubSpace", 0);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi box = mailbox_alloc(ns->list, t_strdup_printf("SubSpace%sInner", sep), 0);
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_begin("mailbox_verify_name (maildir SEP=.)");
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_begin("mailbox_verify_name (maildir SEP=/)");
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_begin("mailbox_verify_name (maildir SEP=. LAYOUT=FS)");
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_mailbox_list_maildir_init(&ctx, "LAYOUT=FS", ".");
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_begin("mailbox_verify_name (maildir SEP=/ LAYOUT=FS)");
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi test_mailbox_list_maildir_init(&ctx, "LAYOUT=FS", "/");
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi /* check that .lock cannot be used */
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi if (test_mail_init_user("testuser", "mbox", "", ".", NULL, &ctx) < 0)
66fa646212a2c1cfd3ec45f97488b6a8ae41cdc0Aki Tuomi ns = mail_namespace_find_inbox(ctx.user->namespaces);
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi void (*const tests[])(void) = {
e3fd3e1a6aac7cba78b147bcdd06eedb34039f3dAki Tuomi master_service = master_service_init("test-mail-storage",