This commit is contained in:
holger krekel
2022-05-06 11:51:25 +02:00
parent 7557f0d35e
commit b1fc906ec0
3 changed files with 74 additions and 40 deletions

View File

@@ -282,6 +282,10 @@ class ACSetup:
def start_configure(self, account, reconfigure=False): def start_configure(self, account, reconfigure=False):
""" add an account and start its configure process. """ """ add an account and start its configure process. """
if reconfigure:
assert account.is_configured()
class PendingTracker: class PendingTracker:
@account_hookimpl @account_hookimpl
def ac_configure_completed(this, success): def ac_configure_completed(this, success):
@@ -290,7 +294,7 @@ class ACSetup:
account.add_account_plugin(PendingTracker(), name="pending_tracker") account.add_account_plugin(PendingTracker(), name="pending_tracker")
self._account2state[account] = self.CONFIGURING self._account2state[account] = self.CONFIGURING
account.configure(reconfigure=reconfigure) account.configure(reconfigure=reconfigure)
self.log("started configure on", account) self.log("started {}configure on".format("re-" if reconfigure else ""), account)
def wait_one_configured(self, account): def wait_one_configured(self, account):
""" wait until this account has successfully configured. """ """ wait until this account has successfully configured. """
@@ -303,6 +307,11 @@ class ACSetup:
self.init_logging(acc) self.init_logging(acc)
acc._evtracker.consume_events() acc._evtracker.consume_events()
def wait_all_configured(self):
""" Wait for all unconfigured accounts to become finished. """
while self.CONFIGURING in self._account2state.values():
self._pop_config_success()
def bring_online(self): def bring_online(self):
""" Wait for all accounts to become ready to receive messages. """ Wait for all accounts to become ready to receive messages.
@@ -417,7 +426,7 @@ class ACFactory:
assert "addr" in configdict and "mail_pw" in configdict assert "addr" in configdict and "mail_pw" in configdict
return configdict return configdict
def _get_cached_account(self, addr): def _get_cached_account_copy(self, addr):
if addr in self.testprocess._addr2files: if addr in self.testprocess._addr2files:
return self._getaccount(addr) return self._getaccount(addr)
@@ -426,6 +435,7 @@ class ACFactory:
def _getaccount(self, try_cache_addr=None): def _getaccount(self, try_cache_addr=None):
logid = "ac{}".format(len(self._accounts) + 1) logid = "ac{}".format(len(self._accounts) + 1)
# we need to use fixed database basename for maybe_cache_* functions to work # we need to use fixed database basename for maybe_cache_* functions to work
path = self.tmpdir.mkdir(logid).join("dc.db") path = self.tmpdir.mkdir(logid).join("dc.db")
if try_cache_addr: if try_cache_addr:
@@ -473,23 +483,41 @@ class ACFactory:
self._acsetup.init_logging(ac) self._acsetup.init_logging(ac)
return ac return ac
# XXX deprecate the next function?
def new_online_configuring_account(self, cache=False, **kwargs): def new_online_configuring_account(self, cache=False, **kwargs):
configdict = self.get_next_liveconfig() configdict = self.get_next_liveconfig()
configdict.update(kwargs) configdict.update(kwargs)
return self._setup_online_configuring_account(configdict) return self._setup_online_configuring_account(configdict, cache=cache)
def get_online_second_device(self, ac1, **kwargs):
ac2 = self._get_cached_account_copy(addr=ac1.get_config("addr"))
if ac2 is None:
# some tests setup the primary account without causing caching.
configdict = kwargs.copy()
configdict["addr"] = ac1.get_config("addr")
configdict["mail_pw"] = ac1.get_config("mail_pw")
ac2 = self._setup_online_configuring_account(configdict, cache=False)
elif kwargs:
ac2.update_config(kwargs)
self._acsetup.add_configured(ac2)
def get_online_second_device(self, ac1):
ac1 = self._get_cached_account(addr=ac1.get_config("addr"))
self.bring_accounts_online() self.bring_accounts_online()
return ac1 return ac2
def get_online_multidevice_setup(self, copied=True): def get_online_multidevice_setup(self, copied=True):
ac1 = self.get_online_accounts(1) """ Provide two accounts. The second uses the same credentials
and if copied is True, also the same database and blobs.
You can use copy=False to get a typical configuration where
a user unsuspectingly sets up a second device and expects it to
"just work" not knowing that an export/import is required.
"""
ac1, = self.get_online_accounts(1)
if copied: if copied:
ac2 = self._get_cached_account(addr=ac1.get_config("addr")) ac2 = self._get_cached_account_copy(addr=ac1.get_config("addr"))
self._acsetup.add_configured(ac2)
else: else:
configdict = dict(addr=ac1.get_config("addr"), mail_pw=ac1.get_config("mail_pw")) config2 = dict(addr=ac1.get_config("addr"), mail_pw=ac1.get_config("mail_pw"))
ac2 = self._setup_online_configuring_account(configdict, cache=False) ac2 = self._setup_online_configuring_account(config2, cache=False)
self.bring_accounts_online() self.bring_accounts_online()
return ac1, ac2 return ac1, ac2
@@ -497,7 +525,7 @@ class ACFactory:
return self.get_next_liveconfig()["addr"] return self.get_next_liveconfig()["addr"]
def _setup_online_configuring_account(self, configdict, cache=False): def _setup_online_configuring_account(self, configdict, cache=False):
ac = self._get_cached_account(addr=configdict["addr"]) if cache else None ac = self._get_cached_account_copy(configdict["addr"]) if cache else None
if ac is not None: if ac is not None:
# make sure we consume a preconfig key, as if we had created a fresh account # make sure we consume a preconfig key, as if we had created a fresh account
self._preconfigured_keys.pop(0) self._preconfigured_keys.pop(0)
@@ -526,10 +554,26 @@ class ACFactory:
self._acsetup.bring_online() self._acsetup.bring_online()
print("all accounts online") print("all accounts online")
def get_online_configured_accounts(self, configlist):
accounts = [self.new_online_configuring_account(cache=True, **config)
for config in configlist]
self._acsetup.wait_all_configured()
for acc in accounts:
self._acsetup.init_imap(acc)
return accounts
def force_reconfigure(self, account):
self._acsetup.start_configure(account, reconfigure=True)
def get_online_accounts(self, num): def get_online_accounts(self, num):
""" Return a list of configured and started Accounts.
This function creates plain online accounts and fill
a testprocess-scoped cache and re-use these plain accounts
on the next test function.
"""
accounts = [self.new_online_configuring_account(cache=True) for i in range(num)] accounts = [self.new_online_configuring_account(cache=True) for i in range(num)]
self.bring_accounts_online() self.bring_accounts_online()
# we cache fully configured and started accounts
for acc in accounts: for acc in accounts:
self.testprocess.cache_maybe_store_configured_db_files(acc) self.testprocess.cache_maybe_store_configured_db_files(acc)
return accounts return accounts
@@ -575,7 +619,7 @@ class ACFactory:
if imap is not None: if imap is not None:
imap.dump_imap_structures(self.tmpdir, logfile=logfile) imap.dump_imap_structures(self.tmpdir, logfile=logfile)
def get_accepted_chat(self, ac1: Account, ac2: Account): def get_accepted_chat(self, ac1: Account, ac2):
ac2.create_chat(ac1) ac2.create_chat(ac1)
return ac1.create_chat(ac2) return ac1.create_chat(ac2)

View File

@@ -192,9 +192,7 @@ def test_fetch_existing(acfactory, lp, mvbox_move):
if mvbox_move: if mvbox_move:
assert ac.get_config("configured_mvbox_folder") assert ac.get_config("configured_mvbox_folder")
ac1 = acfactory.new_online_configuring_account(mvbox_move=mvbox_move) ac1, ac2 = acfactory.get_online_configured_accounts([dict(mvbox_move=mvbox_move), dict()])
ac2 = acfactory.new_online_configuring_account()
acfactory.wait_configured(ac1)
ac1.direct_imap.create_folder("Sent") ac1.direct_imap.create_folder("Sent")
ac1.set_config("sentbox_watch", "1") ac1.set_config("sentbox_watch", "1")
@@ -203,8 +201,9 @@ def test_fetch_existing(acfactory, lp, mvbox_move):
# would also find the "Sent" folder, but it would be too late: # would also find the "Sent" folder, but it would be too late:
# The sentbox thread, started by `start_io()`, would have seen that there is no # The sentbox thread, started by `start_io()`, would have seen that there is no
# ConfiguredSentboxFolder and do nothing. # ConfiguredSentboxFolder and do nothing.
acfactory._acsetup.start_configure(ac1, reconfigure=True) acfactory.force_reconfigure(ac1)
acfactory.bring_accounts_online() acfactory.bring_accounts_online()
assert_folders_configured(ac1) assert_folders_configured(ac1)
assert ac1.direct_imap.select_config_folder("mvbox" if mvbox_move else "inbox") assert ac1.direct_imap.select_config_folder("mvbox" if mvbox_move else "inbox")
@@ -220,7 +219,7 @@ def test_fetch_existing(acfactory, lp, mvbox_move):
assert_folders_configured(ac1) assert_folders_configured(ac1)
lp.sec("create a cloned ac1 and fetch contact history during configure") lp.sec("create a cloned ac1 and fetch contact history during configure")
ac1_clone = acfactory.get_online_second_device(fetch_existing_msgs=1) ac1_clone = acfactory.get_online_second_device(ac1, fetch_existing_msgs=1)
assert_folders_configured(ac1_clone) assert_folders_configured(ac1_clone)
lp.sec("check that ac2 contact was fetchted during configure") lp.sec("check that ac2 contact was fetchted during configure")
@@ -245,10 +244,7 @@ def test_fetch_existing_msgs_group_and_single(acfactory, lp):
So, after fetch-existing-msgs you have one contact request and one chat with the same person. So, after fetch-existing-msgs you have one contact request and one chat with the same person.
See https://github.com/deltachat/deltachat-core-rust/issues/2097""" See https://github.com/deltachat/deltachat-core-rust/issues/2097"""
ac1 = acfactory.new_online_configuring_account() ac1, ac2 = acfactory.get_online_accounts(2)
ac2 = acfactory.new_online_configuring_account()
acfactory.bring_accounts_online()
lp.sec("receive a message") lp.sec("receive a message")
ac2.create_group_chat("group name", contacts=[ac1]).send_text("incoming, unencrypted group message") ac2.create_group_chat("group name", contacts=[ac1]).send_text("incoming, unencrypted group message")
@@ -263,7 +259,7 @@ def test_fetch_existing_msgs_group_and_single(acfactory, lp):
assert idle1.wait_for_seen() assert idle1.wait_for_seen()
lp.sec("Clone online account and let it fetch the existing messages") lp.sec("Clone online account and let it fetch the existing messages")
ac1_clone = acfactory.get_online_second_device(fetch_existing_msgs=1) ac1_clone = acfactory.get_online_second_device(ac1, fetch_existing_msgs=1)
chats = ac1_clone.get_chats() chats = ac1_clone.get_chats()
assert len(chats) == 4 # two newly created chats + self-chat + device-chat assert len(chats) == 4 # two newly created chats + self-chat + device-chat
@@ -276,8 +272,8 @@ def test_fetch_existing_msgs_group_and_single(acfactory, lp):
assert len(group_messages) == 1 assert len(group_messages) == 1
assert group_messages[0].text == "incoming, unencrypted group message" assert group_messages[0].text == "incoming, unencrypted group message"
private_messages = private_chat.get_messages() private_messages = private_chat.get_messages()
# We can't decrypt the message in this chat, so the chat is empty: assert len(private_messages) == 1
assert len(private_messages) == 0 assert private_messages[0].text.startswith("outgoing, encrypted")
def test_undecipherable_group(acfactory, lp): def test_undecipherable_group(acfactory, lp):
@@ -413,7 +409,8 @@ def test_ephemeral_timer(acfactory, lp):
def test_multidevice_sync_seen(acfactory, lp): def test_multidevice_sync_seen(acfactory, lp):
"""Test that message marked as seen on one device is marked as seen on another.""" """Test that message marked as seen on one device is marked as seen on another."""
ac1, ac2 = acfactory.get_online_multidevice_setup() ac1, ac1_clone = acfactory.get_online_multidevice_setup()
ac2, = acfactory.get_online_accounts(1)
ac1.set_config("bcc_self", "1") ac1.set_config("bcc_self", "1")
ac1_clone.set_config("bcc_self", "1") ac1_clone.set_config("bcc_self", "1")

View File

@@ -92,13 +92,13 @@ def test_export_import_self_keys(acfactory, tmpdir, lp):
def test_one_account_send_bcc_setting(acfactory, lp): def test_one_account_send_bcc_setting(acfactory, lp):
ac1, ac1_clone = acfactory.get_online_multidevice_setup() ac1, ac1_clone = acfactory.get_online_multidevice_setup(copied=False)
ac2, = acfactory.get_online_accounts(1)
# test if sent messages are copied to it via BCC. # test if sent messages are copied to it via BCC.
chat = acfactory.get_accepted_chat(ac1, ac2) chat = acfactory.get_accepted_chat(ac1, ac2)
self_addr = ac1.get_config("addr") self_addr = ac1.get_config("addr")
other_addr = acfactory.get_online_devnull_email() ac2_addr = ac2.get_config("addr")
lp.sec("send out message without bcc to ourselves") lp.sec("send out message without bcc to ourselves")
ac1.set_config("bcc_self", "0") ac1.set_config("bcc_self", "0")
@@ -109,9 +109,9 @@ def test_one_account_send_bcc_setting(acfactory, lp):
ev = ac1._evtracker.get_matching("DC_EVENT_SMTP_MESSAGE_SENT") ev = ac1._evtracker.get_matching("DC_EVENT_SMTP_MESSAGE_SENT")
assert ac1.get_config("bcc_self") == "0" assert ac1.get_config("bcc_self") == "0"
# make sure we are not sending message to ourselves # make sure we are NOT sending message to ourselves
assert self_addr not in ev.data2 assert self_addr not in ev.data2
assert other_addr in ev.data2 assert ac2_addr in ev.data2
lp.sec("ac1: setting bcc_self=1") lp.sec("ac1: setting bcc_self=1")
ac1.set_config("bcc_self", "1") ac1.set_config("bcc_self", "1")
@@ -126,7 +126,7 @@ def test_one_account_send_bcc_setting(acfactory, lp):
# now make sure we are sending message to ourselves too # now make sure we are sending message to ourselves too
assert self_addr in ev.data2 assert self_addr in ev.data2
assert other_addr in ev.data2 assert ac2_addr in ev.data2
assert idle1.wait_for_seen() assert idle1.wait_for_seen()
# Second client receives only second message, but not the first # Second client receives only second message, but not the first
@@ -861,17 +861,11 @@ def test_dont_show_emails(acfactory, lp):
def test_no_old_msg_is_fresh(acfactory, lp): def test_no_old_msg_is_fresh(acfactory, lp):
ac1, ac1_clone = acfactory.get_online_multidevice_setup() ac1, ac1_clone = acfactory.get_online_multidevice_setup()
ac2 = acfactory.get_online_accounts(1) ac2, = acfactory.get_online_accounts(1)
#ac1.set_config("e2ee_enabled", "0")
#ac1_clone.set_config("e2ee_enabled", "0")
#ac2.set_config("e2ee_enabled", "0")
ac1_clone.set_config("bcc_self", "1") ac1_clone.set_config("bcc_self", "1")
ac1.create_chat(ac2) ac1.create_chat(ac2)
ac1_clone.create_chat(ac2) ac1_clone.create_chat(ac2)
ac1.get_device_chat().mark_noticed() ac1.get_device_chat().mark_noticed()
lp.sec("Send a first message from ac2 to ac1 and check that it's 'fresh'") lp.sec("Send a first message from ac2 to ac1 and check that it's 'fresh'")
@@ -883,7 +877,6 @@ def test_no_old_msg_is_fresh(acfactory, lp):
lp.sec("Send a message from ac1_clone to ac2 and check that ac1 marks the first message as 'noticed'") lp.sec("Send a message from ac1_clone to ac2 and check that ac1 marks the first message as 'noticed'")
ac1_clone.create_chat(ac2).send_text("Hi back") ac1_clone.create_chat(ac2).send_text("Hi back")
ev = ac1._evtracker.get_matching("DC_EVENT_MSGS_NOTICED") ev = ac1._evtracker.get_matching("DC_EVENT_MSGS_NOTICED")
assert ev.data1 == first_msg_id.chat.id assert ev.data1 == first_msg_id.chat.id
assert ac1.create_chat(ac2).count_fresh_messages() == 0 assert ac1.create_chat(ac2).count_fresh_messages() == 0
assert len(list(ac1.get_fresh_messages())) == 0 assert len(list(ac1.get_fresh_messages())) == 0