Compare commits

..

3 Commits

Author SHA1 Message Date
holger krekel
0885d8f72e apply nami's suggestions (chatmail SSH env var, running --slow in test.sh) 2023-10-16 17:48:15 +02:00
holger krekel
bb567b4fb7 also show the chatmail instance prominently in the test header 2023-10-16 17:09:45 +02:00
holger krekel
fdb01d269c - introduce pytest.mark.slow marker and "--slow" CLI option
- refactor login tests to allow running them against both imap/smtp
2023-10-16 17:00:39 +02:00
7 changed files with 20 additions and 79 deletions

View File

@@ -160,16 +160,6 @@ def _configure_dovecot(mail_server: str) -> bool:
) )
need_restart |= auth_config.changed need_restart |= auth_config.changed
files.put(
src=importlib.resources.files(__package__)
.joinpath("dovecot/expunge.cron")
.open("rb"),
dest="/etc/cron.d/expunge",
user="root",
group="root",
mode="644",
)
return need_restart return need_restart

View File

@@ -1,4 +0,0 @@
2 0 * * * dovecot doveadm expunge -A SEEN BEFORE 40d INBOX
2 0 * * * dovecot doveadm expunge -A SEEN BEFORE 40d Deltachat
2 0 * * * dovecot doveadm expunge -A SEEN BEFORE 40d Trash
2 30 * * * dovecot doveadm purge -A

View File

@@ -30,23 +30,13 @@ def maildomain():
@pytest.fixture @pytest.fixture
def sshdomain(maildomain): def chatmail_ssh(maildomain):
return os.environ.get("CHATMAIL_SSH", maildomain) domain = os.environ.get("CHATMAIL_SSH")
@pytest.fixture
def maildomain2():
domain = os.environ.get("CHATMAIL_DOMAIN2")
if not domain: if not domain:
pytest.skip("set CHATMAIL_DOMAIN2 to a ssh-reachable chatmail instance") domain = maildomain
return domain return domain
@pytest.fixture
def sshdomain2(maildomain2):
return os.environ.get("CHATMAIL_SSH2", maildomain2)
def pytest_report_header(): def pytest_report_header():
domain = os.environ.get("CHATMAIL_DOMAIN") domain = os.environ.get("CHATMAIL_DOMAIN")
if domain: if domain:
@@ -61,8 +51,6 @@ def imap(maildomain):
class ImapConn: class ImapConn:
AuthError = imaplib.IMAP4.error AuthError = imaplib.IMAP4.error
logcmd = "journalctl -f -u dovecot"
name = "dovecot"
def __init__(self, host): def __init__(self, host):
self.host = host self.host = host
@@ -83,8 +71,6 @@ def smtp(maildomain):
class SmtpConn: class SmtpConn:
AuthError = smtplib.SMTPAuthenticationError AuthError = smtplib.SMTPAuthenticationError
logcmd = "journalctl -f -t postfix/smtpd -t postfix/smtp -t postfix/lmtp"
name = "postfix"
def __init__(self, host): def __init__(self, host):
self.host = host self.host = host
@@ -108,17 +94,16 @@ def gencreds(maildomain):
count = itertools.count() count = itertools.count()
next(count) next(count)
def gen(domain=None): def gen():
domain = domain if domain else maildomain
while 1: while 1:
num = next(count) num = next(count)
alphanumeric = "abcdefghijklmnopqrstuvwxyz1234567890" alphanumeric = "abcdefghijklmnopqrstuvwxyz1234567890"
user = "".join(random.choices(alphanumeric, k=10)) user = "".join(random.choices(alphanumeric, k=10))
user = f"ac{num}_{user}" user = f"ac{num}_{user}"
password = "".join(random.choices(alphanumeric, k=10)) password = "".join(random.choices(alphanumeric, k=10))
yield f"{user}@{domain}", f"{password}" yield f"{user}@{maildomain}", f"{password}"
return lambda domain=None: next(gen(domain)) return lambda: next(gen())
# #
@@ -133,13 +118,12 @@ class ChatmailTestProcess:
def __init__(self, pytestconfig, maildomain, gencreds): def __init__(self, pytestconfig, maildomain, gencreds):
self.pytestconfig = pytestconfig self.pytestconfig = pytestconfig
self.maildomain = maildomain self.maildomain = maildomain
assert "." in self.maildomain, maildomain
self.gencreds = gencreds self.gencreds = gencreds
self._addr2files = {} self._addr2files = {}
def get_liveconfig_producer(self): def get_liveconfig_producer(self):
while 1: while 1:
user, password = self.gencreds(self.maildomain) user, password = self.gencreds()
config = { config = {
"addr": user, "addr": user,
"mail_pw": password, "mail_pw": password,
@@ -157,21 +141,13 @@ class ChatmailTestProcess:
@pytest.fixture @pytest.fixture
def cmfactory(request, gencreds, tmpdir, data, maildomain): def cmfactory(request, maildomain, gencreds, tmpdir, data):
# cloned from deltachat.testplugin.amfactory # cloned from deltachat.testplugin.amfactory
pytest.importorskip("deltachat") pytest.importorskip("deltachat")
from deltachat.testplugin import ACFactory from deltachat.testplugin import ACFactory
testproc = ChatmailTestProcess(request.config, maildomain, gencreds) testproc = ChatmailTestProcess(request.config, maildomain, gencreds)
am = ACFactory(request=request, tmpdir=tmpdir, testprocess=testproc, data=data) am = ACFactory(request=request, tmpdir=tmpdir, testprocess=testproc, data=data)
# nb. a bit hacky
# would probably be better if deltachat's test machinery grows native support
def switch_maildomain(maildomain2):
am.testprocess.maildomain = maildomain2
am.switch_maildomain = switch_maildomain
yield am yield am
if hasattr(request.node, "rep_call") and request.node.rep_call.failed: if hasattr(request.node, "rep_call") and request.node.rep_call.failed:
if testproc.pytestconfig.getoption("--extra-info"): if testproc.pytestconfig.getoption("--extra-info"):
@@ -182,20 +158,13 @@ def cmfactory(request, gencreds, tmpdir, data, maildomain):
@pytest.fixture @pytest.fixture
def remote(sshdomain): def dovelogreader(chatmail_ssh):
return Remote(sshdomain) def remote_reader():
popen = subprocess.Popen(
["ssh", f"root@{chatmail_ssh}", "journalctl -f -u dovecot"],
class Remote:
def __init__(self, sshdomain):
self.sshdomain = sshdomain
def iter_output(self, logcmd=""):
getjournal = f"journalctl -f" if not logcmd else logcmd
self.popen = subprocess.Popen(
["ssh", f"root@{self.sshdomain}", getjournal],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
) )
while 1: while 1:
line = self.popen.stdout.readline() yield popen.stdout.readline()
yield line.decode().strip().lower()
return remote_reader

View File

@@ -1,15 +0,0 @@
def test_remote(remote, imap_or_smtp):
lineproducer = remote.iter_output(imap_or_smtp.logcmd)
imap_or_smtp.connect()
assert imap_or_smtp.name in next(lineproducer)
def test_use_two_chatmailservers(cmfactory, maildomain2):
ac1 = cmfactory.new_online_configuring_account(cache=False)
cmfactory.switch_maildomain(maildomain2)
ac2 = cmfactory.new_online_configuring_account(cache=False)
cmfactory.bring_accounts_online()
cmfactory.get_accepted_chat(ac1, ac2)
domain1 = ac1.get_config("addr").split("@")[1]
domain2 = ac2.get_config("addr").split("@")[1]
assert domain1 != domain2

View File

@@ -17,7 +17,7 @@ def test_login_basic_functioning(imap_or_smtp, gencreds, lp):
imap_or_smtp.connect() imap_or_smtp.connect()
lp.sec("success") lp.sec("success")
lp.sec(f"reconnect and verify wrong password fails {user} ") lp.sec("reconnect and verify wrong password fails {user} ")
imap_or_smtp.connect() imap_or_smtp.connect()
with pytest.raises(imap_or_smtp.AuthError): with pytest.raises(imap_or_smtp.AuthError):
imap_or_smtp.login(user, password + "wrong") imap_or_smtp.login(user, password + "wrong")

View File

@@ -19,7 +19,7 @@ class TestEndToEndDeltaChat:
assert msg2.text == "message0" assert msg2.text == "message0"
@pytest.mark.slow @pytest.mark.slow
def test_exceed_quota(self, cmfactory, lp, tmpdir, remote): def test_exceed_quota(self, cmfactory, lp, tmpdir, dovelogreader):
"""This is a very slow test as it needs to upload >100MB of mail data """This is a very slow test as it needs to upload >100MB of mail data
before quota is exceeded, and thus depends on the speed of the upload. before quota is exceeded, and thus depends on the speed of the upload.
""" """
@@ -48,7 +48,8 @@ class TestEndToEndDeltaChat:
addr = ac2.get_config("addr").lower() addr = ac2.get_config("addr").lower()
saved_ok = 0 saved_ok = 0
for line in remote.iter_output("journalctl -f -u dovecot"): for line in dovelogreader():
line = line.decode().lower().strip()
if addr not in line: if addr not in line:
# print(line) # print(line)
continue continue

View File

@@ -3,7 +3,7 @@
## Dovecot goals/steps ## Dovecot goals/steps
- automatic expiry of messages older than M days - automatic expiry of messages older than M days
- also expunge unread messages - delete unconditionally messages older than 40 days
- limit: configure max-connections per account - limit: configure max-connections per account