diff options
Diffstat (limited to 'pigeonhole/src/testsuite/testsuite-script.c')
-rw-r--r-- | pigeonhole/src/testsuite/testsuite-script.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/pigeonhole/src/testsuite/testsuite-script.c b/pigeonhole/src/testsuite/testsuite-script.c new file mode 100644 index 0000000..b6edd9b --- /dev/null +++ b/pigeonhole/src/testsuite/testsuite-script.c @@ -0,0 +1,256 @@ +/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file + */ + +#include "lib.h" + +#include "sieve.h" +#include "sieve-common.h" +#include "sieve-script.h" +#include "sieve-binary.h" +#include "sieve-interpreter.h" +#include "sieve-runtime-trace.h" +#include "sieve-result.h" + +#include "testsuite-common.h" +#include "testsuite-settings.h" +#include "testsuite-log.h" +#include "testsuite-smtp.h" +#include "testsuite-result.h" + +#include "testsuite-script.h" + +/* + * Tested script environment + */ + +void testsuite_script_init(void) +{ +} + +void testsuite_script_deinit(void) +{ +} + +static struct sieve_binary * +_testsuite_script_compile(const struct sieve_runtime_env *renv, + const char *script) +{ + struct sieve_instance *svinst = testsuite_sieve_instance; + struct sieve_binary *sbin; + const char *script_path; + + sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, + "compile script `%s'", script); + + script_path = sieve_file_script_get_dirpath(renv->script); + if (script_path == NULL) + return NULL; + + script_path = t_strconcat(script_path, "/", script, NULL); + if ((sbin = sieve_compile(svinst, script_path, NULL, + testsuite_log_ehandler, 0, NULL)) == NULL) + return NULL; + + return sbin; +} + +bool testsuite_script_compile(const struct sieve_runtime_env *renv, + const char *script) +{ + struct testsuite_interpreter_context *ictx = + testsuite_interpreter_context_get(renv->interp, testsuite_ext); + struct sieve_binary *sbin; + + i_assert(ictx != NULL); + testsuite_log_clear_messages(); + + if ((sbin = _testsuite_script_compile(renv, script)) == NULL) + return FALSE; + + sieve_binary_unref(&ictx->compiled_script); + + ictx->compiled_script = sbin; + return TRUE; +} + +bool testsuite_script_is_subtest(const struct sieve_runtime_env *renv) +{ + struct testsuite_interpreter_context *ictx = + testsuite_interpreter_context_get(renv->interp, testsuite_ext); + + i_assert(ictx != NULL); + if (ictx->compiled_script == NULL) + return FALSE; + + return (sieve_binary_extension_get_index(ictx->compiled_script, + testsuite_ext) >= 0); +} + +bool testsuite_script_run(const struct sieve_runtime_env *renv) +{ + const struct sieve_execute_env *eenv = renv->exec_env; + const struct sieve_script_env *senv = eenv->scriptenv; + struct testsuite_interpreter_context *ictx = + testsuite_interpreter_context_get(renv->interp, testsuite_ext); + struct sieve_script_env scriptenv; + struct sieve_exec_status exec_status; + struct sieve_result *result; + struct sieve_interpreter *interp; + pool_t pool; + struct sieve_execute_env exec_env; + const char *error; + int ret; + + i_assert(ictx != NULL); + + if (ictx->compiled_script == NULL) { + sieve_runtime_error(renv, NULL, "testsuite: " + "trying to run script, but no script compiled yet"); + return FALSE; + } + + testsuite_log_clear_messages(); + + i_zero(&exec_status); + + /* Compose script execution environment */ + if (sieve_script_env_init(&scriptenv, senv->user, &error) < 0) { + sieve_runtime_error(renv, NULL, "testsuite: " + "failed to initialize script execution: %s", error); + return FALSE; + } + 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.duplicate_mark = NULL; + scriptenv.duplicate_check = NULL; + scriptenv.trace_log = eenv->scriptenv->trace_log; + scriptenv.trace_config = eenv->scriptenv->trace_config; + + result = testsuite_result_get(); + + pool = pool_alloconly_create("sieve execution", 4096); + sieve_execute_init(&exec_env, eenv->svinst, pool, eenv->msgdata, + &scriptenv, eenv->flags); + pool_unref(&pool); + + /* Execute the script */ + interp = sieve_interpreter_create(ictx->compiled_script, NULL, + &exec_env, testsuite_log_ehandler); + + if (interp == NULL) { + sieve_execute_deinit(&exec_env); + return FALSE; + } + + ret = sieve_interpreter_run(interp, result); + sieve_interpreter_free(&interp); + + sieve_execute_finish(&exec_env, ret); + sieve_execute_deinit(&exec_env); + + return (ret > 0 || + sieve_binary_extension_get_index(ictx->compiled_script, + testsuite_ext) >= 0); +} + +struct sieve_binary * +testsuite_script_get_binary(const struct sieve_runtime_env *renv) +{ + struct testsuite_interpreter_context *ictx = + testsuite_interpreter_context_get(renv->interp, testsuite_ext); + + i_assert(ictx != NULL); + return ictx->compiled_script; +} + +void testsuite_script_set_binary(const struct sieve_runtime_env *renv, + struct sieve_binary *sbin) +{ + struct testsuite_interpreter_context *ictx = + testsuite_interpreter_context_get(renv->interp, testsuite_ext); + + i_assert(ictx != NULL); + + sieve_binary_unref(&ictx->compiled_script); + + ictx->compiled_script = sbin; + sieve_binary_ref(sbin); +} + +/* + * Multiscript + */ + +bool testsuite_script_multiscript(const struct sieve_runtime_env *renv, + ARRAY_TYPE (const_string) *scriptfiles) +{ + struct sieve_instance *svinst = testsuite_sieve_instance; + const struct sieve_execute_env *eenv = renv->exec_env; + const struct sieve_script_env *senv = eenv->scriptenv; + struct sieve_script_env scriptenv; + struct sieve_exec_status exec_status; + struct sieve_multiscript *mscript; + const char *const *scripts; + const char *error; + unsigned int count, i; + bool more = TRUE; + bool result = TRUE; + + testsuite_log_clear_messages(); + + /* Compose script execution environment */ + if (sieve_script_env_init(&scriptenv, senv->user, &error) < 0) { + sieve_runtime_error(renv, NULL, + "testsuite: failed to initialize script execution: %s", + error); + return FALSE; + } + 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.duplicate_mark = NULL; + scriptenv.duplicate_check = NULL; + scriptenv.trace_log = eenv->scriptenv->trace_log; + scriptenv.trace_config = eenv->scriptenv->trace_config; + scriptenv.exec_status = &exec_status; + + /* Start execution */ + + mscript = sieve_multiscript_start_execute(svinst, eenv->msgdata, + &scriptenv); + + /* Execute scripts before main script */ + + scripts = array_get(scriptfiles, &count); + for (i = 0; i < count && more; i++) { + struct sieve_binary *sbin = NULL; + const char *script = scripts[i]; + + /* Open */ + if ((sbin = _testsuite_script_compile(renv, script)) == NULL) { + result = FALSE; + break; + } + + /* Execute */ + + sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, + "run script `%s'", script); + + more = sieve_multiscript_run(mscript, sbin, + testsuite_log_ehandler, + testsuite_log_ehandler, 0); + + sieve_close(&sbin); + } + + return (sieve_multiscript_finish(&mscript, testsuite_log_ehandler, + 0, SIEVE_EXEC_OK) > 0 && result); +} |