From d68e9de33d3243d6df9beea6d75561960f8cb8f3 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 24 May 2017 21:56:03 +0300 Subject: [PATCH] lib-storage: Add unit test for set/get/push/pop storage error operations --- src/lib-storage/Makefile.am | 5 + src/lib-storage/test-mail-storage.c | 184 ++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+) create mode 100644 src/lib-storage/test-mail-storage.c diff --git a/src/lib-storage/Makefile.am b/src/lib-storage/Makefile.am index 03702ed47b..e81ff66062 100644 --- a/src/lib-storage/Makefile.am +++ b/src/lib-storage/Makefile.am @@ -123,6 +123,7 @@ libdovecot_storage_la_LDFLAGS = -export-dynamic test_programs = \ test-mail-search-args-imap \ test-mail-search-args-simplify \ + test-mail-storage \ test-mailbox-get noinst_PROGRAMS = $(test_programs) @@ -143,6 +144,10 @@ test_mailbox_get_SOURCES = test-mailbox-get.c test_mailbox_get_LDADD = mailbox-get.lo $(test_libs) test_mailbox_get_DEPENDENCIES = $(noinst_LTLIBRARIES) $(test_libs) +test_mail_storage_SOURCES = test-mail-storage.c +test_mail_storage_LDADD = libstorage.la $(LIBDOVECOT) +test_mail_storage_DEPENDENCIES = libstorage.la $(LIBDOVECOT_DEPS) + check: check-am check-test check-test: all-am for bin in $(test_programs); do \ diff --git a/src/lib-storage/test-mail-storage.c b/src/lib-storage/test-mail-storage.c new file mode 100644 index 0000000000..3e43f695bb --- /dev/null +++ b/src/lib-storage/test-mail-storage.c @@ -0,0 +1,184 @@ +/* Copyright (c) 2017 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "test-common.h" +#include "mail-storage-private.h" + +static void test_mail_storage_errors(void) +{ + struct mail_storage storage; + enum mail_error mail_error; + const char *errstr; + + test_begin("mail storage errors"); + i_zero(&storage); + + /* try a regular error */ + mail_storage_set_error(&storage, MAIL_ERROR_PERM, "error1"); + test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "error1") == 0); + test_assert(mail_error == MAIL_ERROR_PERM); + test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "error1") == 0); + test_assert(mail_error == MAIL_ERROR_PERM); + test_assert(!storage.last_error_is_internal); + + /* set the error to itself */ + mail_storage_set_error(&storage, MAIL_ERROR_PARAMS, + mail_storage_get_last_error(&storage, &mail_error)); + test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "error1") == 0); + test_assert(mail_error == MAIL_ERROR_PARAMS); + test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "error1") == 0); + test_assert(mail_error == MAIL_ERROR_PARAMS); + test_assert(!storage.last_error_is_internal); + + /* clear the error - asking for it afterwards is a bug */ + mail_storage_clear_error(&storage); + test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "BUG: Unknown internal error") == 0); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "BUG: Unknown internal error") == 0); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(!storage.last_error_is_internal); + + /* internal error without specifying what it is */ + mail_storage_set_internal_error(&storage); + test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(strstr(mail_storage_get_last_internal_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(!storage.last_error_is_internal); + + /* proper internal error */ + test_expect_error_string("critical1"); + mail_storage_set_critical(&storage, "critical1"); + test_expect_no_more_errors(); + test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical1") == 0); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(storage.last_error_is_internal); + + /* use it in the following internal error */ + test_expect_error_string("critical2: critical1"); + mail_storage_set_critical(&storage, "critical2: %s", + mail_storage_get_last_internal_error(&storage, &mail_error)); + test_expect_no_more_errors(); + test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical2: critical1") == 0); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(storage.last_error_is_internal); + + /* use the previous non-internal error as part of the internal error */ + test_expect_error_string("critical3: "MAIL_ERRSTR_CRITICAL_MSG); + mail_storage_set_critical(&storage, "critical3: %s", + mail_storage_get_last_error(&storage, &mail_error)); + test_expect_no_more_errors(); + test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL); + test_assert(mail_error == MAIL_ERROR_TEMP); + errstr = mail_storage_get_last_internal_error(&storage, &mail_error); + test_assert(strncmp(errstr, "critical3: ", 11) == 0); + test_assert(strstr(errstr+11, MAIL_ERRSTR_CRITICAL_MSG) != NULL); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(storage.last_error_is_internal); + + /* clear the error again and check that all is as expected */ + mail_storage_clear_error(&storage); + test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "BUG: Unknown internal error") == 0); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "BUG: Unknown internal error") == 0); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(!storage.last_error_is_internal); + + /* use internal error as a regular error (although that really + shouldn't be done) */ + test_expect_error_string("critical4"); + mail_storage_set_critical(&storage, "critical4"); + mail_storage_set_error(&storage, MAIL_ERROR_PARAMS, + mail_storage_get_last_internal_error(&storage, &mail_error)); + test_expect_no_more_errors(); + test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "critical4") == 0); + test_assert(mail_error == MAIL_ERROR_PARAMS); + test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical4") == 0); + test_assert(mail_error == MAIL_ERROR_PARAMS); + test_assert(!storage.last_error_is_internal); + + mail_storage_clear_error(&storage); + test_end(); +} + +static void test_mail_storage_last_error_push_pop(void) +{ + struct mail_storage storage; + enum mail_error mail_error; + + test_begin("mail_storage_last_error_push/pop()"); + i_zero(&storage); + + /* regular error 1 */ + mail_storage_set_error(&storage, MAIL_ERROR_PERM, "regular error 1"); + mail_storage_last_error_push(&storage); + + /* critical error 1 */ + test_expect_error_string("critical error 1"); + mail_storage_set_critical(&storage, "critical error 1"); + test_expect_no_more_errors(); + mail_storage_last_error_push(&storage); + + /* regular error 2 */ + mail_storage_set_error(&storage, MAIL_ERROR_PARAMS, "regular error 2"); + mail_storage_last_error_push(&storage); + + /* critical error 2 */ + test_expect_error_string("critical error 2"); + mail_storage_set_critical(&storage, "critical error 2"); + test_expect_no_more_errors(); + mail_storage_last_error_push(&storage); + + /* -- clear all errors -- */ + mail_storage_clear_error(&storage); + + /* critical error 2 pop */ + mail_storage_last_error_pop(&storage); + test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical error 2") == 0); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(storage.last_error_is_internal); + + /* regular error 2 pop */ + mail_storage_last_error_pop(&storage); + test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "regular error 2") == 0); + test_assert(mail_error == MAIL_ERROR_PARAMS); + test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "regular error 2") == 0); + test_assert(mail_error == MAIL_ERROR_PARAMS); + test_assert(!storage.last_error_is_internal); + + /* critical error 1 pop */ + mail_storage_last_error_pop(&storage); + test_assert(strstr(mail_storage_get_last_error(&storage, &mail_error), MAIL_ERRSTR_CRITICAL_MSG) != NULL); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "critical error 1") == 0); + test_assert(mail_error == MAIL_ERROR_TEMP); + test_assert(storage.last_error_is_internal); + + /* regular error 1 pop */ + mail_storage_last_error_pop(&storage); + test_assert(strcmp(mail_storage_get_last_error(&storage, &mail_error), "regular error 1") == 0); + test_assert(mail_error == MAIL_ERROR_PERM); + test_assert(strcmp(mail_storage_get_last_internal_error(&storage, &mail_error), "regular error 1") == 0); + test_assert(mail_error == MAIL_ERROR_PERM); + test_assert(!storage.last_error_is_internal); + + mail_storage_clear_error(&storage); + test_end(); +} + +int main(void) +{ + static void (*const test_functions[])(void) = { + test_mail_storage_errors, + test_mail_storage_last_error_push_pop, + NULL + }; + + return test_run(test_functions); +}