diff --git a/Makefile b/Makefile
index 1ba8e9a..ada48bb 100644
--- a/Makefile
+++ b/Makefile
@@ -46,9 +46,7 @@ $(TEST_DB):
# Run an e2e test of Advanced Content Filter.
#
daemontest:
- $(PYTHON) test/relay.py 2500
- PYTHONPATH=`pwd` $(PYTHON) -m lacre.daemon
- $(PYTHON) test/sendmail.py
+ $(PYTHON) test/daemon_test.py
# Before running the crontest goal we need to make sure that the
# database gets regenerated.
diff --git a/test/daemon_test.py b/test/daemon_test.py
index 45c8e8e..4c6f429 100644
--- a/test/daemon_test.py
+++ b/test/daemon_test.py
@@ -17,15 +17,99 @@
# along with gpg-mailgate source code. If not, see .
#
+import configparser
import logging
+import subprocess
+import os
+import time
+
+
+def _spawn(cmd):
+ env_dict = {
+ "PATH": os.getenv("PATH"),
+ "PYTHONPATH": os.getcwd(),
+ "GPG_MAILGATE_CONFIG": "test/gpg-mailgate-daemon-test.conf"
+ }
+ logging.debug(f"Spawning command: {cmd} with environment: {env_dict!r}")
+ return subprocess.Popen(cmd,
+ stdin=None,
+ stdout=subprocess.PIPE,
+ env=env_dict)
+
+
+def _interrupt(proc):
+ # proc.send_signal(signal.SIGINT)
+ proc.terminate()
+
+
+def _load(name):
+ logging.debug(f"Loading file {name}")
+ f = open(name, "r")
+ contents = f.read()
+ f.close()
+ return contents
+
+
+def _send(host, port, mail_from, mail_to, message):
+ logging.debug(f"Sending message to {host}:{port}")
+ _spawn([os.getenv("PYTHON") or "python",
+ "test/utils/sendmail.py",
+ "-f", mail_from,
+ "-t", mail_to,
+ "-m", message])
+
+
+def _load_test_config():
+ cp = configparser.ConfigParser()
+ cp.read("test/e2e.ini")
+ return cp
+
+
+def _report_result(message_file, expected, test_output):
+ status = None
+ if expected in test_output:
+ status = "Success"
+ else:
+ status = "Failure"
+
+ print(message_file.ljust(30), status)
+
+
+def _execute_case(config, case_name):
+ logging.info(f"Executing case {case_name}")
+ python = os.getenv("PYTHON", "python")
+
+ relay_mock = _spawn([python, "test/utils/relay.py", "2500"])
+ time.sleep(1) # Wait for the relay to start up.
+
+ _send("localhost", 10025, "dave@disposlab", "alice@disposlab", "test/msgin/clear2rsa.msg")
+
+ relay_mock.wait()
+ (test_out, _) = relay_mock.communicate()
+
+ test_out = test_out.decode('utf-8')
+ logging.debug(f"Read {len(test_out)} characters of output: '{test_out}'")
+
+ _report_result(config.get(case_name, "in"), config.get(case_name, "out"), test_out)
def _main():
+ conf = _load_test_config()
+
logging.basicConfig(filename="test/logs/daemon-test.log",
format="%(asctime)s %(pathname)s:%(lineno)d %(levelname)s [%(funcName)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
level=logging.DEBUG)
+
logging.info("Starting Lacre Daemon tests...")
+ python = os.getenv("PYTHON", "python")
+
+ server = _spawn([python, "-m", "lacre.daemon"])
+
+ for case_no in range(1, conf.getint("tests", "cases")):
+ _execute_case(conf, case_name=f"case-{case_no}")
+
+ _interrupt(server)
if __name__ == '__main__':
diff --git a/test/e2e_test.py b/test/e2e_test.py
index 7515f21..0cd044f 100644
--- a/test/e2e_test.py
+++ b/test/e2e_test.py
@@ -111,17 +111,17 @@ def _execute_e2e_test(case_name, config, config_path):
logging.debug(f"Spawning relay: {relay_cmd}")
relay_proc = subprocess.Popen(relay_cmd,
- stdin = None,
- stdout = subprocess.PIPE)
+ stdin=None,
+ stdout=subprocess.PIPE)
logging.debug(f"Spawning GPG-Lacre: {gpglacre_cmd}, stdin = {config.get(case_name, 'in')}")
# pass PATH because otherwise it would be dropped
gpglacre_proc = subprocess.run(gpglacre_cmd,
- input = _load_file(config.get(case_name, "in")),
- capture_output = True,
- env = {"GPG_MAILGATE_CONFIG": config_path,
- "PATH": os.getenv("PATH")})
+ input=_load_file(config.get(case_name, "in")),
+ capture_output=True,
+ env={"GPG_MAILGATE_CONFIG": config_path,
+ "PATH": os.getenv("PATH")})
# Let the relay process the data.
relay_proc.wait()
diff --git a/test/gpg-mailgate-daemon-test.conf b/test/gpg-mailgate-daemon-test.conf
new file mode 100644
index 0000000..0ba4a52
--- /dev/null
+++ b/test/gpg-mailgate-daemon-test.conf
@@ -0,0 +1,31 @@
+[logging]
+config = test/gpg-lacre-log.ini
+file = test/logs/gpg-mailgate.log
+format = %(asctime)s %(module)s[%(process)d]: %(message)s
+date_format = ISO
+
+[gpg]
+keyhome = test/keyhome
+
+[smime]
+cert_path = test/certs
+
+[database]
+enabled = yes
+url = sqlite:///test/lacre.db
+
+[relay]
+host = localhost
+port = 2500
+
+[daemon]
+host = localhost
+port = 10025
+
+[cron]
+send_email = no
+
+[enc_keymap]
+alice@disposlab = 1CD245308F0963D038E88357973CF4D9387C44D7
+bob@disposlab = 19CF4B47ECC9C47AFA84D4BD96F39FDA0E31BB67
+
diff --git a/test/utils/relay.py b/test/utils/relay.py
index 7e850dc..a250e5b 100644
--- a/test/utils/relay.py
+++ b/test/utils/relay.py
@@ -24,79 +24,79 @@ LAST_LINE = -3
def welcome(msg):
- return b"220 %b\r\n" % (msg)
+ return b"220 %b\r\n" % (msg)
def ok(msg = b"OK"):
- return b"250 %b\r\n" % (msg)
+ return b"250 %b\r\n" % (msg)
def bye():
- return b"251 Bye"
+ return b"251 Bye"
def provide_message():
- return b"354 Enter a message, ending it with a '.' on a line by itself\r\n"
+ return b"354 Enter a message, ending it with a '.' on a line by itself\r\n"
def receive_and_confirm(session):
- session.recv(BUFFER_SIZE)
- session.sendall(ok())
+ session.recv(BUFFER_SIZE)
+ session.sendall(ok())
def localhost_at(port):
- return ('127.0.0.1', port)
+ return ('127.0.0.1', port)
def serve(port):
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- s.bind(localhost_at(port))
- logging.info(f"Listening on localhost, port {port}")
- s.listen(1)
- logging.info("Listening...")
- except socket.error as e:
- print("Cannot connect", e)
- logging.error(f"Cannot connect {e}")
- sys.exit(EXIT_UNAVAILABLE)
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ s.bind(localhost_at(port))
+ logging.info(f"Listening on localhost, port {port}")
+ s.listen(1)
+ logging.info("Listening...")
+ except socket.error as e:
+ print("Cannot connect", e)
+ logging.error(f"Cannot connect {e}")
+ sys.exit(EXIT_UNAVAILABLE)
- logging.debug("About to accept a connection...")
- (conn, addr) = s.accept()
- logging.debug(f"Accepting connection from {conn}")
- conn.sendall(welcome(b"TEST SERVER"))
+ logging.debug("About to accept a connection...")
+ (conn, addr) = s.accept()
+ logging.debug(f"Accepting connection from {conn}")
+ conn.sendall(welcome(b"TEST SERVER"))
- receive_and_confirm(conn) # Ignore HELO/EHLO
- receive_and_confirm(conn) # Ignore sender address
- receive_and_confirm(conn) # Ignore recipient address
+ receive_and_confirm(conn) # Ignore HELO/EHLO
+ receive_and_confirm(conn) # Ignore sender address
+ receive_and_confirm(conn) # Ignore recipient address
- data = conn.recv(BUFFER_SIZE)
- conn.sendall(provide_message())
+ conn.recv(BUFFER_SIZE)
+ conn.sendall(provide_message())
- # Consume until we get ., the end-of-message marker.
- message = ''
- while not message.endswith(EOM):
- message += conn.recv(BUFFER_SIZE).decode(ENCODING)
- conn.sendall(ok(b"OK, id=test"))
+ # Consume until we get ., the end-of-message marker.
+ message = ''
+ while not message.endswith(EOM):
+ message += conn.recv(BUFFER_SIZE).decode(ENCODING)
+ conn.sendall(ok(b"OK, id=test"))
- conn.recv(BUFFER_SIZE)
- conn.sendall(bye())
+ conn.recv(BUFFER_SIZE)
+ conn.sendall(bye())
- conn.close()
+ conn.close()
- logging.debug(f"Received {len(message)} characters of data")
+ logging.debug(f"Received {len(message)} characters of data")
- # Trim EOM marker as we're only interested in the message body.
- return message[:-len(EOM)]
+ # Trim EOM marker as we're only interested in the message body.
+ return message[:-len(EOM)]
def error(msg, exit_code):
- logging.error(msg)
- print("ERROR: %s" % (msg))
- sys.exit(exit_code)
+ logging.error(msg)
+ print("ERROR: %s" % (msg))
+ sys.exit(exit_code)
# filename is relative to where we run the tests from, i.e. the project root
# directory
-logging.basicConfig(filename = 'test/logs/relay.log',
- format = '%(asctime)s %(pathname)s:%(lineno)d %(levelname)s [%(funcName)s] %(message)s',
- datefmt = '%Y-%m-%d %H:%M:%S',
- level = logging.DEBUG)
+logging.basicConfig(filename='test/logs/relay.log',
+ format='%(asctime)s %(pathname)s:%(lineno)d %(levelname)s [%(funcName)s] %(message)s',
+ datefmt='%Y-%m-%d %H:%M:%S',
+ level=logging.DEBUG)
if len(sys.argv) < 2:
- error("Usage: relay.py PORT_NUMBER", EXIT_UNAVAILABLE)
+ error("Usage: relay.py PORT_NUMBER", EXIT_UNAVAILABLE)
port = int(sys.argv[1])
body = serve(port)
diff --git a/test/utils/sendmail.py b/test/utils/sendmail.py
index edacf3b..ac5d36d 100644
--- a/test/utils/sendmail.py
+++ b/test/utils/sendmail.py
@@ -1,27 +1,48 @@
+import logging
import smtplib
import sys
import getopt
-def _send(host, port, from_addr, recipients, message):
- smtp = smtplib.SMTP(host, port)
- # smtp.starttls()
- # try:
- # breakpoint()
- smtp.sendmail(from_addr, recipients, message)
- # except smtplib.SMTPDataError as e:
- # print(f"Couldn't deliver message.\nGot error: {e}\n")
+def _load_file(name):
+ f = open(name, 'r')
+ contents = f.read()
+ f.close()
+ return contents
+def _send(host, port, from_addr, recipients, message):
+ logging.info(f"From {from_addr} to {recipients} at {host}:{port}")
+ try:
+ smtp = smtplib.SMTP(host, port)
+ # smtp.starttls()
+ return smtp.sendmail(from_addr, recipients, message)
+ except smtplib.SMTPDataError as e:
+ logging.error(f"Couldn't deliver message. Got error: {e}")
+ return None
+ except ConnectionRefusedError as e:
+ logging.exception(f"Connection refused: {e}")
+ return None
+
+
+logging.basicConfig(filename="test/logs/sendmail.log",
+ format="%(asctime)s %(pathname)s:%(lineno)d %(levelname)s [%(funcName)s] %(message)s",
+ datefmt="%Y-%m-%d %H:%M:%S",
+ level=logging.DEBUG)
+
sender = recipient = message = None
-for opt, value in getopt.getopt(sys.argv[1:], "f:t:m:"):
- if opt == "f":
+opts, _ = getopt.getopt(sys.argv[1:], "f:t:m:")
+for opt, value in opts:
+ if opt == "-f":
sender = value
- if opt == "t":
+ logging.debug(f"Sender is {sender}")
+ if opt == "-t":
recipient = value
- if opt == "m":
- message = value
+ logging.debug(f"Recipient is {recipient}")
+ if opt == "-m":
+ message = _load_file(value)
+ logging.debug(f"Message is {message}")
if message is None:
message = """\