From 7e5c021184c271ad1fdf8aee113ccf5564797f22 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Thu, 29 May 2008 10:10:49 +0200 Subject: [PATCH] Testsuite: added test_fail command. --- src/lib-sieve/sieve-generator.c | 15 ++- src/lib-sieve/sieve-generator.h | 6 +- src/testsuite/Makefile.am | 1 + src/testsuite/cmd-test-fail.c | 147 ++++++++++++++++++++++++++++ src/testsuite/cmd-test.c | 24 +++-- src/testsuite/ext-testsuite.c | 38 ++++--- src/testsuite/tests/testsuite.sieve | 6 +- src/testsuite/testsuite-common.c | 21 +++- src/testsuite/testsuite-common.h | 13 +++ 9 files changed, 239 insertions(+), 32 deletions(-) create mode 100644 src/testsuite/cmd-test-fail.c diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c index d71a6995b..e6dde59ba 100644 --- a/src/lib-sieve/sieve-generator.c +++ b/src/lib-sieve/sieve-generator.c @@ -12,11 +12,16 @@ #include "sieve-generator.h" /* Jump list */ -void sieve_jumplist_init - (struct sieve_jumplist *jlist, pool_t pool, struct sieve_binary *sbin) +struct sieve_jumplist *sieve_jumplist_create + (pool_t pool, struct sieve_binary *sbin) { + struct sieve_jumplist *jlist; + + jlist = p_new(pool, struct sieve_jumplist, 1); jlist->binary = sbin; p_array_init(&jlist->jumps, pool, 4); + + return jlist; } void sieve_jumplist_init_temp @@ -26,6 +31,12 @@ void sieve_jumplist_init_temp t_array_init(&jlist->jumps, 4); } +void sieve_jumplist_reset + (struct sieve_jumplist *jlist) +{ + array_clear(&jlist->jumps); +} + void sieve_jumplist_add(struct sieve_jumplist *jlist, sieve_size_t jump) { array_append(&jlist->jumps, &jump, 1); diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h index aa1b46003..367672d6e 100644 --- a/src/lib-sieve/sieve-generator.h +++ b/src/lib-sieve/sieve-generator.h @@ -41,10 +41,12 @@ struct sieve_jumplist { ARRAY_DEFINE(jumps, sieve_size_t); }; +struct sieve_jumplist *sieve_jumplist_create + (pool_t pool, struct sieve_binary *sbin); void sieve_jumplist_init_temp (struct sieve_jumplist *jlist, struct sieve_binary *sbin); -void sieve_jumplist_init - (struct sieve_jumplist *jlist, pool_t pool, struct sieve_binary *sbin); +void sieve_jumplist_reset + (struct sieve_jumplist *jlist); void sieve_jumplist_add (struct sieve_jumplist *jlist, sieve_size_t jump); void sieve_jumplist_resolve(struct sieve_jumplist *jlist); diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am index 7d4382dd6..1afea9932 100644 --- a/src/testsuite/Makefile.am +++ b/src/testsuite/Makefile.am @@ -39,6 +39,7 @@ testsuite_DEPENDENCIES = $(libs) cmds = \ cmd-test.c \ + cmd-test-fail.c \ cmd-test-set.c testsuite_SOURCES = \ diff --git a/src/testsuite/cmd-test-fail.c b/src/testsuite/cmd-test-fail.c new file mode 100644 index 000000000..13a775356 --- /dev/null +++ b/src/testsuite/cmd-test-fail.c @@ -0,0 +1,147 @@ +#include "sieve-commands.h" +#include "sieve-commands-private.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 "testsuite-common.h" + +/* Predeclarations */ + +static bool cmd_test_fail_operation_dump + (const struct sieve_operation *op, + const struct sieve_dumptime_env *denv, sieve_size_t *address); +static bool cmd_test_fail_operation_execute + (const struct sieve_operation *op, + const struct sieve_runtime_env *renv, sieve_size_t *address); + +static bool cmd_test_fail_validate + (struct sieve_validator *validator, struct sieve_command_context *cmd); +static bool cmd_test_fail_generate + (struct sieve_generator *generator, struct sieve_command_context *ctx); + +/* Test_fail command + * + * Syntax: + * test <reason: string> + */ +const struct sieve_command cmd_test_fail = { + "test_fail", + SCT_COMMAND, + 1, 0, FALSE, FALSE, + NULL, NULL, + cmd_test_fail_validate, + cmd_test_fail_generate, + NULL +}; + +/* Test operation */ + +const struct sieve_operation test_fail_operation = { + "TEST_FAIL", + &testsuite_extension, + TESTSUITE_OPERATION_TEST_FAIL, + cmd_test_fail_operation_dump, + cmd_test_fail_operation_execute +}; + +/* Validation */ + +static bool cmd_test_fail_validate +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *cmd) +{ + struct sieve_ast_argument *arg = cmd->first_positional; + + if ( !sieve_validate_positional_argument + (valdtr, cmd, arg, "reason", 1, SAAT_STRING) ) { + return FALSE; + } + + return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE); +} + +/* Code generation */ + +static inline struct testsuite_generator_context * + _get_generator_context(struct sieve_generator *gentr) +{ + return (struct testsuite_generator_context *) + sieve_generator_extension_get_context(gentr, ext_testsuite_my_id); +} + +static bool cmd_test_fail_generate + (struct sieve_generator *gentr, struct sieve_command_context *ctx) +{ + struct sieve_binary *sbin = sieve_generator_get_binary(gentr); + struct testsuite_generator_context *genctx = + _get_generator_context(gentr); + + sieve_generator_emit_operation_ext(gentr, &test_fail_operation, + ext_testsuite_my_id); + + /* Generate arguments */ + if ( !sieve_generate_arguments(gentr, ctx, NULL) ) + return FALSE; + + sieve_jumplist_add(genctx->exit_jumps, sieve_binary_emit_offset(sbin, 0)); + + return TRUE; +} + +/* + * Code dump + */ + +static bool cmd_test_fail_operation_dump +(const struct sieve_operation *op ATTR_UNUSED, + const struct sieve_dumptime_env *denv, sieve_size_t *address) +{ + unsigned int pc; + int offset; + + sieve_code_dumpf(denv, "TEST_FAIL:"); + sieve_code_descend(denv); + + if ( !sieve_opr_string_dump(denv, address) ) + return FALSE; + + sieve_code_mark(denv); + pc = *address; + if ( sieve_binary_read_offset(denv->sbin, address, &offset) ) + sieve_code_dumpf(denv, "OFFSET: %d [%08x]", offset, pc + offset); + else + return FALSE; + + return TRUE; +} + +/* + * Intepretation + */ + +static bool cmd_test_fail_operation_execute +(const struct sieve_operation *op ATTR_UNUSED, + const struct sieve_runtime_env *renv, sieve_size_t *address) +{ + string_t *reason; + + t_push(); + + if ( !sieve_opr_string_read(renv, address, &reason) ) { + t_pop(); + return FALSE; + } + + printf("TEST FAILED: %s\n", str_c(reason)); + + t_pop(); + + return sieve_interpreter_program_jump(renv->interp, TRUE); +} + + + + diff --git a/src/testsuite/cmd-test.c b/src/testsuite/cmd-test.c index c1f796d53..5772abb83 100644 --- a/src/testsuite/cmd-test.c +++ b/src/testsuite/cmd-test.c @@ -72,27 +72,35 @@ static bool cmd_test_validate /* Code generation */ +static inline struct testsuite_generator_context * + _get_generator_context(struct sieve_generator *gentr) +{ + return (struct testsuite_generator_context *) + sieve_generator_extension_get_context(gentr, ext_testsuite_my_id); +} + static bool cmd_test_generate - (struct sieve_generator *generator, struct sieve_command_context *ctx) + (struct sieve_generator *gentr, struct sieve_command_context *ctx) { - struct sieve_binary *sbin = sieve_generator_get_binary(generator); - struct sieve_jumplist jmplist; + struct sieve_binary *sbin = sieve_generator_get_binary(gentr); + struct testsuite_generator_context *genctx = + _get_generator_context(gentr); - sieve_generator_emit_operation_ext(generator, &test_operation, + sieve_generator_emit_operation_ext(gentr, &test_operation, ext_testsuite_my_id); /* Generate arguments */ - if ( !sieve_generate_arguments(generator, ctx, NULL) ) + if ( !sieve_generate_arguments(gentr, ctx, NULL) ) return FALSE; /* Prepare jumplist */ - sieve_jumplist_init_temp(&jmplist, sbin); + sieve_jumplist_reset(genctx->exit_jumps); /* Test body */ - sieve_generate_block(generator, ctx->ast_node); + sieve_generate_block(gentr, ctx->ast_node); /* Resolve exit jumps to this point */ - sieve_jumplist_resolve(&jmplist); + sieve_jumplist_resolve(genctx->exit_jumps); return TRUE; } diff --git a/src/testsuite/ext-testsuite.c b/src/testsuite/ext-testsuite.c index c787d280e..514755cf8 100644 --- a/src/testsuite/ext-testsuite.c +++ b/src/testsuite/ext-testsuite.c @@ -29,26 +29,25 @@ /* Forward declarations */ static bool ext_testsuite_load(int ext_id); -static bool ext_testsuite_validator_load(struct sieve_validator *validator); +static bool ext_testsuite_validator_load(struct sieve_validator *valdtr); +static bool ext_testsuite_generator_load(struct sieve_generator *gentr); static bool ext_testsuite_binary_load(struct sieve_binary *sbin); /* Commands */ extern const struct sieve_command cmd_test; +extern const struct sieve_command cmd_test_fail; extern const struct sieve_command cmd_test_set; +/* Operations */ + +const struct sieve_operation *testsuite_operations[] = + { &test_operation, &test_fail_operation, &test_set_operation }; + /* Operands */ const struct sieve_operand *testsuite_operands[] = { &testsuite_object_operand }; - -/* Operations */ - -extern const struct sieve_operation test_operation; -extern const struct sieve_operation test_set_operation; - -const struct sieve_operation *testsuite_operations[] = - { &test_operation, &test_set_operation }; /* Extension definitions */ @@ -57,8 +56,9 @@ int ext_testsuite_my_id; const struct sieve_extension testsuite_extension = { "vnd.dovecot.testsuite", ext_testsuite_load, - ext_testsuite_validator_load, - NULL, NULL, + ext_testsuite_validator_load, + ext_testsuite_generator_load, + NULL, ext_testsuite_binary_load, NULL, SIEVE_EXT_DEFINE_OPERATIONS(testsuite_operations), @@ -74,12 +74,20 @@ static bool ext_testsuite_load(int ext_id) /* Load extension into validator */ -static bool ext_testsuite_validator_load(struct sieve_validator *validator) +static bool ext_testsuite_validator_load(struct sieve_validator *valdtr) { - sieve_validator_register_command(validator, &cmd_test); - sieve_validator_register_command(validator, &cmd_test_set); + sieve_validator_register_command(valdtr, &cmd_test); + sieve_validator_register_command(valdtr, &cmd_test_fail); + sieve_validator_register_command(valdtr, &cmd_test_set); - return testsuite_validator_context_initialize(validator); + return testsuite_validator_context_initialize(valdtr); +} + +/* Load extension into generator */ + +static bool ext_testsuite_generator_load(struct sieve_generator *gentr) +{ + return testsuite_generator_context_initialize(gentr); } /* Load extension into binary */ diff --git a/src/testsuite/tests/testsuite.sieve b/src/testsuite/tests/testsuite.sieve index 4c076ba26..05a4e13ad 100644 --- a/src/testsuite/tests/testsuite.sieve +++ b/src/testsuite/tests/testsuite.sieve @@ -12,8 +12,7 @@ Frop! test_set "envelope.from" "stephan@rename-it.nl"; if not header :contains "from" "rename-it.nl" { - discard; - stop; + test_fail "Message data not set properly."; } test_set "message" text: @@ -27,8 +26,7 @@ Friep! test_set "envelope.from" "stephan@rename-it.nl"; if not header :is "from" "nico@vestingbar.nl" { - discard; - stop; + test_fail "Message data not set properly."; } keep; diff --git a/src/testsuite/testsuite-common.c b/src/testsuite/testsuite-common.c index b03846b65..ae5ced7ec 100644 --- a/src/testsuite/testsuite-common.c +++ b/src/testsuite/testsuite-common.c @@ -127,7 +127,7 @@ bool testsuite_validator_context_initialize(struct sieve_validator *valdtr) struct testsuite_validator_context *ctx = p_new(pool, struct testsuite_validator_context, 1); - /* Setup comparator registry */ + /* Setup object registry */ ctx->object_registrations = hash_create (pool, pool, 0, str_hash, (hash_cmp_callback_t *) strcmp); @@ -137,3 +137,22 @@ bool testsuite_validator_context_initialize(struct sieve_validator *valdtr) return TRUE; } + +/* + * Generator context + */ + +bool testsuite_generator_context_initialize(struct sieve_generator *gentr) +{ + pool_t pool = sieve_validator_pool(gentr); + struct sieve_binary *sbin = sieve_generator_get_binary(gentr); + struct testsuite_generator_context *ctx = + p_new(pool, struct testsuite_generator_context, 1); + + /* Setup exit jumplist */ + ctx->exit_jumps = sieve_jumplist_create(pool, sbin); + + sieve_generator_extension_set_context(gentr, ext_testsuite_my_id, ctx); + + return TRUE; +} diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h index c866dd849..b5bb806e3 100644 --- a/src/testsuite/testsuite-common.h +++ b/src/testsuite/testsuite-common.h @@ -26,13 +26,26 @@ struct testsuite_validator_context { bool testsuite_validator_context_initialize(struct sieve_validator *valdtr); +/* Testsuite generator context */ + +struct testsuite_generator_context { + struct sieve_jumplist *exit_jumps; +}; + +bool testsuite_generator_context_initialize(struct sieve_generator *gentr); + /* Testsuite operations */ enum testsuite_operation_code { TESTSUITE_OPERATION_TEST, + TESTSUITE_OPERATION_TEST_FAIL, TESTSUITE_OPERATION_TEST_SET }; +extern const struct sieve_operation test_operation; +extern const struct sieve_operation test_fail_operation; +extern const struct sieve_operation test_set_operation; + /* Testsuite operands */ extern const struct sieve_operand testsuite_object_operand; -- GitLab