From bfbd7d0146141dc61279f5afbe1104bf9dbd5f50 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Sun, 18 Jan 2009 17:32:15 +0100
Subject: [PATCH] Testsuite: added storage of outgoing SMTP messages.

---
 src/testsuite/Makefile.am           |   4 +-
 src/testsuite/testsuite-common.c    |  46 ++++++++++++
 src/testsuite/testsuite-common.h    |  13 ++--
 src/testsuite/testsuite-message.c   |   3 +-
 src/testsuite/testsuite-smtp.c      | 105 ++++++++++++++++++++++++++++
 src/testsuite/testsuite-smtp.h      |  19 +++++
 src/testsuite/testsuite.c           |  29 ++++----
 src/testsuite/tst-test-script-run.c |   1 +
 8 files changed, 196 insertions(+), 24 deletions(-)
 create mode 100644 src/testsuite/testsuite-smtp.c
 create mode 100644 src/testsuite/testsuite-smtp.h

diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am
index 37d042e5c..3ac60626f 100644
--- a/src/testsuite/Makefile.am
+++ b/src/testsuite/Makefile.am
@@ -55,6 +55,7 @@ testsuite_SOURCES = \
 	testsuite-log.c \
 	testsuite-script.c \
 	testsuite-result.c \
+	testsuite-smtp.c \
 	$(commands) \
 	$(tests) \
 	ext-testsuite.c \
@@ -68,5 +69,6 @@ noinst_HEADERS = \
 	testsuite-message.h \
 	testsuite-log.h \
 	testsuite-script.h \
-	testsuite-result.h
+	testsuite-result.h \
+	testsuite-smtp.h
 
diff --git a/src/testsuite/testsuite-common.c b/src/testsuite/testsuite-common.c
index b0541d930..824a07960 100644
--- a/src/testsuite/testsuite-common.c
+++ b/src/testsuite/testsuite-common.c
@@ -8,6 +8,7 @@
 #include "hash.h"
 #include "mail-storage.h"
 #include "env-util.h"
+#include "unlink-directory.h"
 
 #include "mail-raw.h"
 
@@ -27,6 +28,15 @@
 #include "testsuite-log.h"
 #include "testsuite-script.h"
 #include "testsuite-result.h"
+#include "testsuite-smtp.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 /*
  * Global data
@@ -165,6 +175,36 @@ int testsuite_testcase_result(void)
 	return 0;
 }
 
+/*
+ * Testsuite temporary directory
+ */
+
+static char *testsuite_tmp_dir;
+
+static void testsuite_tmp_dir_init(void)
+{
+	testsuite_tmp_dir = i_strdup_printf
+		("/tmp/dsieve-testsuite.%s.%s", dec2str(time(NULL)), dec2str(getpid()));
+
+	if ( mkdir(testsuite_tmp_dir, 0700) < 0 ) {
+		i_fatal("failed to create temporary directory '%s': %m.", 
+			testsuite_tmp_dir);		
+	}
+}
+
+static void testsuite_tmp_dir_deinit(void)
+{
+	if ( unlink_directory(testsuite_tmp_dir, TRUE) < 0 )
+		i_warning("failed to remove temporary directory '%s': %m.",
+			testsuite_tmp_dir);
+
+	i_free(testsuite_tmp_dir);
+}
+
+const char *testsuite_tmp_dir_get(void)
+{
+	return testsuite_tmp_dir;
+}
 
 /*
  * Main testsuite init/deinit
@@ -174,14 +214,20 @@ void testsuite_init(void)
 {
 	testsuite_test_context_init();
 	testsuite_log_init();
+	testsuite_tmp_dir_init();
+	
 	testsuite_script_init();
 	testsuite_result_init();
+	testsuite_smtp_init();
 }
 
 void testsuite_deinit(void)
 {
+	testsuite_smtp_deinit();
 	testsuite_result_deinit();
 	testsuite_script_deinit();
+	
+	testsuite_tmp_dir_deinit();
 	testsuite_log_deinit();
 	testsuite_test_context_deinit();
 }
diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h
index 37c158cdb..258e14663 100644
--- a/src/testsuite/testsuite-common.h
+++ b/src/testsuite/testsuite-common.h
@@ -104,16 +104,11 @@ void testsuite_test_succeed(string_t *reason);
 void testsuite_testcase_fail(const char *reason);
 int testsuite_testcase_result(void);
 
-/* 
- * Tested script environment 
+/*
+ * Testsuite temporary directory
  */
-
-bool testsuite_script_compile(const char *script_path);
-bool testsuite_script_run(const struct sieve_runtime_env *renv);
-
-void testsuite_script_clear_messages(void);
-void testsuite_script_get_error_init(void);
-const char *testsuite_script_get_error_next(bool location);
+ 
+const char *testsuite_tmp_dir_get(void);
 
 /* 
  * Testsuite init/deinit 
diff --git a/src/testsuite/testsuite-message.c b/src/testsuite/testsuite-message.c
index e7cdacebe..493421a09 100644
--- a/src/testsuite/testsuite-message.c
+++ b/src/testsuite/testsuite-message.c
@@ -130,4 +130,5 @@ void testsuite_envelope_set_auth_user(const char *value)
 	str_truncate(envelope_auth, 0);
 	str_append(envelope_auth, value);
 	testsuite_msgdata.auth_user = str_c(envelope_auth);
-}
+} 
+ 
diff --git a/src/testsuite/testsuite-smtp.c b/src/testsuite/testsuite-smtp.c
new file mode 100644
index 000000000..7b3f091dc
--- /dev/null
+++ b/src/testsuite/testsuite-smtp.c
@@ -0,0 +1,105 @@
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
+ */
+
+#include "lib.h"
+#include "array.h"
+#include "unlink-directory.h"
+
+#include "sieve-common.h" 
+ 
+#include "testsuite-common.h"
+#include "testsuite-smtp.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+struct testsuite_smtp_message {
+	const char *envelope_from;
+	const char *envelope_to;
+	const char *file;
+};
+
+static pool_t testsuite_smtp_pool;
+static const char *testsuite_smtp_tmp;
+static ARRAY_DEFINE(testsuite_smtp_messages, struct testsuite_smtp_message);
+
+/*
+ * Initialize
+ */
+
+void testsuite_smtp_init(void)
+{
+	pool_t pool;
+	
+	testsuite_smtp_pool = pool = pool_alloconly_create("testsuite_smtp", 8192);	
+	
+	testsuite_smtp_tmp = p_strconcat
+		(pool, testsuite_tmp_dir_get(), "/smtp", NULL);
+
+	if ( mkdir(testsuite_smtp_tmp, 0700) < 0 ) {
+		i_fatal("failed to create temporary directory '%s': %m.", 
+			testsuite_smtp_tmp);		
+	}
+	
+	p_array_init(&testsuite_smtp_messages, pool, 16);
+}
+
+void testsuite_smtp_deinit(void)
+{
+	if ( unlink_directory(testsuite_smtp_tmp, TRUE) < 0 )
+		i_warning("failed to remove temporary directory '%s': %m.",
+			testsuite_smtp_tmp);
+	
+	pool_unref(&testsuite_smtp_pool);		
+}
+
+void testsuite_smtp_reset(void)
+{
+	testsuite_smtp_deinit();
+	testsuite_smtp_init();
+}
+
+/*
+ * Simulated SMTP out
+ */
+ 
+struct testsuite_smtp {
+	const char *tmp_path;
+	FILE *mfile;
+};
+ 
+void *testsuite_smtp_open
+	(const char *destination, const char *return_path, FILE **file_r)
+{	
+	struct testsuite_smtp_message smtp_msg;
+	struct testsuite_smtp *smtp;
+	unsigned int smtp_count = array_count(&testsuite_smtp_messages);
+	
+	smtp_msg.file = p_strdup_printf(testsuite_smtp_pool, 
+		"%s/%d.eml", testsuite_smtp_tmp, smtp_count);
+	smtp_msg.envelope_from = p_strdup(testsuite_smtp_pool, return_path);
+	smtp_msg.envelope_to = p_strdup(testsuite_smtp_pool, destination);
+	 
+	array_append(&testsuite_smtp_messages, &smtp_msg, 1);
+	
+	smtp = t_new(struct testsuite_smtp, 1);
+	smtp->tmp_path = smtp_msg.file;
+	smtp->mfile = fopen(smtp->tmp_path, "w");
+
+	if ( smtp->mfile == NULL )
+		i_fatal("failed to open tmp file for SMTP simulation.");
+
+	*file_r = smtp->mfile;
+	
+	return (void *) smtp;	
+}
+
+bool testsuite_smtp_close(void *handle)
+{
+	struct testsuite_smtp *smtp = (struct testsuite_smtp *) handle;
+
+	fclose(smtp->mfile);
+	
+	return TRUE;
+}
+
diff --git a/src/testsuite/testsuite-smtp.h b/src/testsuite/testsuite-smtp.h
new file mode 100644
index 000000000..cc73a653f
--- /dev/null
+++ b/src/testsuite/testsuite-smtp.h
@@ -0,0 +1,19 @@
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
+ */
+ 
+#ifndef __TESTSUITE_SMTP_H
+#define __TESTSUITE_SMTP_H
+ 
+void testsuite_smtp_init(void);
+void testsuite_smtp_deinit(void);
+void testsuite_smtp_reset(void);
+
+/*
+ * Simulated SMTP out
+ */
+ 
+void *testsuite_smtp_open
+	(const char *destination, const char *return_path, FILE **file_r);
+bool testsuite_smtp_close(void *handle);
+
+#endif /* __TESTSUITE_SMTP_H */
diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c
index 06a31bebb..38dde8ab1 100644
--- a/src/testsuite/testsuite.c
+++ b/src/testsuite/testsuite.c
@@ -23,6 +23,7 @@
 #include "testsuite-common.h"
 #include "testsuite-result.h"
 #include "testsuite-message.h"
+#include "testsuite-smtp.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -72,28 +73,28 @@ static int testsuite_run
 (struct sieve_binary *sbin, const struct sieve_message_data *msgdata, 
 	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler)
 {
-        struct sieve_interpreter *interp;
+	struct sieve_interpreter *interp;
 	struct sieve_result *result;
-        int ret = 0;
+	int ret = 0;
 
-        /* Create the interpreter */
-        if ( (interp=sieve_interpreter_create(sbin, ehandler)) == NULL )
-                return SIEVE_EXEC_BIN_CORRUPT;
+	/* Create the interpreter */
+	if ( (interp=sieve_interpreter_create(sbin, ehandler)) == NULL )
+		return SIEVE_EXEC_BIN_CORRUPT;
 
-        /* Reset execution status */
-        if ( senv->exec_status != NULL )
-                memset(senv->exec_status, 0, sizeof(*senv->exec_status));
+	/* Reset execution status */
+	if ( senv->exec_status != NULL )
+		memset(senv->exec_status, 0, sizeof(*senv->exec_status));
 
-        /* Run the interpreter */
+	/* Run the interpreter */
 	result = testsuite_result_get();
 	sieve_result_ref(result);
-        ret = sieve_interpreter_run(interp, msgdata, senv, result);
+	ret = sieve_interpreter_run(interp, msgdata, senv, result);
 	sieve_result_unref(&result);
 
-        /* Free the interpreter */
-        sieve_interpreter_free(&interp);
+	/* Free the interpreter */
+	sieve_interpreter_free(&interp);
 
-        return ret;
+	return ret;
 }
 
 int main(int argc, char **argv) 
@@ -169,6 +170,8 @@ int main(int argc, char **argv)
 		memset(&scriptenv, 0, sizeof(scriptenv));
 		scriptenv.default_mailbox = "INBOX";
 		scriptenv.username = user;
+		scriptenv.smtp_open = testsuite_smtp_open;
+        scriptenv.smtp_close = testsuite_smtp_close;
 		scriptenv.trace_stream = ( trace ? o_stream_create_fd(1, 0, FALSE) : NULL );
 
 		/* Run the test */
diff --git a/src/testsuite/tst-test-script-run.c b/src/testsuite/tst-test-script-run.c
index 25a53e9d9..5011d63ab 100644
--- a/src/testsuite/tst-test-script-run.c
+++ b/src/testsuite/tst-test-script-run.c
@@ -13,6 +13,7 @@
 #include "sieve.h"
 
 #include "testsuite-common.h"
+#include "testsuite-script.h"
 #include "testsuite-result.h"
 
 /*
-- 
GitLab