From 3285d7b9f820093473c72c6497e34291fa335191 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Fri, 2 Jan 2009 14:51:03 +0100 Subject: [PATCH] Testsuite: added multiscript tests and required support. --- Makefile.am | 3 +- src/lib-sieve/ext-reject.c | 4 +- src/lib-sieve/plugins/vacation/cmd-vacation.c | 2 +- src/testsuite/Makefile.am | 3 +- src/testsuite/cmd-test-result-print.c | 82 +++++++++++++ src/testsuite/ext-testsuite.c | 4 +- src/testsuite/testsuite-common.h | 3 + src/testsuite/testsuite-log.c | 2 +- src/testsuite/testsuite-result.c | 26 +++- src/testsuite/testsuite-result.h | 7 +- src/testsuite/tst-test-result-execute.c | 2 +- src/testsuite/tst-test-script-compile.c | 4 +- src/testsuite/tst-test-script-run.c | 114 +++++++++++++++++- tests/multiscript/basic.svtest | 91 ++++++++++++++ tests/multiscript/conflicts.svtest | 51 ++++++++ tests/multiscript/fileinto-inbox.sieve | 4 + tests/multiscript/notify.sieve | 3 + tests/multiscript/reject-1.sieve | 3 + tests/multiscript/reject-2.sieve | 3 + tests/multiscript/vacation.sieve | 3 + 20 files changed, 396 insertions(+), 18 deletions(-) create mode 100644 src/testsuite/cmd-test-result-print.c create mode 100644 tests/multiscript/basic.svtest create mode 100644 tests/multiscript/conflicts.svtest create mode 100644 tests/multiscript/fileinto-inbox.sieve create mode 100644 tests/multiscript/notify.sieve create mode 100644 tests/multiscript/reject-1.sieve create mode 100644 tests/multiscript/reject-2.sieve create mode 100644 tests/multiscript/vacation.sieve diff --git a/Makefile.am b/Makefile.am index f969e5fab..c9638a16a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -76,7 +76,8 @@ test_cases = \ tests/extensions/enotify/valid_notify_method.svtest \ tests/extensions/enotify/notify_method_capability.svtest \ tests/extensions/enotify/errors.svtest \ - tests/extensions/enotify/execute.svtest + tests/extensions/enotify/execute.svtest \ + tests/multiscript/basic.svtest if HAVE_DOVECOT_LIBS diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index 8f05591ab..ce8305b8a 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -271,7 +271,7 @@ int act_reject_check_conflict if ( (act_other->action->flags & SIEVE_ACTFLAG_TRIES_DELIVER) > 0 ) { if ( !act_other->executed ) { sieve_runtime_error(renv, act->location, - "reject action conflicts with earlier triggered action: " + "reject action conflicts with other action: " "the %s action (%s) tries to deliver the message", act_other->action->name, act_other->location); return -1; @@ -283,7 +283,7 @@ int act_reject_check_conflict if ( (act_other->action->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) { if ( !act_other->executed ) { sieve_runtime_error(renv, act->location, - "reject action conflicts with earlier triggered action: " + "reject action conflicts with other action: " "the %s action (%s) also sends a response to the sender", act_other->action->name, act_other->location); return -1; diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index 85e271a49..a1d23da55 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -704,7 +704,7 @@ int act_vacation_check_conflict if ( (act_other->action->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) { if ( !act_other->executed ) { sieve_runtime_error(renv, act->location, - "vacation action conflicts with earlier triggered action: " + "vacation action conflicts with other action: " "the %s action (%s) also sends a response back to the sender", act_other->action->name, act_other->location); return -1; diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am index 284efb282..dbb872765 100644 --- a/src/testsuite/Makefile.am +++ b/src/testsuite/Makefile.am @@ -36,7 +36,8 @@ testsuite_DEPENDENCIES = $(libs) commands = \ cmd-test.c \ cmd-test-fail.c \ - cmd-test-set.c + cmd-test-set.c \ + cmd-test-result-print.c tests = \ tst-test-script-compile.c \ diff --git a/src/testsuite/cmd-test-result-print.c b/src/testsuite/cmd-test-result-print.c new file mode 100644 index 000000000..c05a82db8 --- /dev/null +++ b/src/testsuite/cmd-test-result-print.c @@ -0,0 +1,82 @@ +/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file + */ + +#include "sieve-common.h" +#include "sieve-script.h" +#include "sieve-commands.h" +#include "sieve-validator.h" +#include "sieve-generator.h" +#include "sieve-interpreter.h" +#include "sieve-code.h" +#include "sieve-binary.h" +#include "sieve-dump.h" +#include "sieve.h" + +#include "testsuite-common.h" +#include "testsuite-result.h" + +/* + * Test_result_execute command + * + * Syntax: + * test_result_execute + */ + +static bool cmd_test_result_print_generate + (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + +const struct sieve_command cmd_test_result_print = { + "test_result_print", + SCT_COMMAND, + 0, 0, FALSE, FALSE, + NULL, NULL, NULL, + cmd_test_result_print_generate, + NULL +}; + +/* + * Operation + */ + +static int cmd_test_result_print_operation_execute + (const struct sieve_operation *op, + const struct sieve_runtime_env *renv, sieve_size_t *address); + +const struct sieve_operation test_result_print_operation = { + "TEST_RESULT_PRINT", + &testsuite_extension, + TESTSUITE_OPERATION_TEST_RESULT_PRINT, + NULL, + cmd_test_result_print_operation_execute +}; + +/* + * Code generation + */ + +static bool cmd_test_result_print_generate +(const struct sieve_codegen_env *cgenv, + struct sieve_command_context *tst ATTR_UNUSED) +{ + sieve_operation_emit_code(cgenv->sbin, &test_result_print_operation); + + return TRUE; +} + +/* + * Intepretation + */ + +static int cmd_test_result_print_operation_execute +(const struct sieve_operation *op ATTR_UNUSED, + const struct sieve_runtime_env *renv, + sieve_size_t *address ATTR_UNUSED) +{ + testsuite_result_print(renv); + + return SIEVE_EXEC_OK; +} + + + + diff --git a/src/testsuite/ext-testsuite.c b/src/testsuite/ext-testsuite.c index 47b5f2140..ea4006aa1 100644 --- a/src/testsuite/ext-testsuite.c +++ b/src/testsuite/ext-testsuite.c @@ -60,7 +60,8 @@ const struct sieve_operation *testsuite_operations[] = { &test_script_run_operation, &test_error_operation, &test_result_operation, - &test_result_execute_operation + &test_result_execute_operation, + &test_result_print_operation }; /* @@ -106,6 +107,7 @@ static bool ext_testsuite_validator_load(struct sieve_validator *valdtr) sieve_validator_register_command(valdtr, &cmd_test); sieve_validator_register_command(valdtr, &cmd_test_fail); sieve_validator_register_command(valdtr, &cmd_test_set); + sieve_validator_register_command(valdtr, &cmd_test_result_print); sieve_validator_register_command(valdtr, &tst_test_script_compile); sieve_validator_register_command(valdtr, &tst_test_script_run); diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h index 0ee51adbd..2c5beb0df 100644 --- a/src/testsuite/testsuite-common.h +++ b/src/testsuite/testsuite-common.h @@ -55,6 +55,7 @@ bool testsuite_generator_context_initialize(struct sieve_generator *gentr); extern const struct sieve_command cmd_test; extern const struct sieve_command cmd_test_fail; extern const struct sieve_command cmd_test_set; +extern const struct sieve_command cmd_test_result_print; /* * Tests @@ -80,6 +81,7 @@ enum testsuite_operation_code { TESTSUITE_OPERATION_TEST_ERROR, TESTSUITE_OPERATION_TEST_RESULT, TESTSUITE_OPERATION_TEST_RESULT_EXECUTE, + TESTSUITE_OPERATION_TEST_RESULT_PRINT, }; extern const struct sieve_operation test_operation; @@ -91,6 +93,7 @@ extern const struct sieve_operation test_script_run_operation; extern const struct sieve_operation test_error_operation; extern const struct sieve_operation test_result_operation; extern const struct sieve_operation test_result_execute_operation; +extern const struct sieve_operation test_result_print_operation; /* * Operands diff --git a/src/testsuite/testsuite-log.c b/src/testsuite/testsuite-log.c index 92c9b4a81..e36e6e63a 100644 --- a/src/testsuite/testsuite-log.c +++ b/src/testsuite/testsuite-log.c @@ -17,7 +17,7 @@ struct _testsuite_log_message { const char *message; }; -bool _testsuite_log_stdout = TRUE; +bool _testsuite_log_stdout = FALSE; unsigned int _testsuite_log_error_index = 0; diff --git a/src/testsuite/testsuite-result.c b/src/testsuite/testsuite-result.c index b9873b5eb..5fb8a433d 100644 --- a/src/testsuite/testsuite-result.c +++ b/src/testsuite/testsuite-result.c @@ -1,6 +1,9 @@ /* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file */ +#include "lib.h" +#include "ostream.h" + #include "sieve-common.h" #include "sieve-error.h" #include "sieve-actions.h" @@ -15,7 +18,7 @@ static struct sieve_result *_testsuite_result; void testsuite_result_init(void) { - _testsuite_result = NULL; + _testsuite_result = sieve_result_create(testsuite_log_ehandler); } void testsuite_result_deinit(void) @@ -25,13 +28,18 @@ void testsuite_result_deinit(void) } } -void testsuite_result_assign(struct sieve_result *result) +void testsuite_result_reset(void) { if ( _testsuite_result != NULL ) { sieve_result_unref(&_testsuite_result); } - _testsuite_result = result; + _testsuite_result = sieve_result_create(testsuite_log_ehandler);; +} + +struct sieve_result *testsuite_result_get(void) +{ + return _testsuite_result; } struct sieve_result_iterate_context *testsuite_result_iterate_init(void) @@ -75,4 +83,16 @@ bool testsuite_result_execute(const struct sieve_runtime_env *renv) return ( ret > 0 ); } +void testsuite_result_print +(const struct sieve_runtime_env *renv ATTR_UNUSED) +{ + struct ostream *out; + + out = o_stream_create_fd(1, 0, FALSE); + + sieve_result_print(_testsuite_result, out); + + o_stream_destroy(&out); +} + diff --git a/src/testsuite/testsuite-result.h b/src/testsuite/testsuite-result.h index ab21d0f34..b9b146523 100644 --- a/src/testsuite/testsuite-result.h +++ b/src/testsuite/testsuite-result.h @@ -7,10 +7,15 @@ void testsuite_result_init(void); void testsuite_result_deinit(void); -void testsuite_result_assign(struct sieve_result *result); +void testsuite_result_reset(void); + +struct sieve_result *testsuite_result_get(void); struct sieve_result_iterate_context *testsuite_result_iterate_init(void); bool testsuite_result_execute(const struct sieve_runtime_env *renv); +void testsuite_result_print + (const struct sieve_runtime_env *renv ATTR_UNUSED); + #endif /* __TESTSUITE_RESULT_H */ diff --git a/src/testsuite/tst-test-result-execute.c b/src/testsuite/tst-test-result-execute.c index 1ccd9b238..bf28203cd 100644 --- a/src/testsuite/tst-test-result-execute.c +++ b/src/testsuite/tst-test-result-execute.c @@ -43,7 +43,7 @@ static int tst_test_result_execute_operation_execute const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation test_result_execute_operation = { - "test_result_execute", + "TEST_RESULT_EXECUTE", &testsuite_extension, TESTSUITE_OPERATION_TEST_RESULT_EXECUTE, NULL, diff --git a/src/testsuite/tst-test-script-compile.c b/src/testsuite/tst-test-script-compile.c index a2dc4e67f..8ce4fe7b0 100644 --- a/src/testsuite/tst-test-script-compile.c +++ b/src/testsuite/tst-test-script-compile.c @@ -48,7 +48,7 @@ static int tst_test_script_compile_operation_execute const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation test_script_compile_operation = { - "test_script_compile", + "TEST_SCRIPT_COMPILE", &testsuite_extension, TESTSUITE_OPERATION_TEST_SCRIPT_COMPILE, tst_test_script_compile_operation_dump, @@ -100,7 +100,7 @@ static bool tst_test_script_compile_operation_dump (const struct sieve_operation *op ATTR_UNUSED, const struct sieve_dumptime_env *denv, sieve_size_t *address) { - sieve_code_dumpf(denv, "test_script_compile:"); + sieve_code_dumpf(denv, "TEST_SCRIPT_COMPILE:"); sieve_code_descend(denv); if ( !sieve_opr_string_dump(denv, address, "script") ) diff --git a/src/testsuite/tst-test-script-run.c b/src/testsuite/tst-test-script-run.c index f132a419d..2ba17b855 100644 --- a/src/testsuite/tst-test-script-run.c +++ b/src/testsuite/tst-test-script-run.c @@ -13,6 +13,7 @@ #include "sieve.h" #include "testsuite-common.h" +#include "testsuite-result.h" /* * Test_script_run command @@ -21,6 +22,8 @@ * test_script_run */ +static bool tst_test_script_run_registered +(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); static bool tst_test_script_run_generate (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); @@ -28,7 +31,8 @@ const struct sieve_command tst_test_script_run = { "test_script_run", SCT_TEST, 0, 0, FALSE, FALSE, - NULL, NULL, NULL, + tst_test_script_run_registered, + NULL, NULL, tst_test_script_run_generate, NULL }; @@ -37,6 +41,9 @@ const struct sieve_command tst_test_script_run = { * Operation */ +static bool tst_test_script_run_operation_dump + (const struct sieve_operation *op, + const struct sieve_dumptime_env *denv, sieve_size_t *address); static int tst_test_script_run_operation_execute (const struct sieve_operation *op, const struct sieve_runtime_env *renv, sieve_size_t *address); @@ -45,23 +52,89 @@ const struct sieve_operation test_script_run_operation = { "test_script_run", &testsuite_extension, TESTSUITE_OPERATION_TEST_SCRIPT_RUN, - NULL, + tst_test_script_run_operation_dump, tst_test_script_run_operation_execute }; +/* + * Tagged arguments + */ + +/* Codes for optional arguments */ + +enum cmd_vacation_optional { + OPT_END, + OPT_APPEND_RESULT +}; + +/* Tags */ + +static const struct sieve_argument append_result_tag = { + "append_result", + NULL, NULL, NULL, NULL, NULL +}; + +static bool tst_test_script_run_registered +(struct sieve_validator *validator, struct sieve_command_registration *cmd_reg) +{ + sieve_validator_register_tag + (validator, cmd_reg, &append_result_tag, OPT_APPEND_RESULT); + + return TRUE; +} + + /* * Code generation */ static bool tst_test_script_run_generate (const struct sieve_codegen_env *cgenv, - struct sieve_command_context *tst ATTR_UNUSED) + struct sieve_command_context *tst) { sieve_operation_emit_code(cgenv->sbin, &test_script_run_operation); + return sieve_generate_arguments(cgenv, tst, NULL); +} + +/* + * Code dump + */ + +static bool tst_test_script_run_operation_dump +(const struct sieve_operation *op ATTR_UNUSED, + const struct sieve_dumptime_env *denv, sieve_size_t *address) +{ + int opt_code = 1; + + sieve_code_dumpf(denv, "TEST_SCRIPT_RUN"); + sieve_code_descend(denv); + + /* Dump optional operands */ + if ( sieve_operand_optional_present(denv->sbin, address) ) { + while ( opt_code != 0 ) { + sieve_code_mark(denv); + + if ( !sieve_operand_optional_read(denv->sbin, address, &opt_code) ) + return FALSE; + + switch ( opt_code ) { + case 0: + break; + case OPT_APPEND_RESULT: + sieve_code_dumpf(denv, "append_result"); + break; + + default: + return FALSE; + } + } + } + return TRUE; } + /* * Intepretation */ @@ -71,15 +144,48 @@ static int tst_test_script_run_operation_execute const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED) { + bool append_result = FALSE; + int opt_code = 1; bool result = TRUE; + /* + * Read operands + */ + + /* Optional operands */ + if ( sieve_operand_optional_present(renv->sbin, address) ) { + while ( opt_code != 0 ) { + if ( !sieve_operand_optional_read(renv->sbin, address, &opt_code) ) { + sieve_runtime_trace_error(renv, "invalid optional operand"); + return SIEVE_EXEC_BIN_CORRUPT; + } + + switch ( opt_code ) { + case 0: + break; + case OPT_APPEND_RESULT: + append_result = TRUE; + break; + default: + sieve_runtime_trace_error(renv, + "unknown optional operand"); + return SIEVE_EXEC_BIN_CORRUPT; + } + } + } + /* * Perform operation */ + /* Reset result object */ + if ( !append_result ) + testsuite_result_reset(); + + /* Run script */ result = testsuite_script_run(renv); - /* Set result */ + /* Indicate test status */ sieve_interpreter_set_test_result(renv->interp, result); return SIEVE_EXEC_OK; diff --git a/tests/multiscript/basic.svtest b/tests/multiscript/basic.svtest new file mode 100644 index 000000000..54fb26b1c --- /dev/null +++ b/tests/multiscript/basic.svtest @@ -0,0 +1,91 @@ +require "vnd.dovecot.testsuite"; + +test_set "message" text: +From: stephan@rename-it.nl +Message-ID: <frop33333333333333333@frutsens.nl> +To: nico@vestingbar.nl +Subject: Frop. + +Friep. +. +; + +test "Append" { + if not allof ( + test_script_compile "fileinto-inbox.sieve", + test_script_run ){ + test_fail "failed to compile and run first script"; + } + + if not allof ( + test_script_compile "vacation.sieve", + test_script_run :append_result ) { + test_fail "failed to compile and run second script"; + } + + if not allof ( + test_script_compile "notify.sieve", + test_script_run :append_result ) { + test_fail "failed to compile and run third script"; + } + + if not test_result :index 1 "store" { + test_fail "first action is not 'store'"; + } + + if not test_result :index 2 "vacation" { + test_fail "second action is not 'vacation'"; + } + + if not test_result :index 3 "notify" { + test_fail "third action is not 'notify'"; + } + + if not test_result_execute { + test_fail "result execute failed"; + } +} + +test "Sequential Execute" { + if not allof ( + test_script_compile "fileinto-inbox.sieve", + test_script_run ) { + test_fail "failed to compile and run first script"; + } + + if not test_result_execute { + test_fail "result execute failed after first script"; + } + + if not allof ( + test_script_compile "vacation.sieve", + test_script_run :append_result ) { + test_fail "failed to compile and run second script"; + } + + if not test_result_execute { + test_fail "result execute failed after second script"; + } + + if not allof ( + test_script_compile "notify.sieve", + test_script_run :append_result ) { + test_fail "failed to compile and run third script"; + } + + if not test_result_execute { + test_fail "result execute failed after third script"; + } + + if not test_result :index 1 "store" { + test_fail "first action is not 'store'"; + } + + if not test_result :index 2 "vacation" { + test_fail "second action is not 'vacation'"; + } + + if not test_result :index 3 "notify" { + test_fail "third action is not 'notify'"; + } +} diff --git a/tests/multiscript/conflicts.svtest b/tests/multiscript/conflicts.svtest new file mode 100644 index 000000000..be9a58edc --- /dev/null +++ b/tests/multiscript/conflicts.svtest @@ -0,0 +1,51 @@ +require "vnd.dovecot.testsuite"; + +test_set "message" text: +From: stephan@rename-it.nl +Message-ID: <frop33333333333333333@frutsens.nl> +To: nico@vestingbar.nl +Subject: Frop. + +Friep. +. +; + +test "Graceful Conflicts" { + if not allof ( + test_script_compile "fileinto-inbox.sieve", + test_script_run ){ + test_fail "failed to compile and run first script"; + } + + if not test_result_execute { + test_fail "result execute failed after first script"; + } + + if not allof ( + test_script_compile "reject-1.sieve", + test_script_run :append_result ) { + test_fail "failed to compile and run second script"; + } + + if not test_result_execute { + test_fail "result execute failed after second script"; + } + + if not allof ( + test_script_compile "reject-2.sieve", + test_script_run :append_result ) { + test_fail "failed to compile and run third script"; + } + + if not test_result_execute { + test_fail "result execute failed after third script"; + } + + if not test_result :index 1 "store" { + test_fail "first action is not 'store'"; + } + + if test_result :index 2 "reject" { + test_fail "reject action not discarded"; + } +} diff --git a/tests/multiscript/fileinto-inbox.sieve b/tests/multiscript/fileinto-inbox.sieve new file mode 100644 index 000000000..b5da850e7 --- /dev/null +++ b/tests/multiscript/fileinto-inbox.sieve @@ -0,0 +1,4 @@ +require "fileinto"; + +fileinto "INBOX"; + diff --git a/tests/multiscript/notify.sieve b/tests/multiscript/notify.sieve new file mode 100644 index 000000000..9e5507bc7 --- /dev/null +++ b/tests/multiscript/notify.sieve @@ -0,0 +1,3 @@ +require "enotify"; + +notify "mailto:stephan@rename-it.nl"; diff --git a/tests/multiscript/reject-1.sieve b/tests/multiscript/reject-1.sieve new file mode 100644 index 000000000..06744f60a --- /dev/null +++ b/tests/multiscript/reject-1.sieve @@ -0,0 +1,3 @@ +require "reject"; + +reject "Message is not wanted."; diff --git a/tests/multiscript/reject-2.sieve b/tests/multiscript/reject-2.sieve new file mode 100644 index 000000000..96b75642f --- /dev/null +++ b/tests/multiscript/reject-2.sieve @@ -0,0 +1,3 @@ +require "reject"; + +reject "Will not accept this nonsense."; diff --git a/tests/multiscript/vacation.sieve b/tests/multiscript/vacation.sieve new file mode 100644 index 000000000..d735da5bf --- /dev/null +++ b/tests/multiscript/vacation.sieve @@ -0,0 +1,3 @@ +require "vacation"; + +vacation "I am not home"; -- GitLab