diff options
Diffstat (limited to 'pigeonhole/src/testsuite/testsuite.c')
-rw-r--r-- | pigeonhole/src/testsuite/testsuite.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/pigeonhole/src/testsuite/testsuite.c b/pigeonhole/src/testsuite/testsuite.c new file mode 100644 index 0000000..2a6b82e --- /dev/null +++ b/pigeonhole/src/testsuite/testsuite.c @@ -0,0 +1,256 @@ +/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file + */ + +#include "lib.h" +#include "lib-signals.h" +#include "ioloop.h" +#include "env-util.h" +#include "ostream.h" +#include "hostpid.h" +#include "path-util.h" + +#include "sieve.h" +#include "sieve-extensions.h" +#include "sieve-script.h" +#include "sieve-binary.h" +#include "sieve-result.h" +#include "sieve-interpreter.h" + +#include "sieve-tool.h" + +#include "testsuite-common.h" +#include "testsuite-log.h" +#include "testsuite-settings.h" +#include "testsuite-result.h" +#include "testsuite-message.h" +#include "testsuite-smtp.h" +#include "testsuite-mailstore.h" + +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <pwd.h> +#include <sysexits.h> + +const struct sieve_script_env *testsuite_scriptenv; + +/* + * Configuration + */ + +#define DEFAULT_SENDMAIL_PATH "/usr/lib/sendmail" + +/* + * Testsuite execution + */ + +static void print_help(void) +{ + printf( +"Usage: testsuite [-D] [-E] [-F] [-d <dump-filename>]\n" +" [-t <trace-filename>] [-T <trace-option>]\n" +" [-P <plugin>] [-x <extensions>]\n" +" <scriptfile>\n" + ); +} + +static int +testsuite_run(struct sieve_binary *sbin, struct sieve_error_handler *ehandler) +{ + struct sieve_interpreter *interp; + struct sieve_result *result; + int ret = 0; + + /* Create the interpreter */ + interp = sieve_interpreter_create(sbin, NULL, &testsuite_execute_env, + ehandler); + if (interp == NULL) + return SIEVE_EXEC_BIN_CORRUPT; + + /* Run the interpreter */ + result = testsuite_result_get(); + ret = sieve_interpreter_run(interp, result); + + /* Free the interpreter */ + sieve_interpreter_free(&interp); + + return ret; +} + +int main(int argc, char **argv) +{ + struct sieve_instance *svinst; + const char *scriptfile, *dumpfile, *tracefile; + struct sieve_trace_config trace_config; + struct sieve_binary *sbin; + const char *sieve_dir, *cwd, *error; + bool log_stdout = FALSE, expect_failure = FALSE; + int ret, c; + + sieve_tool = sieve_tool_init("testsuite", &argc, &argv, + "d:t:T:EFDP:", TRUE); + + /* Parse arguments */ + dumpfile = tracefile = NULL; + i_zero(&trace_config); + trace_config.level = SIEVE_TRLVL_ACTIONS; + while ((c = sieve_tool_getopt(sieve_tool)) > 0) { + switch (c) { + case 'd': + /* destination address */ + dumpfile = optarg; + break; + case 't': + /* trace file */ + tracefile = optarg; + break; + case 'T': + sieve_tool_parse_trace_option(&trace_config, optarg); + break; + case 'E': + log_stdout = TRUE; + break; + case 'F': + expect_failure = TRUE; + break; + default: + print_help(); + i_fatal_status(EX_USAGE, "Unknown argument: %c", c); + break; + } + } + + if (optind < argc) { + scriptfile = t_strdup(argv[optind++]); + } else { + print_help(); + i_fatal_status(EX_USAGE, "Missing <scriptfile> argument"); + } + + if (optind != argc) { + print_help(); + i_fatal_status(EX_USAGE, "Unknown argument: %s", argv[optind]); + } + + // FIXME: very very ugly + master_service_parse_option( + master_service, 'o', + "postmaster_address=postmaster@example.com"); + + /* Initialize mail user */ + if (t_get_working_dir(&cwd, &error) < 0) + i_fatal("Failed to get working directory: %s", error); + sieve_tool_set_homedir(sieve_tool, cwd); + + /* Initialize settings environment */ + testsuite_settings_init(); + + /* Currently needed for include (FIXME) */ + sieve_dir = strrchr(scriptfile, '/'); + if (sieve_dir == NULL) + sieve_dir = "./"; + else + sieve_dir = t_strdup_until(scriptfile, sieve_dir+1); + + testsuite_setting_set("sieve_dir", + t_strconcat(sieve_dir, "included", NULL)); + testsuite_setting_set("sieve_global_dir", + t_strconcat(sieve_dir, "included-global", NULL)); + + /* Finish testsuite initialization */ + svinst = sieve_tool_init_finish(sieve_tool, FALSE, FALSE); + testsuite_init(svinst, sieve_dir, log_stdout); + + printf("Test case: %s:\n\n", scriptfile); + + /* Compile sieve script */ + if ((sbin = sieve_compile(svinst, scriptfile, NULL, + testsuite_log_main_ehandler, + 0, NULL)) != NULL) { + struct sieve_trace_log *trace_log = NULL; + struct sieve_exec_status exec_status; + struct sieve_script_env scriptenv; + + /* Dump script */ + sieve_tool_dump_binary_to(sbin, dumpfile, FALSE); + + if (tracefile != NULL) { + (void)sieve_trace_log_create( + svinst, (strcmp(tracefile, "-") == 0 ? + NULL : tracefile), &trace_log); + } + + testsuite_mailstore_init(); + testsuite_message_init(); + + if (sieve_script_env_init(&scriptenv, + testsuite_mailstore_get_user(), + &error) < 0) { + i_fatal("Failed to initialize script execution: %s", + error); + } + + i_zero(&exec_status); + + scriptenv.default_mailbox = "INBOX"; + scriptenv.smtp_start = testsuite_smtp_start; + scriptenv.smtp_add_rcpt = testsuite_smtp_add_rcpt; + scriptenv.smtp_send = testsuite_smtp_send; + scriptenv.smtp_abort = testsuite_smtp_abort; + scriptenv.smtp_finish = testsuite_smtp_finish; + scriptenv.trace_log = trace_log; + scriptenv.trace_config = trace_config; + scriptenv.exec_status = &exec_status; + + testsuite_scriptenv = &scriptenv; + + testsuite_result_init(); + + /* Run the test */ + ret = testsuite_run(sbin, testsuite_log_main_ehandler); + + switch (ret) { + case SIEVE_EXEC_OK: + break; + case SIEVE_EXEC_FAILURE: + case SIEVE_EXEC_KEEP_FAILED: + case SIEVE_EXEC_TEMP_FAILURE: + testsuite_testcase_fail( + "test script execution aborted due to error"); + break; + case SIEVE_EXEC_BIN_CORRUPT: + testsuite_testcase_fail( + "compiled test script binary is corrupt"); + break; + case SIEVE_EXEC_RESOURCE_LIMIT: + testsuite_testcase_fail( + "resource limit exceeded"); + break; + } + + sieve_close(&sbin); + + /* De-initialize message environment */ + testsuite_result_deinit(); + testsuite_message_deinit(); + testsuite_mailstore_deinit(); + + if (trace_log != NULL) + sieve_trace_log_free(&trace_log); + + testsuite_scriptenv = NULL; + } else { + testsuite_testcase_fail("failed to compile testcase script"); + } + + /* De-initialize testsuite */ + testsuite_deinit(); + testsuite_settings_deinit(); + + sieve_tool_deinit(&sieve_tool); + + if (!testsuite_testcase_result(expect_failure)) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} |