Mercurial > dovecot > core-2.2
view src/lib-storage/test-mail-storage.c @ 22469:4b1e95fa17e8
lib-storage: Fix error logging after mail_storage_set_internal_error()
The function doesn't actually set the last_internal_error and it also
doesn't update last_error_is_internal, so calling
mail_storage_get_last_internal_error() afterwards could be returning an
error for some different older error.
Since there's no parameter to set the internal error string, just reset
last_error_is_internal=FALSE.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Mon, 21 Aug 2017 15:11:30 +0300 |
parents | 41e9e1c79db3 |
children | cb108f786fb4 |
line wrap: on
line source
/* 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); /* set internal error in preparation for the next test */ test_expect_error_string("critical0"); mail_storage_set_critical(&storage, "critical0"); 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), "critical0") == 0); test_assert(mail_error == MAIL_ERROR_TEMP); test_assert(storage.last_error_is_internal); /* internal error without specifying what it is. this needs to clear the previous internal error. */ 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); i_assert(array_count(&storage.error_stack) == 0); array_free(&storage.error_stack); test_end(); } int main(void) { static void (*test_functions[])(void) = { test_mail_storage_errors, test_mail_storage_last_error_push_pop, NULL }; return test_run(test_functions); }