Skip to content
Snippets Groups Projects
Commit 3285d7b9 authored by Stephan Bosch's avatar Stephan Bosch
Browse files

Testsuite: added multiscript tests and required support.

parent 0d907631
No related branches found
No related tags found
No related merge requests found
Showing
with 396 additions and 18 deletions
......@@ -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
......
......@@ -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;
......
......@@ -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;
......
......@@ -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 \
......
/* 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;
}
......@@ -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);
......
......@@ -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
......
......@@ -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;
......
/* 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);
}
......@@ -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 */
......@@ -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,
......
......@@ -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") )
......
......@@ -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;
......
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'";
}
}
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";
}
}
require "fileinto";
fileinto "INBOX";
require "enotify";
notify "mailto:stephan@rename-it.nl";
require "reject";
reject "Message is not wanted.";
require "reject";
reject "Will not accept this nonsense.";
require "vacation";
vacation "I am not home";
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment

Consent

On this website, we use the web analytics service Matomo to analyze and review the use of our website. Through the collected statistics, we can improve our offerings and make them more appealing for you. Here, you can decide whether to allow us to process your data and set corresponding cookies for these purposes, in addition to technically necessary cookies. Further information on data protection—especially regarding "cookies" and "Matomo"—can be found in our privacy policy. You can withdraw your consent at any time.