summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/testsuite/testsuite.c
diff options
context:
space:
mode:
Diffstat (limited to 'pigeonhole/src/testsuite/testsuite.c')
-rw-r--r--pigeonhole/src/testsuite/testsuite.c256
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;
+}