mirror of
https://github.com/chatmail/relay.git
synced 2026-05-20 04:48:06 +00:00
add a quota test (inspired by nami's #21 ) and try to get postfix/dovecot to implement the limit and the test to pass (it doesn't yet)
This commit is contained in:
@@ -79,7 +79,7 @@ plugin {
|
|||||||
quota_rule = *:storage=100M
|
quota_rule = *:storage=100M
|
||||||
quota_max_mail_size=30M
|
quota_max_mail_size=30M
|
||||||
quota_grace = 0
|
quota_grace = 0
|
||||||
quota_over_flag_value = TRUE
|
# quota_over_flag_value = TRUE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ mydestination =
|
|||||||
relayhost =
|
relayhost =
|
||||||
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
|
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
|
||||||
mailbox_size_limit = 0
|
mailbox_size_limit = 0
|
||||||
|
# maximum 30MB sized messages
|
||||||
|
message_size_limit = 31457280
|
||||||
recipient_delimiter = +
|
recipient_delimiter = +
|
||||||
inet_interfaces = all
|
inet_interfaces = all
|
||||||
inet_protocols = all
|
inet_protocols = all
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
# service type private unpriv chroot wakeup maxproc command + args
|
# service type private unpriv chroot wakeup maxproc command + args
|
||||||
# (yes) (yes) (no) (never) (100)
|
# (yes) (yes) (no) (never) (100)
|
||||||
# ==========================================================================
|
# ==========================================================================
|
||||||
smtp inet n - y - - smtpd
|
smtp inet n - y - - smtpd -v
|
||||||
#smtp inet n - y - 1 postscreen
|
#smtp inet n - y - 1 postscreen
|
||||||
#smtpd pass - - y - - smtpd
|
#smtpd pass - - y - - smtpd
|
||||||
#dnsblog unix - - y - 0 dnsblog
|
#dnsblog unix - - y - 0 dnsblog
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import io
|
import io
|
||||||
|
import random
|
||||||
import imaplib
|
import imaplib
|
||||||
import smtplib
|
import smtplib
|
||||||
import itertools
|
import itertools
|
||||||
@@ -50,13 +51,15 @@ class SmtpConn:
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def gencreds(maildomain):
|
def gencreds(maildomain):
|
||||||
prefix = str(time.time())
|
|
||||||
count = itertools.count()
|
count = itertools.count()
|
||||||
|
|
||||||
def gen():
|
def gen():
|
||||||
while 1:
|
while 1:
|
||||||
num = next(count)
|
num = next(count)
|
||||||
yield f"user{prefix}_{num}@{maildomain}", f"password{prefix}_{num}"
|
alphanumeric = "abcdefghijklmnopqrstuvwxyz1234567890"
|
||||||
|
user = "".join(random.choices(alphanumeric, k=10))
|
||||||
|
password = "".join(random.choices(alphanumeric, k=10))
|
||||||
|
yield f"{user}@{maildomain}", f"{password}"
|
||||||
|
|
||||||
return lambda: next(gen())
|
return lambda: next(gen())
|
||||||
|
|
||||||
@@ -99,7 +102,7 @@ def cmfactory(request, maildomain, gencreds, tmpdir, data):
|
|||||||
am = ACFactory(request=request, tmpdir=tmpdir, testprocess=testproc, data=data)
|
am = ACFactory(request=request, tmpdir=tmpdir, testprocess=testproc, data=data)
|
||||||
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 testprocess.pytestconfig.getoption("--extra-info"):
|
if testproc.pytestconfig.getoption("--extra-info"):
|
||||||
logfile = io.StringIO()
|
logfile = io.StringIO()
|
||||||
am.dump_imap_summary(logfile=logfile)
|
am.dump_imap_summary(logfile=logfile)
|
||||||
print(logfile.getvalue())
|
print(logfile.getvalue())
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import random
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
class TestMailSending:
|
class TestMailSending:
|
||||||
def test_one_on_one(self, cmfactory, lp):
|
def test_one_on_one(self, cmfactory, lp):
|
||||||
ac1, ac2 = cmfactory.get_online_accounts(2)
|
ac1, ac2 = cmfactory.get_online_accounts(2)
|
||||||
@@ -9,3 +13,41 @@ class TestMailSending:
|
|||||||
lp.sec("wait for ac2 to receive message")
|
lp.sec("wait for ac2 to receive message")
|
||||||
msg2 = ac2._evtracker.wait_next_incoming_message()
|
msg2 = ac2._evtracker.wait_next_incoming_message()
|
||||||
assert msg2.text == "message0"
|
assert msg2.text == "message0"
|
||||||
|
|
||||||
|
def test_exceed_quota(self, cmfactory, lp, tmpdir):
|
||||||
|
ac1, ac2 = cmfactory.get_online_accounts(2)
|
||||||
|
chat = cmfactory.get_accepted_chat(ac1, ac2)
|
||||||
|
|
||||||
|
quota = 1024 * 1024 * 100
|
||||||
|
attachsize = 1 * 1024 * 1024
|
||||||
|
num_to_send = quota // attachsize + 2
|
||||||
|
lp.sec(f"ac1: send {num_to_send} large files to ac2")
|
||||||
|
lp.indent(f"per-user quota is assumed to be: {quota/(1024*1024)}MB")
|
||||||
|
alphanumeric = "abcdefghijklmnopqrstuvwxyz1234567890"
|
||||||
|
msgs = []
|
||||||
|
for i in range(num_to_send):
|
||||||
|
attachment = tmpdir / f"attachment{i}"
|
||||||
|
data = "".join(random.choice(alphanumeric) for i in range(1024))
|
||||||
|
with open(attachment, "w+") as f:
|
||||||
|
for j in range(attachsize // len(data)):
|
||||||
|
f.write(data)
|
||||||
|
|
||||||
|
msg = chat.send_file(str(attachment))
|
||||||
|
msgs.append(msg)
|
||||||
|
lp.indent(f"Sent out msg {i}, size {attachsize/(1024*1024)}MB")
|
||||||
|
|
||||||
|
lp.sec("ac2: check that at least one message failed due to quota")
|
||||||
|
bytes_sent = 0
|
||||||
|
for i, msg in enumerate(msgs):
|
||||||
|
# wait for the message to be received
|
||||||
|
msg_received = ac2.wait_next_incoming_message()
|
||||||
|
if msg.is_out_failed():
|
||||||
|
assert bytes_sent + 10 * 1024*1024 > quota, "quota kicked in too early"
|
||||||
|
lp.indent("good, message sending failed because quota was exceeded")
|
||||||
|
lp.indent(chat.get_messages()[i].get_message_info())
|
||||||
|
return
|
||||||
|
assert msg.is_out_delivered(), msg.get_message_info()
|
||||||
|
bytes_sent += attachsize
|
||||||
|
mb = bytes_sent // (1024*1024)
|
||||||
|
lp.indent(f"message {i} success, bytes transmitted so far {mb}MB")
|
||||||
|
pytest.fail("sending succeeded although messages should exceed quota")
|
||||||
|
|||||||
Reference in New Issue
Block a user