Changeset - 8902cd5aa66b
[Not reviewed]
0 2 0
Branko Majic (branko) - 15 months ago 2024-09-06 15:02:01
branko@majic.rs
MAR-218: Improve mail server role test reliability:

- Introduce sleep after sending out mails in order to ensure that
Postfix has had enough time to process the messages.
- Relevant only for tests that take care of parsing the mail log.
- Solves the false negatives caused by timing issues.
- It might be a good idea down the line to implement some kind of
retry/backoff mechanism instead.
2 files changed with 16 insertions and 1 deletions:
0 comments (0 inline, 0 general)
roles/mail_server/molecule/default/tests/test_default.py
Show inline comments
 
import os
 
import re
 
import time
 
import uuid
 

	
 
import defusedxml.ElementTree as ElementTree
 

	
 
import testinfra.utils.ansible_runner
 

	
 

	
 
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
 
    os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('parameters-*')
 

	
 

	
 
def test_installed_packages(host):
 
@@ -249,24 +250,27 @@ def test_postfix_delivery_to_dovecot(host):
 
    """
 
    Tests if mail received by Postfix is properly delivered to Dovecot.
 
    """
 

	
 
    hostname = host.run('hostname').stdout.strip()
 

	
 
    message_id = "%s@localhost" % str(uuid.uuid4())
 

	
 
    # Virtual account.
 
    send = host.run('swaks --header %s --suppress-data --to john.doe@domain1 --server %s', "Message-Id: <%s>" % message_id, hostname)
 
    assert send.rc == 0
 

	
 
    # Wait for a little while for message to be processed.
 
    time.sleep(5)
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 
        pattern = r"dovecot: lda\(john.doe@domain1\)<\d+><.+?>: msgid=<%s>: saved mail to INBOX" % message_id
 
        assert re.search(pattern, mail_log.content_string) is not None
 

	
 

	
 
def test_dovecot_system_authentication_is_disabled(host):
 
    """
 
    Tests if Dovecot system-based authentication has been disabled.
 
    """
 

	
 
    config = host.file("/etc/dovecot/conf.d/10-auth.conf")
 
@@ -525,24 +529,27 @@ def test_smtp_tls_connectivity(host):
 

	
 
def test_postfix_local_delivery(host):
 
    """
 
    Tests if mail received by Postfix is properly delivered to local
 
    account's mail spool.
 
    """
 

	
 
    message_id = "%s@localhost" % str(uuid.uuid4())
 

	
 
    send = host.run('swaks --header %s --suppress-data --to localuser@localhost --server localhost', "Message-Id: <%s>" % message_id)
 
    assert send.rc == 0
 

	
 
    # Wait for a little while for message to be processed.
 
    time.sleep(5)
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 

	
 
        pattern = r"postfix/cleanup\[\d+\]: (?P<queue_id>[^:]+): message-id=<%s>" % message_id
 
        match_result = re.search(pattern, mail_log.content_string)
 
        assert match_result is not None
 

	
 
        queue_id = match_result.group('queue_id')
 
        pattern = r"postfix/local\[\d+\]: %s: to=<localuser@localhost>, relay=local,.*, status=sent \(delivered to mailbox\)" % queue_id
 
        match_result = re.search(pattern, mail_log.content_string)
 
        assert match_result is not None, queue_id
 

	
 
@@ -553,24 +560,27 @@ def test_postfix_sends_mails_without_tls_when_unavailable(host):
 
    on remote server.
 
    """
 

	
 
    # Verify that the remote host refuses to accept mails over TLS first.
 
    send = host.run('swaks --tls --suppress-data --to root@smtp-server-refusing-tls --server smtp-server-refusing-tls')
 
    assert send.rc == 29
 
    assert "Host did not advertise STARTTLS" in send.stderr
 

	
 
    message_id = "%s@localhost" % str(uuid.uuid4())
 
    send = host.run('swaks --header %s --suppress-data --to root@smtp-server-refusing-tls --server localhost', "Message-Id: <%s>" % message_id)
 
    assert send.rc == 0
 

	
 
    # Wait for a little while for message to be processed.
 
    time.sleep(5)
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 

	
 
        pattern = r"postfix/cleanup\[\d+\]: (?P<queue_id>[^:]+): message-id=<%s>" % message_id
 
        match_result = re.search(pattern, mail_log.content_string)
 
        assert match_result is not None
 

	
 
        queue_id = match_result.group('queue_id')
 
        pattern = r"postfix/smtp\[\d+\]: %s: to=<root@smtp-server-refusing-tls>, relay=smtp-server-refusing-tls.*, status=sent" % queue_id
 
        match_result = re.search(pattern, mail_log.content_string)
 
        assert match_result is not None, queue_id
 

	
 
@@ -581,24 +591,27 @@ def test_postfix_sends_mails_over_tls_when_available(host):
 
    remote server (oportunistic encryption).
 
    """
 

	
 
    # Verify that the remote host refuses to accept mails without TLS first.
 
    send = host.run('swaks --suppress-data --to root@smtp-server-requiring-tls --server smtp-server-requiring-tls')
 
    assert send.rc == 23
 
    assert "Must issue a STARTTLS command first" in send.stdout
 

	
 
    message_id = "%s@localhost" % str(uuid.uuid4())
 
    send = host.run('swaks --tls --header %s --suppress-data --to root@smtp-server-requiring-tls --server localhost', "Message-Id: <%s>" % message_id)
 
    assert send.rc == 0
 

	
 
    # Wait for a little while for message to be processed.
 
    time.sleep(5)
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 

	
 
        pattern = r"postfix/cleanup\[\d+\]: (?P<queue_id>[^:]+): message-id=<%s>" % message_id
 
        match_result = re.search(pattern, mail_log.content_string)
 
        assert match_result is not None
 

	
 
        queue_id = match_result.group('queue_id')
 
        pattern = r"postfix/smtp\[\d+\]: %s: to=<root@smtp-server-requiring-tls>, relay=smtp-server-requiring-tls.*, status=sent" % queue_id
 
        match_result = re.search(pattern, mail_log.content_string)
 
        assert match_result is not None, queue_id
 

	
roles/mail_server/molecule/default/tests/test_optional.py
Show inline comments
 
@@ -48,27 +48,29 @@ def test_postfix_main_cf_file_content(host):
 
    assert "  reject_rbl_client zen.spamhaus.org" in config_lines
 
    assert "smtp_host_lookup = dns, native" in config_lines
 

	
 

	
 
def test_local_aliases(host):
 
    """
 
    Tests if local aliases are configured correctly.
 
    """
 

	
 
    message_id = "%s@localhost" % str(uuid.uuid4())
 

	
 
    send = host.run('swaks --header %s --suppress-data --to root@localhost', "Message-Id: <%s>" % message_id)
 
    time.sleep(1)
 
    assert send.rc == 0
 

	
 
    # Wait for a little while for message to be processed.
 
    time.sleep(5)
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 
        pattern = r"dovecot: lda\(john.doe@domain1\)<\d+><.+?>: msgid=<%s>: saved mail to INBOX" % message_id
 
        assert re.search(pattern, mail_log.content_string) is not None
 

	
 

	
 
def test_dovecot_mailbox_directories(host):
 
    """
 
    Tests if mailbox directories are created correctly.
 
    """
 

	
 
    # Deliver two mails in order to make sure the directory structure is
0 comments (0 inline, 0 general)