From 67dc990f1ff6150162078e2b04a08ea9b460bc54 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Thu, 29 May 2008 01:57:55 +0200 Subject: [PATCH] Testsuite: added 'test' command to group sieve statements into a test. --- src/lib-sieve/cmd-if.c | 2 +- src/lib-sieve/sieve-generator.c | 10 +- src/lib-sieve/sieve-generator.h | 5 +- src/lib-sieve/tst-allof.c | 2 +- src/lib-sieve/tst-anyof.c | 2 +- src/testsuite/Makefile.am | 1 + src/testsuite/cmd-test-set.c | 25 ++--- src/testsuite/cmd-test.c | 141 ++++++++++++++++++++++++++++ src/testsuite/ext-testsuite.c | 7 +- src/testsuite/tests/testsuite.sieve | 33 +++---- src/testsuite/testsuite-common.h | 7 ++ src/testsuite/testsuite-objects.c | 28 ++++-- 12 files changed, 211 insertions(+), 52 deletions(-) create mode 100644 src/testsuite/cmd-test.c diff --git a/src/lib-sieve/cmd-if.c b/src/lib-sieve/cmd-if.c index 279f694bd..16c5b55ce 100644 --- a/src/lib-sieve/cmd-if.c +++ b/src/lib-sieve/cmd-if.c @@ -148,7 +148,7 @@ static bool cmd_if_generate struct sieve_jumplist jmplist; /* Prepare jumplist */ - sieve_jumplist_init(&jmplist, sbin); + sieve_jumplist_init_temp(&jmplist, sbin); /* Generate test condition */ test = sieve_ast_test_first(ctx->ast_node); diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c index 27d70874b..d71a6995b 100644 --- a/src/lib-sieve/sieve-generator.c +++ b/src/lib-sieve/sieve-generator.c @@ -12,7 +12,15 @@ #include "sieve-generator.h" /* Jump list */ -void sieve_jumplist_init(struct sieve_jumplist *jlist, struct sieve_binary *sbin) +void sieve_jumplist_init + (struct sieve_jumplist *jlist, pool_t pool, struct sieve_binary *sbin) +{ + jlist->binary = sbin; + p_array_init(&jlist->jumps, pool, 4); +} + +void sieve_jumplist_init_temp + (struct sieve_jumplist *jlist, struct sieve_binary *sbin) { jlist->binary = sbin; t_array_init(&jlist->jumps, 4); diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h index 979e118ad..aa1b46003 100644 --- a/src/lib-sieve/sieve-generator.h +++ b/src/lib-sieve/sieve-generator.h @@ -36,12 +36,15 @@ inline const void *sieve_generator_extension_get_context /* Jump list */ struct sieve_jumplist { + pool_t pool; struct sieve_binary *binary; ARRAY_DEFINE(jumps, sieve_size_t); }; -void sieve_jumplist_init +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_add (struct sieve_jumplist *jlist, sieve_size_t jump); void sieve_jumplist_resolve(struct sieve_jumplist *jlist); diff --git a/src/lib-sieve/tst-allof.c b/src/lib-sieve/tst-allof.c index 05f078dfa..1b1d50467 100644 --- a/src/lib-sieve/tst-allof.c +++ b/src/lib-sieve/tst-allof.c @@ -38,7 +38,7 @@ static bool tst_allof_generate if ( jump_true ) { /* Prepare jumplist */ - sieve_jumplist_init(&false_jumps, sbin); + sieve_jumplist_init_temp(&false_jumps, sbin); } test = sieve_ast_test_first(ctx->ast_node); diff --git a/src/lib-sieve/tst-anyof.c b/src/lib-sieve/tst-anyof.c index f9f6f25da..9ec7f50db 100644 --- a/src/lib-sieve/tst-anyof.c +++ b/src/lib-sieve/tst-anyof.c @@ -36,7 +36,7 @@ static bool tst_anyof_generate if ( !jump_true ) { /* Prepare jumplist */ - sieve_jumplist_init(&true_jumps, sbin); + sieve_jumplist_init_temp(&true_jumps, sbin); } test = sieve_ast_test_first(ctx->ast_node); diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am index 061606cc4..7d4382dd6 100644 --- a/src/testsuite/Makefile.am +++ b/src/testsuite/Makefile.am @@ -38,6 +38,7 @@ testsuite_LDADD = $(ldadd) testsuite_DEPENDENCIES = $(libs) cmds = \ + cmd-test.c \ cmd-test-set.c testsuite_SOURCES = \ diff --git a/src/testsuite/cmd-test-set.c b/src/testsuite/cmd-test-set.c index 7506177db..1db6aacb6 100644 --- a/src/testsuite/cmd-test-set.c +++ b/src/testsuite/cmd-test-set.c @@ -54,51 +54,38 @@ const struct sieve_command cmd_test_set = { const struct sieve_operation test_set_operation = { "TEST_SET", &testsuite_extension, - 0, + TESTSUITE_OPERATION_TEST_SET, cmd_test_set_operation_dump, cmd_test_set_operation_execute }; -/* Fields */ - -enum cmd_test_set_object { - CMD_SET_OBJ_MESSAGE, - CMD_SET_OBJ_ENVELOPE -}; - -enum cmd_test_set_envelope_field { - CMD_SET_ENVELOPE_SENDER, - CMD_SET_ENVELOPE_RECIPIENT, - CMD_SET_ENVELOPE_AUTH_USER -}; - /* * Validation */ static bool cmd_test_set_validate -(struct sieve_validator *validator, struct sieve_command_context *cmd) +(struct sieve_validator *valdtr, struct sieve_command_context *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; /* Check arguments */ if ( !sieve_validate_positional_argument - (validator, cmd, arg, "object", 1, SAAT_STRING) ) { + (valdtr, cmd, arg, "object", 1, SAAT_STRING) ) { return FALSE; } - if ( !testsuite_object_argument_activate(validator, arg, cmd) ) + if ( !testsuite_object_argument_activate(valdtr, arg, cmd) ) return FALSE; arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument - (validator, cmd, arg, "value", 2, SAAT_STRING) ) { + (valdtr, cmd, arg, "value", 2, SAAT_STRING) ) { return FALSE; } - return sieve_validator_argument_activate(validator, cmd, arg, FALSE); + return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE); } /* diff --git a/src/testsuite/cmd-test.c b/src/testsuite/cmd-test.c new file mode 100644 index 000000000..c1f796d53 --- /dev/null +++ b/src/testsuite/cmd-test.c @@ -0,0 +1,141 @@ +#include "sieve-commands.h" +#include "sieve-commands-private.h" +#include "sieve-validator.h" +#include "sieve-generator.h" +#include "sieve-code.h" +#include "sieve-binary.h" +#include "sieve-dump.h" + +#include "testsuite-common.h" + +/* Predeclarations */ + +static bool cmd_test_operation_dump + (const struct sieve_operation *op, + const struct sieve_dumptime_env *denv, sieve_size_t *address); +static bool cmd_test_operation_execute + (const struct sieve_operation *op, + const struct sieve_runtime_env *renv, sieve_size_t *address); + +static bool cmd_test_validate + (struct sieve_validator *validator, struct sieve_command_context *cmd); +static bool cmd_test_generate + (struct sieve_generator *generator, struct sieve_command_context *ctx); + +/* Test command + * + * Syntax: + * test <test-name: string> <block> + */ +const struct sieve_command cmd_test = { + "test", + SCT_COMMAND, + 1, 0, TRUE, TRUE, + NULL, NULL, + cmd_test_validate, + cmd_test_generate, + NULL +}; + +/* Test operation */ + +const struct sieve_operation test_operation = { + "TEST", + &testsuite_extension, + TESTSUITE_OPERATION_TEST, + cmd_test_operation_dump, + cmd_test_operation_execute +}; + +/* Validation */ + +static bool cmd_test_validate +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *cmd) +{ + struct sieve_ast_argument *arg = cmd->first_positional; + + /* Check valid command placement */ + if ( !sieve_command_is_toplevel(cmd) ) + { + sieve_command_validate_error(valdtr, cmd, + "tests cannot be nested: test command must be issued at top-level"); + return FALSE; + } + + if ( !sieve_validate_positional_argument + (valdtr, cmd, arg, "test-name", 1, SAAT_STRING) ) { + return FALSE; + } + + return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE); +} + +/* Code generation */ + +static bool cmd_test_generate + (struct sieve_generator *generator, struct sieve_command_context *ctx) +{ + struct sieve_binary *sbin = sieve_generator_get_binary(generator); + struct sieve_jumplist jmplist; + + sieve_generator_emit_operation_ext(generator, &test_operation, + ext_testsuite_my_id); + + /* Generate arguments */ + if ( !sieve_generate_arguments(generator, ctx, NULL) ) + return FALSE; + + /* Prepare jumplist */ + sieve_jumplist_init_temp(&jmplist, sbin); + + /* Test body */ + sieve_generate_block(generator, ctx->ast_node); + + /* Resolve exit jumps to this point */ + sieve_jumplist_resolve(&jmplist); + + return TRUE; +} + +/* + * Code dump + */ + +static bool cmd_test_operation_dump +(const struct sieve_operation *op ATTR_UNUSED, + const struct sieve_dumptime_env *denv, sieve_size_t *address) +{ + sieve_code_dumpf(denv, "TEST:"); + sieve_code_descend(denv); + + return + sieve_opr_string_dump(denv, address); +} + +/* + * Intepretation + */ + +static bool cmd_test_operation_execute +(const struct sieve_operation *op ATTR_UNUSED, + const struct sieve_runtime_env *renv, sieve_size_t *address) +{ + string_t *test_name; + + t_push(); + + if ( !sieve_opr_string_read(renv, address, &test_name) ) { + t_pop(); + return FALSE; + } + + printf("TEST: %s\n", str_c(test_name)); + + t_pop(); + + return TRUE; +} + + + + diff --git a/src/testsuite/ext-testsuite.c b/src/testsuite/ext-testsuite.c index 11100afe0..c787d280e 100644 --- a/src/testsuite/ext-testsuite.c +++ b/src/testsuite/ext-testsuite.c @@ -34,6 +34,7 @@ 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_set; /* Operands */ @@ -43,10 +44,11 @@ const struct sieve_operand *testsuite_operands[] = /* Operations */ +extern const struct sieve_operation test_operation; extern const struct sieve_operation test_set_operation; const struct sieve_operation *testsuite_operations[] = - { &test_set_operation }; + { &test_operation, &test_set_operation }; /* Extension definitions */ @@ -59,7 +61,7 @@ const struct sieve_extension testsuite_extension = { NULL, NULL, ext_testsuite_binary_load, NULL, - SIEVE_EXT_DEFINE_OPERATION(test_set_operation), + SIEVE_EXT_DEFINE_OPERATIONS(testsuite_operations), SIEVE_EXT_DEFINE_OPERAND(testsuite_object_operand) }; @@ -74,6 +76,7 @@ static bool ext_testsuite_load(int ext_id) static bool ext_testsuite_validator_load(struct sieve_validator *validator) { + sieve_validator_register_command(validator, &cmd_test); sieve_validator_register_command(validator, &cmd_test_set); return testsuite_validator_context_initialize(validator); diff --git a/src/testsuite/tests/testsuite.sieve b/src/testsuite/tests/testsuite.sieve index 6a260b4c6..4c076ba26 100644 --- a/src/testsuite/tests/testsuite.sieve +++ b/src/testsuite/tests/testsuite.sieve @@ -1,35 +1,36 @@ require "vnd.dovecot.testsuite"; -test_set "message" text: +test "Message environment test" { + test_set "message" text: From: sirius@rename-it.nl To: nico@vestingbar.nl Subject: Frop! Frop! . -; -test_set "envelope.from" "stephan@rename-it.nl"; + ; + test_set "envelope.from" "stephan@rename-it.nl"; -if not header :contains "from" "rename-it.nl" { - discard; - stop; -} + if not header :contains "from" "rename-it.nl" { + discard; + stop; + } -test_set "message" text: + test_set "message" text: From: nico@vestingbar.nl To: stephan@zuiphol.nl Subject: Friep! Friep! . -; -test_set "envelope.from" "stephan@rename-it.nl"; - -if not header :is "from" "nico@vestingbar.nl" { - discard; - stop; -} + ; + test_set "envelope.from" "stephan@rename-it.nl"; -keep; + if not header :is "from" "nico@vestingbar.nl" { + discard; + stop; + } + keep; +} diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h index d2e62e931..c866dd849 100644 --- a/src/testsuite/testsuite-common.h +++ b/src/testsuite/testsuite-common.h @@ -26,6 +26,13 @@ struct testsuite_validator_context { bool testsuite_validator_context_initialize(struct sieve_validator *valdtr); +/* Testsuite operations */ + +enum testsuite_operation_code { + TESTSUITE_OPERATION_TEST, + TESTSUITE_OPERATION_TEST_SET +}; + /* Testsuite operands */ extern const struct sieve_operand testsuite_object_operand; diff --git a/src/testsuite/testsuite-objects.c b/src/testsuite/testsuite-objects.c index d4dda7b91..31976acd9 100644 --- a/src/testsuite/testsuite-objects.c +++ b/src/testsuite/testsuite-objects.c @@ -308,7 +308,6 @@ static int tsto_envelope_get_member_id(const char *identifier); static const char *tsto_envelope_get_member_name(int id); static bool tsto_envelope_set_member(int id, string_t *value); - const struct testsuite_object message_testsuite_object = { "message", TESTSUITE_OBJECT_MESSAGE, @@ -328,6 +327,12 @@ const struct testsuite_object envelope_testsuite_object = { NULL }; +enum testsuite_object_envelope_field { + TESTSUITE_OBJECT_ENVELOPE_FROM, + TESTSUITE_OBJECT_ENVELOPE_TO, + TESTSUITE_OBJECT_ENVELOPE_AUTH_USER +}; + static bool tsto_message_set_member(int id, string_t *value) { if ( id != -1 ) return FALSE; @@ -340,11 +345,11 @@ static bool tsto_message_set_member(int id, string_t *value) static int tsto_envelope_get_member_id(const char *identifier) { if ( strcasecmp(identifier, "from") == 0 ) - return 0; + return TESTSUITE_OBJECT_ENVELOPE_FROM; if ( strcasecmp(identifier, "to") == 0 ) - return 1; + return TESTSUITE_OBJECT_ENVELOPE_TO; if ( strcasecmp(identifier, "auth") == 0 ) - return 2; + return TESTSUITE_OBJECT_ENVELOPE_AUTH_USER; return -1; } @@ -352,9 +357,12 @@ static int tsto_envelope_get_member_id(const char *identifier) static const char *tsto_envelope_get_member_name(int id) { switch ( id ) { - case 0: return "from"; - case 1: return "to"; - case 2: return "auth"; + case TESTSUITE_OBJECT_ENVELOPE_FROM: + return "from"; + case TESTSUITE_OBJECT_ENVELOPE_TO: + return "to"; + case TESTSUITE_OBJECT_ENVELOPE_AUTH_USER: + return "auth"; } return NULL; @@ -363,13 +371,13 @@ static const char *tsto_envelope_get_member_name(int id) static bool tsto_envelope_set_member(int id, string_t *value) { switch ( id ) { - case 0: + case TESTSUITE_OBJECT_ENVELOPE_FROM: testsuite_envelope_set_sender(str_c(value)); return TRUE; - case 1: + case TESTSUITE_OBJECT_ENVELOPE_TO: testsuite_envelope_set_recipient(str_c(value)); return TRUE; - case 2: + case TESTSUITE_OBJECT_ENVELOPE_AUTH_USER: testsuite_envelope_set_auth_user(str_c(value)); return TRUE; } -- GitLab