From 7b048e6cbb9165c6b58fb088e511b5b9a595b599 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Mon, 28 Jul 2008 18:44:23 +0200 Subject: [PATCH] Testsuite: completed support for error validation and added one test case. --- src/lib-sieve/sieve-error.c | 10 +- src/lib-sieve/sieve-error.h | 5 + src/testsuite/Makefile.am | 3 +- .../tests/{ => compile}/errors.svtest | 4 +- .../errors/header.sieve} | 0 src/testsuite/testsuite-common.c | 135 +++++++++++++++++- src/testsuite/testsuite-common.h | 14 +- src/testsuite/testsuite.c | 12 +- src/testsuite/tst-test-compile.c | 15 +- src/testsuite/tst-test-error.c | 35 ++++- 10 files changed, 200 insertions(+), 33 deletions(-) rename src/testsuite/tests/{ => compile}/errors.svtest (97%) rename src/testsuite/tests/{header-errors.sieve => compile/errors/header.sieve} (100%) diff --git a/src/lib-sieve/sieve-error.c b/src/lib-sieve/sieve-error.c index 26161e645..44bb0cc40 100644 --- a/src/lib-sieve/sieve-error.c +++ b/src/lib-sieve/sieve-error.c @@ -43,7 +43,8 @@ void sieve_verror } if ( sieve_errors_more_allowed(ehandler) ) { - ehandler->verror(ehandler, location, fmt, args); + if ( ehandler->verror != NULL ) + ehandler->verror(ehandler, location, fmt, args); ehandler->errors++; } } @@ -60,8 +61,9 @@ void sieve_vwarning else sieve_sys_warning("%s: %s", location, t_strdup_vprintf(fmt, args)); } - - ehandler->vwarning(ehandler, location, fmt, args); + + if ( ehandler->vwarning != NULL ) + ehandler->vwarning(ehandler, location, fmt, args); ehandler->warnings++; } @@ -78,7 +80,7 @@ void sieve_vinfo sieve_sys_info("%s: %s", location, t_strdup_vprintf(fmt, args)); } - if ( ehandler->log_info ) + if ( ehandler->log_info && ehandler->vinfo != NULL ) ehandler->vinfo(ehandler, location, fmt, args); } diff --git a/src/lib-sieve/sieve-error.h b/src/lib-sieve/sieve-error.h index a39f6cc25..e3a02ac63 100644 --- a/src/lib-sieve/sieve-error.h +++ b/src/lib-sieve/sieve-error.h @@ -125,10 +125,15 @@ void sieve_error_handler_unref(struct sieve_error_handler **ehandler); * Error handlers */ +/* Write errors to stderr */ struct sieve_error_handler *sieve_stderr_ehandler_create (unsigned int max_errors); + +/* Write errors into a string buffer */ struct sieve_error_handler *sieve_strbuf_ehandler_create (string_t *strbuf, unsigned int max_errors); + +/* Write errors to a logfile */ struct sieve_error_handler *sieve_logfile_ehandler_create (const char *logfile, unsigned int max_errors); diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am index db2cf88cd..3fdd8a331 100644 --- a/src/testsuite/Makefile.am +++ b/src/testsuite/Makefile.am @@ -85,7 +85,8 @@ test_cases = \ tests/extensions/imapflags/basic.svtest \ tests/extensions/imapflags/rfc.svtest \ tests/compile/compile.svtest \ - tests/compile/compile-examples.svtest + tests/compile/compile-examples.svtest \ + tests/compile/errors.svtest $(test_cases): @$(TESTSUITE_BIN) $@ diff --git a/src/testsuite/tests/errors.svtest b/src/testsuite/tests/compile/errors.svtest similarity index 97% rename from src/testsuite/tests/errors.svtest rename to src/testsuite/tests/compile/errors.svtest index 107585bc2..ac841bd80 100644 --- a/src/testsuite/tests/errors.svtest +++ b/src/testsuite/tests/compile/errors.svtest @@ -4,7 +4,7 @@ require "relational"; require "comparator-i;ascii-numeric"; test "Header errors" { - if test_compile "header-errors.sieve" { + if test_compile "errors/header.sieve" { test_fail "compile should have failed."; } @@ -25,7 +25,7 @@ test "Header errors" { if not test_error :index 3 :matches "unknown tagged argument ':all' * header test *" { test_fail "error 3 is invalid"; - } + } if not test_error :index 4 :matches "*header test * string list * 2 (key list), * number *" { diff --git a/src/testsuite/tests/header-errors.sieve b/src/testsuite/tests/compile/errors/header.sieve similarity index 100% rename from src/testsuite/tests/header-errors.sieve rename to src/testsuite/tests/compile/errors/header.sieve diff --git a/src/testsuite/testsuite-common.c b/src/testsuite/testsuite-common.c index a17a84393..034829f55 100644 --- a/src/testsuite/testsuite-common.c +++ b/src/testsuite/testsuite-common.c @@ -8,6 +8,7 @@ #include "mail-raw.h" #include "namespaces.h" #include "sieve.h" +#include "sieve-error-private.h" #include "sieve-code.h" #include "sieve-commands.h" #include "sieve-extensions.h" @@ -32,6 +33,10 @@ static string_t *test_name; unsigned int test_index; unsigned int test_failures; +/* Tested script context */ + +static struct sieve_error_handler *test_script_ehandler; + /* * Testsuite message environment */ @@ -193,7 +198,7 @@ bool testsuite_generator_context_initialize(struct sieve_generator *gentr) * Test context */ -void testsuite_test_context_init(void) +static void testsuite_test_context_init(void) { test_name = str_new(default_pool, 128); test_index = 0; @@ -255,7 +260,7 @@ void testsuite_test_succeed(string_t *reason) str_truncate(test_name, 0); } -void testsuite_test_context_deinit(void) +static void testsuite_test_context_deinit(void) { //str_free(test_name); } @@ -271,3 +276,129 @@ int testsuite_testcase_result(void) return 0; } +/* + * Tested script environment + */ + +/* Special error handler */ + +struct _testsuite_script_message { + const char *location; + const char *message; +}; + +unsigned int _testsuite_script_error_index = 0; + +static pool_t _testsuite_scriptmsg_pool = NULL; +ARRAY_DEFINE(_testsuite_script_errors, struct _testsuite_script_message); + +static void _testsuite_script_verror +(struct sieve_error_handler *ehandler ATTR_UNUSED, const char *location, + const char *fmt, va_list args) +{ + pool_t pool = _testsuite_scriptmsg_pool; + struct _testsuite_script_message msg; + + msg.location = p_strdup(pool, location); + msg.message = p_strdup_vprintf(pool, fmt, args); + + array_append(&_testsuite_script_errors, &msg, 1); +} + +static struct sieve_error_handler *_testsuite_script_ehandler_create(void) +{ + pool_t pool; + struct sieve_error_handler *ehandler; + + /* Pool is not strictly necessary, but other handler types will need a pool, + * so this one will have one too. + */ + pool = pool_alloconly_create + ("testsuite_script_error_handler", sizeof(struct sieve_error_handler)); + ehandler = p_new(pool, struct sieve_error_handler, 1); + sieve_error_handler_init(ehandler, pool, 0); + + ehandler->verror = _testsuite_script_verror; + + return ehandler; +} + +static void testsuite_script_clear_messages(void) +{ + if ( _testsuite_scriptmsg_pool != NULL ) { + if ( array_count(&_testsuite_script_errors) == 0 ) + return; + pool_unref(&_testsuite_scriptmsg_pool); + } + + _testsuite_scriptmsg_pool = pool_alloconly_create + ("testsuite_script_messages", 8192); + + p_array_init(&_testsuite_script_errors, _testsuite_scriptmsg_pool, 128); +} + +void testsuite_script_get_error_init(void) +{ + _testsuite_script_error_index = 0; +} + +const char *testsuite_script_get_error_next(bool location) +{ + const struct _testsuite_script_message *msg; + + if ( _testsuite_script_error_index >= array_count(&_testsuite_script_errors) ) + return NULL; + + msg = array_idx(&_testsuite_script_errors, _testsuite_script_error_index++); + + if ( location ) + return msg->location; + + return msg->message; +} + +static void testsuite_script_init(void) +{ + testsuite_script_clear_messages(); + + test_script_ehandler = _testsuite_script_ehandler_create(); + sieve_error_handler_accept_infolog(test_script_ehandler, TRUE); +} + +bool testsuite_script_compile(const char *script_path) +{ + struct sieve_binary *sbin; + + testsuite_script_clear_messages(); + + if ( (sbin = sieve_compile(script_path, test_script_ehandler)) == NULL ) + return FALSE; + + sieve_close(&sbin); + return TRUE; +} + +static void testsuite_script_deinit(void) +{ + sieve_error_handler_unref(&test_script_ehandler); + + pool_unref(&_testsuite_scriptmsg_pool); + //str_free(test_script_error_buf); +} + +/* + * Main testsuite init/deinit + */ + +void testsuite_init(void) +{ + testsuite_test_context_init(); + testsuite_script_init(); +} + +void testsuite_deinit(void) +{ + testsuite_script_deinit(); + testsuite_test_context_deinit(); +} + diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h index 9568a0ba1..5385b26c8 100644 --- a/src/testsuite/testsuite-common.h +++ b/src/testsuite/testsuite-common.h @@ -64,13 +64,23 @@ enum testsuite_operand_code { /* Test context */ -void testsuite_test_context_init(void); void testsuite_test_start(string_t *name); void testsuite_test_fail(string_t *reason); void testsuite_test_succeed(string_t *reason); -void testsuite_test_context_deinit(void); void testsuite_testcase_fail(const char *reason); int testsuite_testcase_result(void); +/* Tested script environment */ + +bool testsuite_script_compile(const char *script_path); + +void testsuite_script_get_error_init(void); +const char *testsuite_script_get_error_next(bool location); + +/* Testsuite init/deinit */ + +void testsuite_init(void); +void testsuite_deinit(void); + #endif /* __TESTSUITE_COMMON_H */ diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c index d4e7a75d2..99f9fd9a6 100644 --- a/src/testsuite/testsuite.c +++ b/src/testsuite/testsuite.c @@ -43,7 +43,7 @@ static void sig_die(int signo, void *context ATTR_UNUSED) exit(1); } -static void testsuite_init(void) +static void testsuite_bin_init(void) { lib_init(); ioloop = io_loop_create(); @@ -59,12 +59,12 @@ static void testsuite_init(void) (void) sieve_extension_register(&testsuite_extension); - testsuite_test_context_init(); + testsuite_init(); } -static void testsuite_deinit(void) +static void testsuite_bin_deinit(void) { - testsuite_test_context_deinit(); + testsuite_deinit(); sieve_deinit(); @@ -182,7 +182,7 @@ int main(int argc, char **argv) struct sieve_script_env scriptenv; bool trace = FALSE; - testsuite_init(); + testsuite_bin_init(); /* Parse arguments */ scriptfile = dumpfile = NULL; @@ -258,7 +258,7 @@ int main(int argc, char **argv) testsuite_message_deinit(); namespaces_deinit(); - testsuite_deinit(); + testsuite_bin_deinit(); return testsuite_testcase_result(); } diff --git a/src/testsuite/tst-test-compile.c b/src/testsuite/tst-test-compile.c index 49a1e5266..79f5bd4a9 100644 --- a/src/testsuite/tst-test-compile.c +++ b/src/testsuite/tst-test-compile.c @@ -109,9 +109,6 @@ static int tst_test_compile_operation_execute (const struct sieve_operation *op ATTR_UNUSED, const struct sieve_runtime_env *renv, sieve_size_t *address) { - struct sieve_error_handler *ehandler; - struct sieve_binary *sbin; - string_t *script_name; const char *script_path; bool result = TRUE; @@ -139,17 +136,7 @@ static int tst_test_compile_operation_execute /* Attempt script compile */ - ehandler = sieve_stderr_ehandler_create(0); - sieve_error_handler_accept_infolog(ehandler, TRUE); - - if ( (sbin = sieve_compile(script_path, ehandler)) == NULL ) { - sieve_error_handler_unref(&ehandler); - result = FALSE; - } else { - sieve_close(&sbin); - } - - sieve_error_handler_unref(&ehandler); + result = testsuite_script_compile(script_path); /* Set result */ sieve_interpreter_set_test_result(renv->interp, result); diff --git a/src/testsuite/tst-test-error.c b/src/testsuite/tst-test-error.c index 77c4524f4..07a881180 100644 --- a/src/testsuite/tst-test-error.c +++ b/src/testsuite/tst-test-error.c @@ -214,7 +214,8 @@ static int tst_test_error_operation_execute struct sieve_match_context *mctx; struct sieve_coded_stringlist *key_list; bool matched; - int index = 0; + const char *error; + int cur_index = 0, index = 0; int ret; /* @@ -255,7 +256,37 @@ static int tst_test_error_operation_execute * Perform operation */ - matched = TRUE; + sieve_runtime_trace(renv, "TEST_ERROR test (index: %d)", index); + + testsuite_script_get_error_init(); + + /* Initialize match */ + mctx = sieve_match_begin(renv->interp, mtch, cmp, NULL, key_list); + + /* Iterate through all errors to match */ + error = NULL; + matched = FALSE; + cur_index = 1; + ret = 0; + while ( result && !matched && + (error=testsuite_script_get_error_next(FALSE)) != NULL ) { + + if ( index == 0 || index == cur_index ) { + if ( (ret=sieve_match_value(mctx, error, strlen(error))) < 0 ) { + result = FALSE; + break; + } + } + + matched = ret > 0; + cur_index++; + } + + /* Finish match */ + if ( (ret=sieve_match_end(mctx)) < 0 ) + result = FALSE; + else + matched = ( ret > 0 || matched ); /* Set test result for subsequent conditional jump */ if ( result ) { -- GitLab