diff --git a/Makefile.am b/Makefile.am index e9b08aa86d392a7608b1b88033bc4c85687b084d..828d228ae2c58792df9dc02a3d5b75473661bb5d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,3 +12,5 @@ ChangeLog: .hg/dirstate hg log --style=changelog > ChangeLog endif +test: + $(MAKE) -C src/testsuite test diff --git a/TODO b/TODO index 73328665eae40f2f149c82f53d99bc17e8a795a7..c91b112294f3e66c3e1b4fe0b9aca1179b47dd7f 100644 --- a/TODO +++ b/TODO @@ -2,8 +2,6 @@ Next (in order of descending priority/precedence): * Make utility functions for handling sieve system errors. * Review sieve-address parsing implementation for past-end checks * Improve handling of old/corrupt binaries. -* Distinguish between 1.2 and 1.1 and start using mailbox_keyword_is_valid() - and new const str. * Test with dovecot --enable-debug for initial mempool allocation size * Full standards compliance review for the engine and all fully implemented @@ -13,32 +11,32 @@ Next (in order of descending priority/precedence): * Full security review. Enforce limits on number of created objects, script size, execution time, etc... * Make simple test suite for the base functionality +* Distinguish between 1.2 and 1.1 and start using mailbox_keyword_is_valid() + and new const str. * ## MAKE A FIRST RELEASE ## +* Add normalize() method to comparators to normalize the string before mathing + (for efficiency). +* Verify outgoing mail addresses at runtime when necessary (e.g. after variables + substitution) +* Implement dropping errors in the user's mailbox as a mail message. * Provide a solution for mail_get_headers_utf8 reparsing the whole message each time it is called (header and address test; Timo might provide solution from within Dovecot) * Build a sieve tool to filter an entire existing mailbox through a sieve script. * Build a server with test mail accounts that processes lots and lots of mail (e.g. spam, mailing lists etc.) -* Implement environment extension -* Implement notify extension with sole support for mailto mechanism. -* Implement date and index extensions * Make this implementation conform section 2.7.2 of RFC3028 (Comparisons Across Character Sets). -* Verify outgoing mail addresses at runtime when necessary (e.g. after variables - substitution) -* Implement dropping errors in the user's mailbox as a mail message. -* Add normalize() method to comparators to normalize the string before mathing - (for efficiency). * Implement comparator-i;unicode-casemap +* Implement environment extension +* Implement notify extension with sole support for mailto mechanism. +* Implement date and index extensions * Automate script tests; i.e. build a test suite. * Use lib/str-find.h for :contains and :matches match types * Resolve code duplication introduced for handling address-parts and match-types in different command implementations. -* Resolve code duplication amongst comparator, address-part and match-type - support as much as possible. * Add development documentation, i.e. comment on library functions and document the binary and byte-code format. * Make the engine and its extensions much more configurable. Possibly this can diff --git a/configure.in b/configure.in index 4c225fdaac1311ccbe422338eee7843299cf07c5..7a1e69012763a38916c6fd30fc0be1426226fe43 100644 --- a/configure.in +++ b/configure.in @@ -54,6 +54,9 @@ AC_SUBST(MODULE_LIBS) AC_SUBST(dovecot_incdir) AC_SUBST(moduledir) +TESTSUITE_BIN="\$(top_srcdir)/src/testsuite/testsuite" +AC_SUBST(TESTSUITE_BIN) + AC_CONFIG_FILES([ Makefile src/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index e3940c66446bf9e83d65392116a8520794ae7bc0..4edf1020e588c0f0043016b09196858c7e324396 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1 +1,2 @@ SUBDIRS = lib-sieve sieve-bin plugins testsuite + diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am index 1afea99323086a6b39426f129ffb318c64bd57e3..9c57d0d75cb17b5f781050c95eda65dbeeb4c586 100644 --- a/src/testsuite/Makefile.am +++ b/src/testsuite/Makefile.am @@ -56,3 +56,21 @@ noinst_HEADERS = \ testsuite-objects.h \ namespaces.h \ mail-raw.h + +# Testsuite tests + +EXTRA_DIST = tests + +test_cases = \ + tests/control-structures.svtest \ + tests/testsuite.svtest\ + tests/comparators/core.svtest \ + tests/match-types/contains.svtest \ + tests/match-types/matches.svtest \ + tests/extensions/variables/basic.svtest + +$(test_cases): + @$(TESTSUITE_BIN) $@ +.PHONY: $(test_cases) + +test: $(test_cases) diff --git a/src/testsuite/tests/testsuite.svtest b/src/testsuite/tests/testsuite.svtest index 05a4e13ad4d0b31aca3e25835a3ed254770e1d48..8b79dbd54d3714464a7fe2636fa35ebf4d8f918f 100644 --- a/src/testsuite/tests/testsuite.svtest +++ b/src/testsuite/tests/testsuite.svtest @@ -1,6 +1,6 @@ require "vnd.dovecot.testsuite"; -test "Message environment test" { +test "Message Environment" { test_set "message" text: From: sirius@rename-it.nl To: nico@vestingbar.nl @@ -12,7 +12,7 @@ Frop! test_set "envelope.from" "stephan@rename-it.nl"; if not header :contains "from" "rename-it.nl" { - test_fail "Message data not set properly."; + test_fail "message data not set properly."; } test_set "message" text: @@ -26,7 +26,7 @@ Friep! test_set "envelope.from" "stephan@rename-it.nl"; if not header :is "from" "nico@vestingbar.nl" { - test_fail "Message data not set properly."; + test_fail "message data not set properly."; } keep; diff --git a/src/testsuite/testsuite-common.c b/src/testsuite/testsuite-common.c index 5a613850a48a8b649263f8e84ff64e1aca8a9c58..cdfd1d49044bf8f69feb27b72267cc6541d552bc 100644 --- a/src/testsuite/testsuite-common.c +++ b/src/testsuite/testsuite-common.c @@ -30,6 +30,7 @@ struct sieve_message_data testsuite_msgdata; static string_t *test_name; unsigned int test_index; +unsigned int test_failures; /* * Testsuite message environment @@ -176,6 +177,7 @@ void testsuite_test_context_init(void) { test_name = str_new(default_pool, 128); test_index = 0; + test_failures = 0; } void testsuite_test_start(string_t *name) @@ -202,6 +204,8 @@ void testsuite_test_fail(string_t *reason) } str_truncate(test_name, 0); + + test_failures++; } void testsuite_test_succeed(string_t *reason) @@ -226,3 +230,14 @@ void testsuite_test_context_deinit(void) //str_free(test_name); } +int testsuite_testcase_result(void) +{ + if ( test_failures > 0 ) { + printf("\nFAIL: %d of %d tests failed.\n\n", test_failures, test_index); + return 1; + } + + printf("\nPASS: %d tests succeeded.\n\n", test_index); + return 0; +} + diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h index cdf9c3092a1730c63b999c7c9c6ae6faf51d42a9..761b4e5566c0cafe3c451417504ddc2932fffc77 100644 --- a/src/testsuite/testsuite-common.h +++ b/src/testsuite/testsuite-common.h @@ -66,4 +66,6 @@ void testsuite_test_fail(string_t *reason); void testsuite_test_succeed(string_t *reason); void testsuite_test_context_deinit(void); +int testsuite_testcase_result(void); + #endif /* __TESTSUITE_COMMON_H */ diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c index f72b8b6638b0c3d1e20f239ec8f310002b5d45b4..5d9adb16250b624115b8b9f2da30ca13a52f78d3 100644 --- a/src/testsuite/testsuite.c +++ b/src/testsuite/testsuite.c @@ -11,6 +11,8 @@ #include "namespaces.h" #include "sieve.h" #include "sieve-extensions.h" +#include "sieve-result.h" +#include "sieve-interpreter.h" #include "testsuite-common.h" @@ -134,6 +136,25 @@ static void print_help(void) ); } +static int testsuite_run +(struct sieve_binary *sbin, const struct sieve_script_env *scriptenv) +{ + struct sieve_error_handler *ehandler = sieve_stderr_ehandler_create(0); + struct sieve_result *sres = sieve_result_create(ehandler); + struct sieve_interpreter *interp = + sieve_interpreter_create(sbin, ehandler, NULL); + int ret = 0; + + ret = sieve_interpreter_run(interp, &testsuite_msgdata, scriptenv, &sres); + + sieve_interpreter_free(&interp); + sieve_result_unref(&sres); + + sieve_error_handler_unref(&ehandler); + + return ret; +} + int main(int argc, char **argv) { const char *scriptfile, *dumpfile; @@ -142,8 +163,6 @@ int main(int argc, char **argv) pool_t namespaces_pool; struct sieve_binary *sbin; struct sieve_script_env scriptenv; - struct sieve_error_handler *ehandler; - struct ostream *teststream; testsuite_init(); @@ -168,6 +187,8 @@ int main(int argc, char **argv) print_help(); i_fatal("Missing <scriptfile> argument"); } + + printf("Test case: %s:\n\n", scriptfile); /* Compile sieve script */ sbin = _compile_sieve_script(scriptfile); @@ -183,23 +204,15 @@ int main(int argc, char **argv) scriptenv.inbox = "INBOX"; scriptenv.username = user; - ehandler = sieve_stderr_ehandler_create(0); - - teststream = o_stream_create_fd(1, 0, FALSE); - /* Run the test */ - (void) sieve_test - (sbin, &testsuite_msgdata, &scriptenv, teststream, ehandler, NULL); - - o_stream_destroy(&teststream); + (void) testsuite_run(sbin, &scriptenv); sieve_close(&sbin); - sieve_error_handler_unref(&ehandler); testsuite_message_deinit(); namespaces_deinit(); testsuite_deinit(); - return 0; + return testsuite_testcase_result(); }