/* Copyright (c) 2017-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "mkdir-parents.h"
#include "unlink-directory.h"
#include "hex-binary.h"
#include "randgen.h"
#include "test-common.h"
#include "master-service.h"
#include "mail-storage-service.h"
#include "mail-storage-private.h"
{
}
{
}
}
struct test_mail_storage_ctx {
const char *mail_home;
};
static void test_mail_storage_errors(void)
{
const char *errstr;
test_begin("mail storage errors");
/* try a regular error */
/* set the error to itself */
/* clear the error - asking for it afterwards is a bug */
test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "BUG: Unknown internal error") == 0);
test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "BUG: Unknown internal error") == 0);
/* set internal error in preparation for the next test */
test_expect_error_string("critical0");
test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
/* internal error without specifying what it is. this needs to clear
the previous internal error. */
test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
test_assert(strstr(mail_storage_get_last_internal_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
/* proper internal error */
test_expect_error_string("critical1");
test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
/* use it in the following internal error */
test_expect_error_string("critical2: critical1");
test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical2: critical1") == 0);
/* use the previous non-internal error as part of the internal error */
test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
/* clear the error again and check that all is as expected */
test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "BUG: Unknown internal error") == 0);
test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "BUG: Unknown internal error") == 0);
/* use internal error as a regular error (although that really
shouldn't be done) */
test_expect_error_string("critical4");
test_end();
}
static void test_mail_storage_last_error_push_pop(void)
{
/* regular error 1 */
/* critical error 1 */
test_expect_error_string("critical error 1");
/* regular error 2 */
/* critical error 2 */
test_expect_error_string("critical error 2");
/* -- clear all errors -- */
/* critical error 2 pop */
test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical error 2") == 0);
/* regular error 2 pop */
test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "regular error 2") == 0);
/* critical error 1 pop */
test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL);
test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical error 1") == 0);
/* regular error 1 pop */
test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "regular error 1") == 0);
test_end();
}
{
const char *error;
i_fatal("getcwd() failed: %m");
}
{
const char *error;
if (chdir("..") < 0)
i_fatal("chdir(..) failed: %m");
&error) < 0)
}
const char *driver_opts, const char *sep,
const char *const *extra_input,
struct test_mail_storage_ctx *ctx)
{
const char *const default_input[] = {
"postmaster_address=postmaster@localhost",
"namespace=inbox",
};
if (extra_input != NULL)
while(*extra_input != NULL)
.no_userdb_lookup = TRUE,
};
&error) < 0) {
i_error("mail_storage_service_lookup_next(%s) failed: %s",
return -1;
}
return 0;
}
{
}
struct mailbox_verify_test_cases {
char ns_sep;
char list_sep;
const char *box;
int ret;
} test_cases[] = {
{ '\0', '\0', "INBOX", 0 },
{ '/', '/', ".DUMPSTER", 0 },
{ '\0', '\0', "DUMPSTER", 0 },
{ '\0', '\0', "~DUMPSTER", -1 },
{ '.', '.', "foo.bar", 0 },
{ '/', '.', "foo.bar", -1 },
{ '.', '/', "foo.bar", 0 },
{ '/', '/', "foo.bar", 0 },
{ '/', '\0', "/foo", -1 },
{ '/', '\0', "foo/", -1 },
{ '/', '\0', "foo//bar", -1 },
{ '.', '/', "/foo", -1 },
{ '.', '/', "foo/", -1 },
{ '.', '/', "foo//bar", -1 },
{ '.', '.', ".foo", -1 },
{ '.', '.', "foo.", -1 },
{ '.', '.', "foo..bar", -1 },
{ '.', '/', ".foo", -1 },
{ '.', '/', "foo.", -1 },
{ '.', '/', "foo..bar", -1 },
{ '.', '/', "/", -1 },
{ '.', '.', ".", -1 },
{ '/', '\0', "/", -1 },
{ '\0', '/', "/", -1 },
{ '\0', '\0', "", -1 },
};
static void
struct mail_namespace *ns,
size_t i)
{
int ret;
#ifdef DEBUG
i_debug("%c == %c %c == %c",
if (ret < 0)
}
#endif
/* Cannot rename to INBOX */
test_assert_idx(ret == 0, i);
mailbox_free(&box);
return;
}
/* check if the mailbox exists */
test_assert_idx(ret == 0, i);
if (ret != 0) {
mailbox_free(&box);
mailbox_free(&src);
return;
}
if (exists == MAILBOX_EXISTENCE_NONE)
#ifdef DEBUG
i_debug("%c == %c %c == %c",
if (ret < 0)
}
#endif
mailbox_free(&box);
mailbox_free(&src);
}
static void
{
continue;
}
}
const char *driver_opts,
struct test_mail_storage_ctx *ctx)
{
const char *const ns2[] = {
"namespace=subspace",
};
return;
}
const char *driver_opts,
struct test_mail_storage_ctx *ctx)
{
const char *const ns2[] = {
"namespace=subspace",
};
return;
}
static void test_mailbox_verify_name(void)
{
struct {
const char *name;
const char *driver;
const char *opts;
} test_cases[] = {
{ "mbox", "mbox", "" },
{ "mbox LAYOUT=FS", "mbox", ":LAYOUT=FS" },
{ "mbox LAYOUT=INDEX", "mbox", ":LAYOUT=INDEX" },
{ "maildir LAYOUT=INDEX", "maildir", ":LAYOUT=INDEX" },
{ "sdbox", "sdbox", "" },
{ "sdbox LAYOUT=FS", "sdbox", ":LAYOUT=FS" },
{ "sdbox LAYOUT=INDEX", "sdbox", ":LAYOUT=INDEX" },
{ "mdbox", "mdbox", "" },
{ "mdbox LAYOUT=FS", "mdbox", ":LAYOUT=FS" },
{ "mdbox LAYOUT=INDEX", "mdbox", ":LAYOUT=INDEX" },
};
test_end();
test_end();
} T_END;
}
{
{ '\0', '\0', "INBOX", 0 },
{ '/', '/', ".DUMPSTER", 0 },
{ '\0', '\0', "DUMPSTER", 0 },
{ '\0', '\0', "~DUMPSTER", -1 },
{ '.', '/', "INBOX.new", -1 },
{ '.', '/', "SubSpace.new", -1 },
{ '.', '.', "foo.bar", 0 },
{ '/', '.', "foo.bar", -1 },
{ '.', '/', "foo.bar", 0 },
{ '/', '/', "foo.bar", 0 },
{ '/', '\0', "/foo", -1 },
{ '/', '\0', "foo/", -1 },
{ '/', '\0', "foo//bar", -1 },
{ '.', '/', "/foo", -1 },
{ '.', '/', "foo/", -1 },
{ '.', '/', "foo//bar", -1 },
{ '.', '.', ".foo", -1 },
{ '.', '.', "foo.", -1 },
{ '.', '.', "foo..bar", -1 },
{ '.', '/', ".foo", -1 },
{ '.', '/', "foo.", -1 },
{ '.', '/', "foo..bar", -1 },
{ '.', '/', "/", -1 },
{ '.', '.', ".", -1 },
{ '/', '\0', "/", -1 },
{ '\0', '/', "/", -1 },
{ '\0', '\0', "", -1 },
};
}
const char *driver_opts, const char *sep)
{
const char *const ns2[] = {
"namespace=subspace",
};
i_unreached();
test_assert(ret == 0);
#ifdef DEBUG
if (ret < 0) {
i_debug("Failed test for mailbox %s: %s",
}
#endif
mailbox_free(&box);
test_assert(ret == 0);
#ifdef DEBUG
if (ret < 0) {
i_debug("Failed test for mailbox %s: %s",
}
#endif
mailbox_free(&box);
}
static void test_mailbox_list_maildir(void)
{
test_begin("mailbox_verify_name (maildir SEP=.)");
test_end();
test_begin("mailbox_verify_name (maildir SEP=/)");
test_end();
test_begin("mailbox_verify_name (maildir SEP=. LAYOUT=FS)");
test_end();
test_begin("mailbox_verify_name (maildir SEP=/ LAYOUT=FS)");
test_end();
}
static void test_mailbox_list_mbox(void)
{
test_begin("mailbox_list_mbox");
/* check that .lock cannot be used */
i_unreached();
test_end();
}
{
int ret;
void (*const tests[])(void) = {
};
return ret;
}