From b1fc906ec0179612ca38dbaf9295fbe41db46e8b Mon Sep 17 00:00:00 2001 From: holger krekel Date: Fri, 6 May 2022 11:51:25 +0200 Subject: [PATCH] snap --- python/src/deltachat/testplugin.py | 70 +++++++++++++++++++++----- python/tests/test_0_complex_or_slow.py | 23 ++++----- python/tests/test_1_online.py | 21 +++----- 3 files changed, 74 insertions(+), 40 deletions(-) diff --git a/python/src/deltachat/testplugin.py b/python/src/deltachat/testplugin.py index 3c767142b..c8335e752 100644 --- a/python/src/deltachat/testplugin.py +++ b/python/src/deltachat/testplugin.py @@ -282,6 +282,10 @@ class ACSetup: def start_configure(self, account, reconfigure=False): """ add an account and start its configure process. """ + + if reconfigure: + assert account.is_configured() + class PendingTracker: @account_hookimpl def ac_configure_completed(this, success): @@ -290,7 +294,7 @@ class ACSetup: account.add_account_plugin(PendingTracker(), name="pending_tracker") self._account2state[account] = self.CONFIGURING 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): """ wait until this account has successfully configured. """ @@ -303,6 +307,11 @@ class ACSetup: self.init_logging(acc) 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): """ 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 return configdict - def _get_cached_account(self, addr): + def _get_cached_account_copy(self, addr): if addr in self.testprocess._addr2files: return self._getaccount(addr) @@ -426,6 +435,7 @@ class ACFactory: def _getaccount(self, try_cache_addr=None): logid = "ac{}".format(len(self._accounts) + 1) + # we need to use fixed database basename for maybe_cache_* functions to work path = self.tmpdir.mkdir(logid).join("dc.db") if try_cache_addr: @@ -473,23 +483,41 @@ class ACFactory: self._acsetup.init_logging(ac) return ac + # XXX deprecate the next function? def new_online_configuring_account(self, cache=False, **kwargs): configdict = self.get_next_liveconfig() 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() - return ac1 + return ac2 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: - 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: - configdict = dict(addr=ac1.get_config("addr"), mail_pw=ac1.get_config("mail_pw")) - ac2 = self._setup_online_configuring_account(configdict, cache=False) + config2 = dict(addr=ac1.get_config("addr"), mail_pw=ac1.get_config("mail_pw")) + ac2 = self._setup_online_configuring_account(config2, cache=False) self.bring_accounts_online() return ac1, ac2 @@ -497,7 +525,7 @@ class ACFactory: return self.get_next_liveconfig()["addr"] 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: # make sure we consume a preconfig key, as if we had created a fresh account self._preconfigured_keys.pop(0) @@ -526,10 +554,26 @@ class ACFactory: self._acsetup.bring_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): + """ 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)] self.bring_accounts_online() - # we cache fully configured and started accounts for acc in accounts: self.testprocess.cache_maybe_store_configured_db_files(acc) return accounts @@ -575,7 +619,7 @@ class ACFactory: if imap is not None: 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) return ac1.create_chat(ac2) diff --git a/python/tests/test_0_complex_or_slow.py b/python/tests/test_0_complex_or_slow.py index c63ee3896..60cd9c0a2 100644 --- a/python/tests/test_0_complex_or_slow.py +++ b/python/tests/test_0_complex_or_slow.py @@ -192,9 +192,7 @@ def test_fetch_existing(acfactory, lp, mvbox_move): if mvbox_move: assert ac.get_config("configured_mvbox_folder") - ac1 = acfactory.new_online_configuring_account(mvbox_move=mvbox_move) - ac2 = acfactory.new_online_configuring_account() - acfactory.wait_configured(ac1) + ac1, ac2 = acfactory.get_online_configured_accounts([dict(mvbox_move=mvbox_move), dict()]) ac1.direct_imap.create_folder("Sent") 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: # The sentbox thread, started by `start_io()`, would have seen that there is no # ConfiguredSentboxFolder and do nothing. - acfactory._acsetup.start_configure(ac1, reconfigure=True) + acfactory.force_reconfigure(ac1) acfactory.bring_accounts_online() + assert_folders_configured(ac1) 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) 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) 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. See https://github.com/deltachat/deltachat-core-rust/issues/2097""" - ac1 = acfactory.new_online_configuring_account() - ac2 = acfactory.new_online_configuring_account() - - acfactory.bring_accounts_online() + ac1, ac2 = acfactory.get_online_accounts(2) lp.sec("receive a 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() 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() 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 group_messages[0].text == "incoming, unencrypted group message" private_messages = private_chat.get_messages() - # We can't decrypt the message in this chat, so the chat is empty: - assert len(private_messages) == 0 + assert len(private_messages) == 1 + assert private_messages[0].text.startswith("outgoing, encrypted") def test_undecipherable_group(acfactory, lp): @@ -413,7 +409,8 @@ def test_ephemeral_timer(acfactory, lp): def test_multidevice_sync_seen(acfactory, lp): """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_clone.set_config("bcc_self", "1") diff --git a/python/tests/test_1_online.py b/python/tests/test_1_online.py index 8844054a6..2fb3468f9 100644 --- a/python/tests/test_1_online.py +++ b/python/tests/test_1_online.py @@ -92,13 +92,13 @@ def test_export_import_self_keys(acfactory, tmpdir, 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. - chat = acfactory.get_accepted_chat(ac1, ac2) 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") 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") 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 other_addr in ev.data2 + assert ac2_addr in ev.data2 lp.sec("ac1: setting 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 assert self_addr in ev.data2 - assert other_addr in ev.data2 + assert ac2_addr in ev.data2 assert idle1.wait_for_seen() # 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): ac1, ac1_clone = acfactory.get_online_multidevice_setup() - 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") + ac2, = acfactory.get_online_accounts(1) ac1_clone.set_config("bcc_self", "1") - ac1.create_chat(ac2) ac1_clone.create_chat(ac2) - ac1.get_device_chat().mark_noticed() 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'") ac1_clone.create_chat(ac2).send_text("Hi back") ev = ac1._evtracker.get_matching("DC_EVENT_MSGS_NOTICED") - assert ev.data1 == first_msg_id.chat.id assert ac1.create_chat(ac2).count_fresh_messages() == 0 assert len(list(ac1.get_fresh_messages())) == 0