diff --git a/python/src/deltachat/testplugin.py b/python/src/deltachat/testplugin.py index 673782eb5..f889c9489 100644 --- a/python/src/deltachat/testplugin.py +++ b/python/src/deltachat/testplugin.py @@ -214,11 +214,13 @@ def data(request): class PendingConfigure: CONFIGURING = "CONFIGURING" CONFIGURED = "CONFIGURED" - POSTPROCESSED = "POSTPROCESSED" + IDLEREADY = "IDLEREADY" - def __init__(self): + def __init__(self, init_time): self._configured_events = Queue() self._account2state = {} + self._imap_cleaned = set() + self.init_time = init_time def add_account(self, acc, reconfigure=False): class PendingTracker: @@ -231,34 +233,67 @@ class PendingConfigure: acc.configure(reconfigure=reconfigure) print("started configure on pending", acc) - def wait_all(self, onconfigured=lambda x: None): - """ Wait for all accounts to finish configuration. - """ - print("wait_all finds accounts=", self._account2state) - for acc, state in self._account2state.items(): - if state == self.CONFIGURED: - onconfigured(acc) - self._account2state[acc] = self.POSTPROCESSED - - while self.CONFIGURING in self._account2state.values(): - acc, success = self._pop_one() - onconfigured(acc) - self._account2state[acc] = self.POSTPROCESSED - print("finished, account2state", self._account2state) - - def wait_one(self, account): + def wait_one_configured(self, account): if self._account2state[account] == self.CONFIGURING: while 1: - acc, success = self._pop_one() + acc = self._pop_config_success() if acc == account: break + self.init_direct_imap_and_logging(acc) + acc._evtracker.consume_events() - def _pop_one(self): + def bring_online(self): + """ Wait for all accounts to finish configuration. + """ + print("wait_all_configured finds accounts=", self._account2state) + for acc, state in self._account2state.items(): + if state == self.CONFIGURED: + self._onconfigure_start_io(acc) + self._account2state[acc] = self.IDLEREADY + + while self.CONFIGURING in self._account2state.values(): + acc = self._pop_config_success() + self._onconfigure_start_io(acc) + self._account2state[acc] = self.IDLEREADY + print("finished, account2state", self._account2state) + + def _pop_config_success(self): acc, success = self._configured_events.get() if not success: pytest.fail("configuring online account failed: {}".format(acc)) self._account2state[acc] = self.CONFIGURED - return (acc, success) + return acc + + def _onconfigure_start_io(self, acc): + acc.start_io() + print(acc._logid, "waiting for inbox IDLE to become ready") + acc._evtracker.wait_idle_inbox_ready() + self.init_direct_imap_and_logging(acc) + acc.get_device_chat().mark_noticed() + acc._evtracker.consume_events() + acc.log("inbox IDLE ready") + + def init_direct_imap_and_logging(self, acc): + """ idempotent function for initializing direct_imap and logging for an account. """ + self.init_direct_imap(acc) + logger = FFIEventLogger(acc, logid=acc._logid, init_time=self.init_time) + acc.add_account_plugin(logger, name=acc._logid) + + def init_direct_imap(self, acc): + from deltachat.direct_imap import DirectImap + if not hasattr(acc, "direct_imap"): + acc.direct_imap = DirectImap(acc) + addr = acc.get_config("addr") + if addr not in self._imap_cleaned: + imap = acc.direct_imap + for folder in imap.list_folders(): + if folder.lower() == "inbox" or folder.lower() == "deltachat": + assert imap.select_folder(folder) + imap.delete("1:*", expunge=True) + else: + imap.conn.folder.delete(folder) + acc.log("imap cleaned for addr {}".format(addr)) + self._imap_cleaned.add(addr) class ACFactory: @@ -275,8 +310,7 @@ class ACFactory: self._finalizers = [] self._accounts = [] - self._pending_configure = PendingConfigure() - self._imap_cleaned = set() + self._pending_configure = PendingConfigure(self.init_time) self._preconfigured_keys = ["alice", "bob", "charlie", "dom", "elena", "fiona"] self.set_logging_default(False) @@ -382,29 +416,12 @@ class ACFactory: def new_cloned_configuring_account(self, account): return self.new_online_configuring_account(cloned_from=account) - def _onconfigure_start_io(self, acc): - acc.start_io() - print(acc._logid, "waiting for inbox IDLE to become ready") - acc._evtracker.wait_idle_inbox_ready() - self.init_direct_imap_and_logging(acc) - acc.get_device_chat().mark_noticed() - acc._evtracker.consume_events() - acc.log("inbox IDLE ready") - - def init_direct_imap_and_logging(self, acc): - """ idempotent function for initializing direct_imap and logging for an account. """ - self.init_direct_imap(acc) - logger = FFIEventLogger(acc, logid=acc._logid, init_time=self.init_time) - acc.add_account_plugin(logger, name=acc._logid) - def wait_configured(self, acc): - self._pending_configure.wait_one(acc) - self.init_direct_imap_and_logging(acc) - acc._evtracker.consume_events() + self._pending_configure.wait_one_configured(acc) def bring_accounts_online(self): print("bringing accounts online") - self._pending_configure.wait_all(onconfigured=self._onconfigure_start_io) + self._pending_configure.bring_online() print("all accounts online") def get_online_accounts(self, num): @@ -447,22 +464,6 @@ class ACFactory: self._finalizers.append(bot.kill) return bot - def init_direct_imap(self, acc): - from deltachat.direct_imap import DirectImap - if not hasattr(acc, "direct_imap"): - acc.direct_imap = DirectImap(acc) - addr = acc.get_config("addr") - if addr not in self._imap_cleaned: - imap = acc.direct_imap - for folder in imap.list_folders(): - if folder.lower() == "inbox" or folder.lower() == "deltachat": - assert imap.select_folder(folder) - imap.delete("1:*", expunge=True) - else: - imap.conn.folder.delete(folder) - acc.log("imap cleaned for addr {}".format(addr)) - self._imap_cleaned.add(addr) - def dump_imap_summary(self, logfile): for ac in self._accounts: ac.dump_account_info(logfile=logfile) diff --git a/python/tests/test_account.py b/python/tests/test_account.py index 3fb68e521..76108f850 100644 --- a/python/tests/test_account.py +++ b/python/tests/test_account.py @@ -2401,7 +2401,7 @@ class TestOnlineAccount: ac3.stop_io() acfactory.remove_preconfigured_keys() ac4 = acfactory.new_cloned_configuring_account(ac3) - acfactory._pending_configure.wait_one(ac4) + acfactory.wait_configured(ac4) # Create contacts to make sure incoming messages are not treated as contact requests chat41 = ac4.create_chat(ac1) chat42 = ac4.create_chat(ac2) diff --git a/python/tests/test_lowlevel.py b/python/tests/test_lowlevel.py index f9fa21e2a..1ae8ff188 100644 --- a/python/tests/test_lowlevel.py +++ b/python/tests/test_lowlevel.py @@ -12,21 +12,23 @@ from deltachat.testplugin import PendingConfigure class TestPendingConfigure: def test_basic_states(self, acfactory, monkeypatch): - pc = PendingConfigure() + pc = PendingConfigure(init_time=0.0) acc = acfactory.get_unconfigured_account() monkeypatch.setattr(acc, "configure", lambda **kwargs: None) pc.add_account(acc) assert pc._account2state[acc] == pc.CONFIGURING pc._configured_events.put((acc, True)) - pc.wait_one(acc) + monkeypatch.setattr(pc, "init_direct_imap", lambda *args, **kwargs: None) + pc.wait_one_configured(acc) assert pc._account2state[acc] == pc.CONFIGURED - accounts = [] - pc.wait_all(onconfigured=accounts.append) - assert pc._account2state[acc] == pc.POSTPROCESSED - assert accounts == [acc] + monkeypatch.setattr(pc, "_onconfigure_start_io", lambda *args, **kwargs: None) + pc.bring_online() + assert pc._account2state[acc] == pc.IDLEREADY def test_two_accounts_one_waited_all_started(self, monkeypatch, acfactory): - pc = PendingConfigure() + pc = PendingConfigure(init_time=0.0) + monkeypatch.setattr(pc, "init_direct_imap", lambda *args, **kwargs: None) + monkeypatch.setattr(pc, "_onconfigure_start_io", lambda *args, **kwargs: None) ac1 = acfactory.get_unconfigured_account() monkeypatch.setattr(ac1, "configure", lambda **kwargs: None) pc.add_account(ac1) @@ -36,15 +38,13 @@ class TestPendingConfigure: assert pc._account2state[ac1] == pc.CONFIGURING assert pc._account2state[ac2] == pc.CONFIGURING pc._configured_events.put((ac1, True)) - pc.wait_one(ac1) + pc.wait_one_configured(ac1) assert pc._account2state[ac1] == pc.CONFIGURED assert pc._account2state[ac2] == pc.CONFIGURING - accounts = [] pc._configured_events.put((ac2, True)) - pc.wait_all(onconfigured=accounts.append) - assert pc._account2state[ac1] == pc.POSTPROCESSED - assert pc._account2state[ac2] == pc.POSTPROCESSED - assert accounts == [ac1, ac2] + pc.bring_online() + assert pc._account2state[ac1] == pc.IDLEREADY + assert pc._account2state[ac2] == pc.IDLEREADY def test_empty_context():