mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 17:36:29 +03:00
shift startio/init machinery into PendingConfigure class
This commit is contained in:
@@ -214,11 +214,13 @@ def data(request):
|
|||||||
class PendingConfigure:
|
class PendingConfigure:
|
||||||
CONFIGURING = "CONFIGURING"
|
CONFIGURING = "CONFIGURING"
|
||||||
CONFIGURED = "CONFIGURED"
|
CONFIGURED = "CONFIGURED"
|
||||||
POSTPROCESSED = "POSTPROCESSED"
|
IDLEREADY = "IDLEREADY"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, init_time):
|
||||||
self._configured_events = Queue()
|
self._configured_events = Queue()
|
||||||
self._account2state = {}
|
self._account2state = {}
|
||||||
|
self._imap_cleaned = set()
|
||||||
|
self.init_time = init_time
|
||||||
|
|
||||||
def add_account(self, acc, reconfigure=False):
|
def add_account(self, acc, reconfigure=False):
|
||||||
class PendingTracker:
|
class PendingTracker:
|
||||||
@@ -231,34 +233,67 @@ class PendingConfigure:
|
|||||||
acc.configure(reconfigure=reconfigure)
|
acc.configure(reconfigure=reconfigure)
|
||||||
print("started configure on pending", acc)
|
print("started configure on pending", acc)
|
||||||
|
|
||||||
def wait_all(self, onconfigured=lambda x: None):
|
def wait_one_configured(self, account):
|
||||||
""" 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):
|
|
||||||
if self._account2state[account] == self.CONFIGURING:
|
if self._account2state[account] == self.CONFIGURING:
|
||||||
while 1:
|
while 1:
|
||||||
acc, success = self._pop_one()
|
acc = self._pop_config_success()
|
||||||
if acc == account:
|
if acc == account:
|
||||||
break
|
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()
|
acc, success = self._configured_events.get()
|
||||||
if not success:
|
if not success:
|
||||||
pytest.fail("configuring online account failed: {}".format(acc))
|
pytest.fail("configuring online account failed: {}".format(acc))
|
||||||
self._account2state[acc] = self.CONFIGURED
|
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:
|
class ACFactory:
|
||||||
@@ -275,8 +310,7 @@ class ACFactory:
|
|||||||
|
|
||||||
self._finalizers = []
|
self._finalizers = []
|
||||||
self._accounts = []
|
self._accounts = []
|
||||||
self._pending_configure = PendingConfigure()
|
self._pending_configure = PendingConfigure(self.init_time)
|
||||||
self._imap_cleaned = set()
|
|
||||||
self._preconfigured_keys = ["alice", "bob", "charlie",
|
self._preconfigured_keys = ["alice", "bob", "charlie",
|
||||||
"dom", "elena", "fiona"]
|
"dom", "elena", "fiona"]
|
||||||
self.set_logging_default(False)
|
self.set_logging_default(False)
|
||||||
@@ -382,29 +416,12 @@ class ACFactory:
|
|||||||
def new_cloned_configuring_account(self, account):
|
def new_cloned_configuring_account(self, account):
|
||||||
return self.new_online_configuring_account(cloned_from=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):
|
def wait_configured(self, acc):
|
||||||
self._pending_configure.wait_one(acc)
|
self._pending_configure.wait_one_configured(acc)
|
||||||
self.init_direct_imap_and_logging(acc)
|
|
||||||
acc._evtracker.consume_events()
|
|
||||||
|
|
||||||
def bring_accounts_online(self):
|
def bring_accounts_online(self):
|
||||||
print("bringing accounts online")
|
print("bringing accounts online")
|
||||||
self._pending_configure.wait_all(onconfigured=self._onconfigure_start_io)
|
self._pending_configure.bring_online()
|
||||||
print("all accounts online")
|
print("all accounts online")
|
||||||
|
|
||||||
def get_online_accounts(self, num):
|
def get_online_accounts(self, num):
|
||||||
@@ -447,22 +464,6 @@ class ACFactory:
|
|||||||
self._finalizers.append(bot.kill)
|
self._finalizers.append(bot.kill)
|
||||||
return bot
|
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):
|
def dump_imap_summary(self, logfile):
|
||||||
for ac in self._accounts:
|
for ac in self._accounts:
|
||||||
ac.dump_account_info(logfile=logfile)
|
ac.dump_account_info(logfile=logfile)
|
||||||
|
|||||||
@@ -2401,7 +2401,7 @@ class TestOnlineAccount:
|
|||||||
ac3.stop_io()
|
ac3.stop_io()
|
||||||
acfactory.remove_preconfigured_keys()
|
acfactory.remove_preconfigured_keys()
|
||||||
ac4 = acfactory.new_cloned_configuring_account(ac3)
|
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
|
# Create contacts to make sure incoming messages are not treated as contact requests
|
||||||
chat41 = ac4.create_chat(ac1)
|
chat41 = ac4.create_chat(ac1)
|
||||||
chat42 = ac4.create_chat(ac2)
|
chat42 = ac4.create_chat(ac2)
|
||||||
|
|||||||
@@ -12,21 +12,23 @@ from deltachat.testplugin import PendingConfigure
|
|||||||
|
|
||||||
class TestPendingConfigure:
|
class TestPendingConfigure:
|
||||||
def test_basic_states(self, acfactory, monkeypatch):
|
def test_basic_states(self, acfactory, monkeypatch):
|
||||||
pc = PendingConfigure()
|
pc = PendingConfigure(init_time=0.0)
|
||||||
acc = acfactory.get_unconfigured_account()
|
acc = acfactory.get_unconfigured_account()
|
||||||
monkeypatch.setattr(acc, "configure", lambda **kwargs: None)
|
monkeypatch.setattr(acc, "configure", lambda **kwargs: None)
|
||||||
pc.add_account(acc)
|
pc.add_account(acc)
|
||||||
assert pc._account2state[acc] == pc.CONFIGURING
|
assert pc._account2state[acc] == pc.CONFIGURING
|
||||||
pc._configured_events.put((acc, True))
|
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
|
assert pc._account2state[acc] == pc.CONFIGURED
|
||||||
accounts = []
|
monkeypatch.setattr(pc, "_onconfigure_start_io", lambda *args, **kwargs: None)
|
||||||
pc.wait_all(onconfigured=accounts.append)
|
pc.bring_online()
|
||||||
assert pc._account2state[acc] == pc.POSTPROCESSED
|
assert pc._account2state[acc] == pc.IDLEREADY
|
||||||
assert accounts == [acc]
|
|
||||||
|
|
||||||
def test_two_accounts_one_waited_all_started(self, monkeypatch, acfactory):
|
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()
|
ac1 = acfactory.get_unconfigured_account()
|
||||||
monkeypatch.setattr(ac1, "configure", lambda **kwargs: None)
|
monkeypatch.setattr(ac1, "configure", lambda **kwargs: None)
|
||||||
pc.add_account(ac1)
|
pc.add_account(ac1)
|
||||||
@@ -36,15 +38,13 @@ class TestPendingConfigure:
|
|||||||
assert pc._account2state[ac1] == pc.CONFIGURING
|
assert pc._account2state[ac1] == pc.CONFIGURING
|
||||||
assert pc._account2state[ac2] == pc.CONFIGURING
|
assert pc._account2state[ac2] == pc.CONFIGURING
|
||||||
pc._configured_events.put((ac1, True))
|
pc._configured_events.put((ac1, True))
|
||||||
pc.wait_one(ac1)
|
pc.wait_one_configured(ac1)
|
||||||
assert pc._account2state[ac1] == pc.CONFIGURED
|
assert pc._account2state[ac1] == pc.CONFIGURED
|
||||||
assert pc._account2state[ac2] == pc.CONFIGURING
|
assert pc._account2state[ac2] == pc.CONFIGURING
|
||||||
accounts = []
|
|
||||||
pc._configured_events.put((ac2, True))
|
pc._configured_events.put((ac2, True))
|
||||||
pc.wait_all(onconfigured=accounts.append)
|
pc.bring_online()
|
||||||
assert pc._account2state[ac1] == pc.POSTPROCESSED
|
assert pc._account2state[ac1] == pc.IDLEREADY
|
||||||
assert pc._account2state[ac2] == pc.POSTPROCESSED
|
assert pc._account2state[ac2] == pc.IDLEREADY
|
||||||
assert accounts == [ac1, ac2]
|
|
||||||
|
|
||||||
|
|
||||||
def test_empty_context():
|
def test_empty_context():
|
||||||
|
|||||||
Reference in New Issue
Block a user