Skip to content

Commit c8bfa98

Browse files
committed
actually enable online account caching. previously it was creating (>100) online test accounts
1 parent 34053c7 commit c8bfa98

File tree

5 files changed

+48
-31
lines changed

5 files changed

+48
-31
lines changed

python/src/deltachat/direct_imap.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ class IdleManager:
177177
def __init__(self, direct_imap):
178178
self.direct_imap = direct_imap
179179
self.log = direct_imap.account.log
180+
# fetch latest messages before starting idle so that it only
181+
# returns messages that arrive anew
182+
self.direct_imap.conn.fetch("1:*")
180183
self.direct_imap.conn.idle.start()
181184

182185
def check(self, timeout=None) -> List[bytes]:

python/src/deltachat/testplugin.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ class TestProcess:
138138
"""
139139
def __init__(self, pytestconfig):
140140
self.pytestconfig = pytestconfig
141+
self._addr2files = {}
142+
self._configlist = []
141143

142144
def get_liveconfig_producer(self):
143145
""" provide live account configs, cached on a per-test-process scope
@@ -149,22 +151,21 @@ def get_liveconfig_producer(self):
149151
if not liveconfig_opt:
150152
pytest.skip("specify DCC_NEW_TMP_EMAIL or --liveconfig to provide live accounts")
151153

152-
configlist = []
153154
if not liveconfig_opt.startswith("http"):
154155
for line in open(liveconfig_opt):
155156
if line.strip() and not line.strip().startswith('#'):
156157
d = {}
157158
for part in line.split():
158159
name, value = part.split("=")
159160
d[name] = value
160-
configlist.append(d)
161+
self._configlist.append(d)
161162

162-
yield from iter(configlist)
163+
yield from iter(self._configlist)
163164
else:
164165
MAX_LIVE_CREATED_ACCOUNTS = 10
165166
for index in range(MAX_LIVE_CREATED_ACCOUNTS):
166167
try:
167-
yield configlist[index]
168+
yield self._configlist[index]
168169
except IndexError:
169170
res = requests.post(liveconfig_opt)
170171
if res.status_code != 200:
@@ -173,7 +174,7 @@ def get_liveconfig_producer(self):
173174
d = res.json()
174175
config = dict(addr=d["email"], mail_pw=d["password"])
175176
print("newtmpuser {}: addr={}".format(index, config["addr"]))
176-
configlist.append(config)
177+
self._configlist.append(config)
177178
yield config
178179
pytest.fail("more than {} live accounts requested.".format(MAX_LIVE_CREATED_ACCOUNTS))
179180

@@ -217,10 +218,11 @@ class ACSetup:
217218
CONFIGURED = "CONFIGURED"
218219
IDLEREADY = "IDLEREADY"
219220

220-
def __init__(self, init_time):
221+
def __init__(self, testprocess, init_time):
221222
self._configured_events = Queue()
222223
self._account2state = {}
223224
self._imap_cleaned = set()
225+
self.testprocess = testprocess
224226
self.init_time = init_time
225227

226228
def start_configure(self, account, reconfigure=False):
@@ -242,7 +244,8 @@ def wait_one_configured(self, account):
242244
acc = self._pop_config_success()
243245
if acc == account:
244246
break
245-
self.init_direct_imap_and_logging(acc)
247+
self.init_imap(acc)
248+
self.init_logging(acc)
246249
acc._evtracker.consume_events()
247250

248251
def bring_online(self):
@@ -272,25 +275,24 @@ def _pop_config_success(self):
272275
return acc
273276

274277
def _onconfigure_start_io(self, acc):
278+
self.init_imap(acc)
279+
self.init_logging(acc)
275280
acc.start_io()
276281
print(acc._logid, "waiting for inbox IDLE to become ready")
277282
acc._evtracker.wait_idle_inbox_ready()
278-
self.init_direct_imap_and_logging(acc)
279283
acc._evtracker.consume_events()
280284
acc.log("inbox IDLE ready")
281285

282-
def init_direct_imap_and_logging(self, acc):
283-
""" idempotent function for initializing direct_imap and logging for an account. """
284-
self.init_direct_imap(acc)
285-
self.init_logging(acc)
286-
287286
def init_logging(self, acc):
287+
""" idempotent function for initializing logging (will replace existing logger). """
288288
logger = FFIEventLogger(acc, logid=acc._logid, init_time=self.init_time)
289-
acc.add_account_plugin(logger, name=acc._logid)
289+
acc.add_account_plugin(logger, name="logger-" + acc._logid)
290290

291-
def init_direct_imap(self, acc):
292-
""" idempotent function for initializing direct_imap."""
291+
def init_imap(self, acc):
292+
""" initialize direct_imap and cleanup server state. """
293293
from deltachat.direct_imap import DirectImap
294+
295+
assert acc.is_configured()
294296
if not hasattr(acc, "direct_imap"):
295297
acc.direct_imap = DirectImap(acc)
296298
addr = acc.get_config("addr")
@@ -315,11 +317,12 @@ def __init__(self, request, testprocess, tmpdir, data) -> None:
315317
self.tmpdir = tmpdir
316318
self.pytestconfig = request.config
317319
self.data = data
320+
self.testprocess = testprocess
318321
self._liveconfig_producer = testprocess.get_liveconfig_producer()
319322

320323
self._finalizers = []
321324
self._accounts = []
322-
self._acsetup = ACSetup(self.init_time)
325+
self._acsetup = ACSetup(testprocess, self.init_time)
323326
self._preconfigured_keys = ["alice", "bob", "charlie",
324327
"dom", "elena", "fiona"]
325328
self.set_logging_default(False)
@@ -344,7 +347,7 @@ def get_next_liveconfig(self):
344347
""" Base function to get functional online configurations
345348
where we can make valid SMTP and IMAP connections with.
346349
"""
347-
configdict = next(self._liveconfig_producer)
350+
configdict = next(self._liveconfig_producer).copy()
348351
if "e2ee_enabled" not in configdict:
349352
configdict["e2ee_enabled"] = "1"
350353

@@ -480,10 +483,6 @@ def dump_imap_summary(self, logfile):
480483
ac.dump_account_info(logfile=logfile)
481484
imap = getattr(ac, "direct_imap", None)
482485
if imap is not None:
483-
try:
484-
imap.idle_done()
485-
except Exception:
486-
pass
487486
imap.dump_imap_structures(self.tmpdir, logfile=logfile)
488487

489488
def get_accepted_chat(self, ac1: Account, ac2: Account):
@@ -501,6 +500,7 @@ def introduce_each_other(self, accounts, sending=True):
501500
acc2.create_chat(acc).send_text("hi back")
502501
to_wait.append(acc)
503502
for acc in to_wait:
503+
acc.log("waiting for incoming message")
504504
acc._evtracker.wait_next_incoming_message()
505505

506506

python/tests/bench_test_setup.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88

99
import pytest
1010

11+
BENCH_NUM = 3
12+
1113

1214
class TestEmpty:
1315
def test_prepare_setup_measurings(self, acfactory):
14-
acfactory.get_online_accounts(5)
16+
acfactory.get_online_accounts(BENCH_NUM)
1517

16-
@pytest.mark.parametrize("num", range(0, 5))
18+
@pytest.mark.parametrize("num", range(0, BENCH_NUM + 1))
1719
def test_setup_online_accounts(self, acfactory, num):
1820
acfactory.get_online_accounts(num)

python/tests/test_1_online.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,8 @@ def test_send_and_receive_message_markseen(acfactory, lp):
419419
assert msg2.chat.id == msg4.chat.id
420420
assert ev.data1 == msg2.chat.id
421421
assert ev.data2 == 0
422+
idle2.wait_for_seen()
422423

423-
idle2.wait_for_new_message()
424424
lp.step("1")
425425
for i in range(2):
426426
ev = ac1._evtracker.get_matching("DC_EVENT_MSG_READ")

python/tests/test_4_lowlevel.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,23 @@
1111

1212

1313
class TestACSetup:
14-
def test_basic_states(self, acfactory, monkeypatch):
15-
pc = ACSetup(init_time=0.0)
14+
def test_basic_states(self, acfactory, monkeypatch, testprocess):
15+
pc = ACSetup(init_time=0.0, testprocess=testprocess)
1616
acc = acfactory.get_unconfigured_account()
1717
monkeypatch.setattr(acc, "configure", lambda **kwargs: None)
1818
pc.start_configure(acc)
1919
assert pc._account2state[acc] == pc.CONFIGURING
2020
pc._configured_events.put((acc, True))
21-
monkeypatch.setattr(pc, "init_direct_imap", lambda *args, **kwargs: None)
21+
monkeypatch.setattr(pc, "init_imap", lambda *args, **kwargs: None)
2222
pc.wait_one_configured(acc)
2323
assert pc._account2state[acc] == pc.CONFIGURED
2424
monkeypatch.setattr(pc, "_onconfigure_start_io", lambda *args, **kwargs: None)
2525
pc.bring_online()
2626
assert pc._account2state[acc] == pc.IDLEREADY
2727

28-
def test_two_accounts_one_waited_all_started(self, monkeypatch, acfactory):
29-
pc = ACSetup(init_time=0.0)
30-
monkeypatch.setattr(pc, "init_direct_imap", lambda *args, **kwargs: None)
28+
def test_two_accounts_one_waited_all_started(self, monkeypatch, acfactory, testprocess):
29+
pc = ACSetup(init_time=0.0, testprocess=testprocess)
30+
monkeypatch.setattr(pc, "init_imap", lambda *args, **kwargs: None)
3131
monkeypatch.setattr(pc, "_onconfigure_start_io", lambda *args, **kwargs: None)
3232
ac1 = acfactory.get_unconfigured_account()
3333
monkeypatch.setattr(ac1, "configure", lambda **kwargs: None)
@@ -47,6 +47,18 @@ def test_two_accounts_one_waited_all_started(self, monkeypatch, acfactory):
4747
assert pc._account2state[ac2] == pc.IDLEREADY
4848

4949

50+
def test_liveconfig_caching(acfactory, monkeypatch):
51+
prod = [
52+
{"addr": "[email protected]", "mail_pw": "123"},
53+
]
54+
acfactory._liveconfig_producer = iter(prod)
55+
d1 = acfactory.get_next_liveconfig()
56+
d1["hello"] = "world"
57+
acfactory._liveconfig_producer = iter(prod)
58+
d2 = acfactory.get_next_liveconfig()
59+
assert "hello" not in d2
60+
61+
5062
def test_empty_context():
5163
ctx = capi.lib.dc_context_new(capi.ffi.NULL, capi.ffi.NULL, capi.ffi.NULL)
5264
capi.lib.dc_context_unref(ctx)

0 commit comments

Comments
 (0)