From e38b0bbd071d64a612b27c9318d50a3e45116608 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Fri, 25 Jul 2008 00:05:16 +0200 Subject: [PATCH] Testsuite: added test_compile command to test compilation of scripts. --- .hgignore | 1 - src/lib-sieve/sieve-script.c | 5 + src/lib-sieve/sieve-script.h | 1 + src/testsuite/Makefile.am | 12 +- src/testsuite/cmd-test-fail.c | 48 +++--- src/testsuite/cmd-test-set.c | 57 +++---- src/testsuite/cmd-test.c | 61 +++---- src/testsuite/ext-testsuite.c | 9 +- .../tests/compile/compile-examples.svtest | 51 ++++++ src/testsuite/tests/compile/compile.svtest | 16 ++ src/testsuite/tests/compile/redirect.sieve | 23 +++ src/testsuite/tests/compile/trivial.sieve | 3 + src/testsuite/testsuite-common.h | 4 +- src/testsuite/tst-test-compile.c | 152 ++++++++++++++++++ 14 files changed, 349 insertions(+), 94 deletions(-) create mode 100644 src/testsuite/tests/compile/compile-examples.svtest create mode 100644 src/testsuite/tests/compile/compile.svtest create mode 100644 src/testsuite/tests/compile/redirect.sieve create mode 100644 src/testsuite/tests/compile/trivial.sieve create mode 100644 src/testsuite/tst-test-compile.c diff --git a/.hgignore b/.hgignore index bdfb8af23..ead9aba20 100644 --- a/.hgignore +++ b/.hgignore @@ -1,7 +1,6 @@ syntax: glob aclocal.m4 autom4te.cache -compile config.cache config.guess dsieve-config.h diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c index 777163024..6c6761936 100644 --- a/src/lib-sieve/sieve-script.c +++ b/src/lib-sieve/sieve-script.c @@ -244,6 +244,11 @@ const char *sieve_script_path(struct sieve_script *script) return script->path; } +const char *sieve_script_dirpath(struct sieve_script *script) +{ + return script->dirpath; +} + const char *sieve_script_binpath(struct sieve_script *script) { return t_strconcat(script->dirpath, "/", script->basename, ".svbin", NULL); diff --git a/src/lib-sieve/sieve-script.h b/src/lib-sieve/sieve-script.h index 548e9bc61..8747f9bcb 100644 --- a/src/lib-sieve/sieve-script.h +++ b/src/lib-sieve/sieve-script.h @@ -34,5 +34,6 @@ const char *sieve_script_name(struct sieve_script *script); const char *sieve_script_filename(struct sieve_script *script); const char *sieve_script_path(struct sieve_script *script); const char *sieve_script_binpath(struct sieve_script *script); +const char *sieve_script_dirpath(struct sieve_script *script); #endif /* __SIEVE_SCRIPT_H */ diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am index 945b9b7b5..a25a30c02 100644 --- a/src/testsuite/Makefile.am +++ b/src/testsuite/Makefile.am @@ -37,17 +37,21 @@ ldadd = \ testsuite_LDADD = $(ldadd) testsuite_DEPENDENCIES = $(libs) -cmds = \ +commands = \ cmd-test.c \ cmd-test-fail.c \ cmd-test-set.c +tests = \ + tst-test-compile.c + testsuite_SOURCES = \ namespaces.c \ mail-raw.c \ testsuite-common.c \ testsuite-objects.c \ - $(cmds) \ + $(commands) \ + $(tests) \ ext-testsuite.c \ testsuite.c @@ -70,7 +74,9 @@ test_cases = \ tests/match-types/contains.svtest \ tests/match-types/matches.svtest \ tests/address-parts/subaddress.svtest \ - tests/extensions/variables/basic.svtest + tests/extensions/variables/basic.svtest \ + tests/compile/compile.svtest \ + tests/compile/compile-examples.svtest $(test_cases): @$(TESTSUITE_BIN) $@ diff --git a/src/testsuite/cmd-test-fail.c b/src/testsuite/cmd-test-fail.c index f3a9994cb..9106a5698 100644 --- a/src/testsuite/cmd-test-fail.c +++ b/src/testsuite/cmd-test-fail.c @@ -9,25 +9,18 @@ #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); +/* + * Test_fail command + * + * Syntax: + * test <reason: string> + */ static bool cmd_test_fail_validate (struct sieve_validator *validator, struct sieve_command_context *cmd); static bool cmd_test_fail_generate (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); -/* Test_fail command - * - * Syntax: - * test <reason: string> - */ const struct sieve_command cmd_test_fail = { "test_fail", SCT_COMMAND, @@ -38,7 +31,16 @@ const struct sieve_command cmd_test_fail = { NULL }; -/* Test operation */ +/* + * Test operation + */ + +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); const struct sieve_operation test_fail_operation = { "TEST_FAIL", @@ -48,7 +50,9 @@ const struct sieve_operation test_fail_operation = { cmd_test_fail_operation_execute }; -/* Validation */ +/* + * Validation + */ static bool cmd_test_fail_validate (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *cmd) @@ -63,7 +67,9 @@ static bool cmd_test_fail_validate return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE); } -/* Code generation */ +/* + * Code generation + */ static inline struct testsuite_generator_context * _get_generator_context(struct sieve_generator *gentr) @@ -99,7 +105,7 @@ static bool cmd_test_fail_operation_dump const struct sieve_dumptime_env *denv, sieve_size_t *address) { unsigned int pc; - int offset; + int offset; sieve_code_dumpf(denv, "TEST_FAIL:"); sieve_code_descend(denv); @@ -127,18 +133,12 @@ static bool cmd_test_fail_operation_execute { string_t *reason; - t_push(); - - if ( !sieve_opr_string_read(renv, address, &reason) ) { - t_pop(); + if ( !sieve_opr_string_read(renv, address, &reason) ) return FALSE; - } sieve_runtime_trace(renv, "TEST FAIL"); testsuite_test_fail(reason); - t_pop(); - return sieve_interpreter_program_jump(renv->interp, TRUE); } diff --git a/src/testsuite/cmd-test-set.c b/src/testsuite/cmd-test-set.c index d6ffcd22c..2381680fd 100644 --- a/src/testsuite/cmd-test-set.c +++ b/src/testsuite/cmd-test-set.c @@ -19,26 +19,18 @@ #include <stdio.h> -/* Forward declarations */ - -static bool cmd_test_set_operation_dump - (const struct sieve_operation *op, - const struct sieve_dumptime_env *denv, sieve_size_t *address); -static bool cmd_test_set_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); +/* + * Test_set command + * + * Syntax + * redirect <address: string> + */ static bool cmd_test_set_validate (struct sieve_validator *validator, struct sieve_command_context *cmd); static bool cmd_test_set_generate (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); -/* Test_set command - * - * Syntax - * redirect <address: string> - */ - const struct sieve_command cmd_test_set = { "test_set", SCT_COMMAND, @@ -49,7 +41,16 @@ const struct sieve_command cmd_test_set = { NULL }; -/* Test_set operation */ +/* + * Test_set operation + */ + +static bool cmd_test_set_operation_dump + (const struct sieve_operation *op, + const struct sieve_dumptime_env *denv, sieve_size_t *address); +static bool cmd_test_set_operation_execute + (const struct sieve_operation *op, + const struct sieve_runtime_env *renv, sieve_size_t *address); const struct sieve_operation test_set_operation = { "TEST_SET", @@ -93,15 +94,12 @@ static bool cmd_test_set_validate */ static bool cmd_test_set_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) { sieve_operation_emit_code(cgenv->sbin, &test_set_operation); /* Generate arguments */ - if ( !sieve_generate_arguments(cgenv, ctx, NULL) ) - return FALSE; - - return TRUE; + return sieve_generate_arguments(cgenv, ctx, NULL); } /* @@ -132,31 +130,20 @@ static bool cmd_test_set_operation_execute string_t *value; int member_id; - t_push(); - if ( (object=testsuite_object_read_member(renv->sbin, address, &member_id)) - == NULL ) { - t_pop(); + == NULL ) return FALSE; - } - if ( !sieve_opr_string_read(renv, address, &value) ) { - t_pop(); + if ( !sieve_opr_string_read(renv, address, &value) ) return FALSE; - } sieve_runtime_trace(renv, "TEST SET command (%s = \"%s\")", testsuite_object_member_name(object, member_id), str_c(value)); - if ( object->set_member == NULL ) { - t_pop(); + if ( object->set_member == NULL ) return FALSE; - } - object->set_member(member_id, value); - - t_pop(); - + object->set_member(member_id, value); return TRUE; } diff --git a/src/testsuite/cmd-test.c b/src/testsuite/cmd-test.c index 078c15354..b505f502a 100644 --- a/src/testsuite/cmd-test.c +++ b/src/testsuite/cmd-test.c @@ -9,28 +9,18 @@ #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_finish_operation_execute - (const struct sieve_operation *op, - const struct sieve_runtime_env *renv, sieve_size_t *address); +/* + * Test command + * + * Syntax: + * test <test-name: string> <block> + */ static bool cmd_test_validate (struct sieve_validator *validator, struct sieve_command_context *cmd); static bool cmd_test_generate (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); -/* Test command - * - * Syntax: - * test <test-name: string> <block> - */ const struct sieve_command cmd_test = { "test", SCT_COMMAND, @@ -41,8 +31,19 @@ const struct sieve_command cmd_test = { NULL }; +/* + * Test operations + */ + /* Test operation */ +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); + const struct sieve_operation test_operation = { "TEST", &testsuite_extension, @@ -51,6 +52,12 @@ const struct sieve_operation test_operation = { cmd_test_operation_execute }; +/* Test_finish operation */ + +static bool cmd_test_finish_operation_execute + (const struct sieve_operation *op, + const struct sieve_runtime_env *renv, sieve_size_t *address); + const struct sieve_operation test_finish_operation = { "TEST-FINISH", &testsuite_extension, @@ -59,7 +66,9 @@ const struct sieve_operation test_finish_operation = { cmd_test_finish_operation_execute }; -/* Validation */ +/* + * Validation + */ static bool cmd_test_validate (struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *cmd) @@ -82,7 +91,9 @@ static bool cmd_test_validate return sieve_validator_argument_activate(valdtr, cmd, arg, FALSE); } -/* Code generation */ +/* + * Code generation + */ static inline struct testsuite_generator_context * _get_generator_context(struct sieve_generator *gentr) @@ -142,19 +153,12 @@ static bool cmd_test_operation_execute { string_t *test_name; - t_push(); - - if ( !sieve_opr_string_read(renv, address, &test_name) ) { - t_pop(); + if ( !sieve_opr_string_read(renv, address, &test_name) ) return FALSE; - } - testsuite_test_start(test_name); - sieve_runtime_trace(renv, "TEST \"%s\"", str_c(test_name)); - - t_pop(); - + + testsuite_test_start(test_name); return TRUE; } @@ -166,7 +170,6 @@ static bool cmd_test_finish_operation_execute sieve_runtime_trace(renv, "TEST FINISHED"); testsuite_test_succeed(NULL); - return TRUE; } diff --git a/src/testsuite/ext-testsuite.c b/src/testsuite/ext-testsuite.c index 2d493b3de..7b4389e52 100644 --- a/src/testsuite/ext-testsuite.c +++ b/src/testsuite/ext-testsuite.c @@ -39,13 +39,18 @@ extern const struct sieve_command cmd_test; extern const struct sieve_command cmd_test_fail; extern const struct sieve_command cmd_test_set; +/* Tests */ + +extern const struct sieve_command tst_test_compile; + /* Operations */ const struct sieve_operation *testsuite_operations[] = { &test_operation, &test_finish_operation, &test_fail_operation, - &test_set_operation + &test_set_operation, + &test_compile_operation }; /* Operands */ @@ -84,6 +89,8 @@ 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, &tst_test_compile); return testsuite_validator_context_initialize(valdtr); } diff --git a/src/testsuite/tests/compile/compile-examples.svtest b/src/testsuite/tests/compile/compile-examples.svtest new file mode 100644 index 000000000..b1161e474 --- /dev/null +++ b/src/testsuite/tests/compile/compile-examples.svtest @@ -0,0 +1,51 @@ +require "vnd.dovecot.testsuite"; + +# Compile all example scripts + +test "Elvey example" { + if not test_compile "../../../../sieve/examples/elvey.sieve" { + test_fail "could not compile"; + } +} + +test "M. Johnson example" { + if not test_compile "../../../../sieve/examples/mjohnson.sieve" { + test_fail "could not compile"; + } +} + +test "RFC 3028 example" { + if not test_compile "../../../../sieve/examples/rfc3028.sieve" { + test_fail "could not compile"; + } +} + +test "Sieve examples" { + if not test_compile "../../../../sieve/examples/sieve_examples.sieve" { + test_fail "could not compile"; + } +} + +test "Vivil example" { + if not test_compile "../../../../sieve/examples/vivil.sieve" { + test_fail "could not compile"; + } +} + +test "Jerry example" { + if not test_compile "../../../../sieve/examples/jerry.sieve" { + test_fail "could not compile"; + } +} + +test "M. Klose example" { + if not test_compile "../../../../sieve/examples/mklose.sieve" { + test_fail "could not compile"; + } +} + +test "Sanjay example" { + if not test_compile "../../../../sieve/examples/sanjay.sieve" { + test_fail "could not compile"; + } +} diff --git a/src/testsuite/tests/compile/compile.svtest b/src/testsuite/tests/compile/compile.svtest new file mode 100644 index 000000000..5a54d6b55 --- /dev/null +++ b/src/testsuite/tests/compile/compile.svtest @@ -0,0 +1,16 @@ +require "vnd.dovecot.testsuite"; + +# Just test whether valid scripts will compile without problems + +test "Trivial" { + if not test_compile "trivial.sieve" { + test_fail "could not compile"; + } +} + +test "Redirect" { + if not test_compile "redirect.sieve" { + test_fail "could not compile"; + } +} + diff --git a/src/testsuite/tests/compile/redirect.sieve b/src/testsuite/tests/compile/redirect.sieve new file mode 100644 index 000000000..890855202 --- /dev/null +++ b/src/testsuite/tests/compile/redirect.sieve @@ -0,0 +1,23 @@ +# Test various white space occurences +redirect "stephan@rename-it.nl"; +redirect " stephan@rename-it.nl"; +redirect "stephan @rename-it.nl"; +redirect "stephan@ rename-it.nl"; +redirect "stephan@rename-it.nl "; +redirect " stephan @ rename-it.nl "; +redirect "Stephan Bosch<stephan@rename-it.nl>"; +redirect " Stephan Bosch<stephan@rename-it.nl>"; +redirect "Stephan Bosch <stephan@rename-it.nl>"; +redirect "Stephan Bosch< stephan@rename-it.nl>"; +redirect "Stephan Bosch<stephan @rename-it.nl>"; +redirect "Stephan Bosch<stephan@ rename-it.nl>"; +redirect "Stephan Bosch<stephan@rename-it.nl >"; +redirect "Stephan Bosch<stephan@rename-it.nl> "; +redirect " Stephan Bosch < stephan @ rename-it.nl > "; + +# Test address syntax +redirect "\"Stephan Bosch\"@rename-it.nl"; +redirect "Stephan.Bosch@rename-it.nl"; +redirect "Stephan.Bosch@ReNaMe-It.Nl"; +redirect "Stephan Bosch <stephan@rename-it.nl>"; + diff --git a/src/testsuite/tests/compile/trivial.sieve b/src/testsuite/tests/compile/trivial.sieve new file mode 100644 index 000000000..1bb76a9cc --- /dev/null +++ b/src/testsuite/tests/compile/trivial.sieve @@ -0,0 +1,3 @@ +keep; +discard; +stop; diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h index 761b4e556..54aea4f94 100644 --- a/src/testsuite/testsuite-common.h +++ b/src/testsuite/testsuite-common.h @@ -42,13 +42,15 @@ enum testsuite_operation_code { TESTSUITE_OPERATION_TEST, TESTSUITE_OPERATION_TEST_FINISH, TESTSUITE_OPERATION_TEST_FAIL, - TESTSUITE_OPERATION_TEST_SET + TESTSUITE_OPERATION_TEST_SET, + TESTSUITE_OPERATION_TEST_COMPILE }; extern const struct sieve_operation test_operation; extern const struct sieve_operation test_finish_operation; extern const struct sieve_operation test_fail_operation; extern const struct sieve_operation test_set_operation; +extern const struct sieve_operation test_compile_operation; /* Testsuite operands */ diff --git a/src/testsuite/tst-test-compile.c b/src/testsuite/tst-test-compile.c new file mode 100644 index 000000000..90f0a87e4 --- /dev/null +++ b/src/testsuite/tst-test-compile.c @@ -0,0 +1,152 @@ +#include "sieve-common.h" +#include "sieve-script.h" +#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 "sieve.h" + +#include "testsuite-common.h" + +/* + * Test_compile command + * + * Syntax: + * test <reason: string> + */ + +static bool tst_test_compile_validate + (struct sieve_validator *validator, struct sieve_command_context *cmd); +static bool tst_test_compile_generate + (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + +const struct sieve_command tst_test_compile = { + "test_compile", + SCT_TEST, + 1, 0, FALSE, FALSE, + NULL, NULL, + tst_test_compile_validate, + tst_test_compile_generate, + NULL +}; + +/* Test_compile operation */ + +static bool tst_test_compile_operation_dump + (const struct sieve_operation *op, + const struct sieve_dumptime_env *denv, sieve_size_t *address); +static bool tst_test_compile_operation_execute + (const struct sieve_operation *op, + const struct sieve_runtime_env *renv, sieve_size_t *address); + +const struct sieve_operation test_compile_operation = { + "TEST_COMPILE", + &testsuite_extension, + TESTSUITE_OPERATION_TEST_COMPILE, + tst_test_compile_operation_dump, + tst_test_compile_operation_execute +}; + +/* Validation */ + +static bool tst_test_compile_validate +(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_command_context *tst) +{ + struct sieve_ast_argument *arg = tst->first_positional; + + if ( !sieve_validate_positional_argument + (valdtr, tst, arg, "script", 1, SAAT_STRING) ) { + return FALSE; + } + + return sieve_validator_argument_activate(valdtr, tst, 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, &testsuite_extension); +} + +static bool tst_test_compile_generate +(const struct sieve_codegen_env *cgenv, struct sieve_command_context *tst) +{ + sieve_operation_emit_code(cgenv->sbin, &test_compile_operation); + + /* Generate arguments */ + return sieve_generate_arguments(cgenv, tst, NULL); +} + +/* + * Code dump + */ + +static bool tst_test_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_COMPILE:"); + sieve_code_descend(denv); + + if ( !sieve_opr_string_dump(denv, address) ) + return FALSE; + + return TRUE; +} + +/* + * Intepretation + */ + +static bool 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; + + if ( !sieve_opr_string_read(renv, address, &script_name) ) + return FALSE; + + sieve_runtime_trace(renv, "TEST COMPILE: %s", str_c(script_name)); + + script_path = sieve_script_dirpath(renv->script); + if ( script_path == NULL ) + return FALSE; + + script_path = t_strconcat(script_path, "/", str_c(script_name), NULL); + + /* 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); + + /* Set result */ + sieve_interpreter_set_test_result(renv->interp, result); + + return TRUE; +} + + + + -- GitLab