diff --git a/python/src/deltachat/account.py b/python/src/deltachat/account.py index ff08cc237..0f18fcbe3 100644 --- a/python/src/deltachat/account.py +++ b/python/src/deltachat/account.py @@ -543,6 +543,10 @@ class Account(object): self._pm.check_pending() return plugin + def remove_account_plugin(self, plugin, name=None): + """ remove an account plugin. """ + self._pm.unregister(plugin, name=name) + @contextmanager def temp_plugin(self, plugin): """ run a with-block with the given plugin temporarily registered. """ @@ -569,22 +573,27 @@ class Account(object): :returns: None (account is configured and with io-scheduling running) """ if not self.is_configured(): - if not self.get_config("addr") or not self.get_config("mail_pw"): - raise MissingCredentials("addr or mail_pwd not set in config") - with self.temp_plugin(ConfigureTracker()) as config_tracker: - lib.dc_configure(self._dc_context) - config_tracker.wait_finish() + self.configure() + self.wait_configure_finish() lib.dc_context_run(self._dc_context) - @contextmanager def configure(self): - if self.is_configured(): - return + assert not self.is_configured() + assert not hasattr(self, "_configtracker") if not self.get_config("addr") or not self.get_config("mail_pw"): raise MissingCredentials("addr or mail_pwd not set in config") - with self.temp_plugin(ConfigureTracker()) as config_tracker: - lib.dc_configure(self._dc_context) - yield config_tracker + if hasattr(self, "_configtracker"): + self.remove_account_plugin(self._configtracker) + self._configtracker = ConfigureTracker() + self.add_account_plugin(self._configtracker) + lib.dc_configure(self._dc_context) + + def wait_configure_finish(self): + try: + self._configtracker.wait_finish() + finally: + self.remove_account_plugin(self._configtracker) + del self._configtracker def is_started(self): return self._event_thread.is_alive() and bool(lib.dc_is_running(self._dc_context)) diff --git a/python/src/deltachat/events.py b/python/src/deltachat/events.py index 9fc50ef56..bd23e3359 100644 --- a/python/src/deltachat/events.py +++ b/python/src/deltachat/events.py @@ -90,6 +90,13 @@ class FFIEventTracker: else: assert not rex.match(ev.name), "event found {}".format(ev) + def wait_securejoin_inviter_progress(self, target): + while 1: + event = self.get_matching("DC_EVENT_SECUREJOIN_INVITER_PROGRESS") + if event.data2 >= target: + print("** SECUREJOINT-INVITER PROGRESS {}".format(target), self.account) + break + def get_matching(self, event_name_regex, check_error=True, timeout=None): self.account.log("-- waiting for event with regex: {} --".format(event_name_regex)) rex = re.compile("(?:{}).*".format(event_name_regex)) diff --git a/python/src/deltachat/testplugin.py b/python/src/deltachat/testplugin.py index adce704d0..910db5c71 100644 --- a/python/src/deltachat/testplugin.py +++ b/python/src/deltachat/testplugin.py @@ -13,7 +13,6 @@ import pytest import requests from . import Account, const -from .tracker import ConfigureTracker from .capi import lib from .events import FFIEventLogger, FFIEventTracker from _pytest.monkeypatch import MonkeyPatch @@ -234,7 +233,6 @@ def acfactory(pytestconfig, tmpdir, request, session_liveconfig, data): def make_account(self, path, logid, quiet=False): ac = Account(path, logging=self._logging) ac._evtracker = ac.add_account_plugin(FFIEventTracker(ac)) - ac._configtracker = ac.add_account_plugin(ConfigureTracker()) if not quiet: ac.add_account_plugin(FFIEventLogger(ac, logid=logid)) self._accounts.append(ac) @@ -297,7 +295,7 @@ def acfactory(pytestconfig, tmpdir, request, session_liveconfig, data): return ac, dict(configdict) def get_online_configuring_account(self, mvbox=False, sentbox=False, move=False, - pre_generated_key=True, quiet=False, config={}, start=True): + pre_generated_key=True, quiet=False, config={}): ac, configdict = self.get_online_config( pre_generated_key=pre_generated_key, quiet=quiet) configdict.update(config) @@ -305,23 +303,20 @@ def acfactory(pytestconfig, tmpdir, request, session_liveconfig, data): configdict["mvbox_move"] = str(int(move)) configdict["sentbox_watch"] = str(int(sentbox)) ac.update_config(configdict) - if start: - ac.start() + ac.configure() return ac def get_one_online_account(self, pre_generated_key=True, mvbox=False, move=False): ac1 = self.get_online_configuring_account( pre_generated_key=pre_generated_key, mvbox=mvbox, move=move) - ac1._configtracker.wait_imap_connected() - ac1._configtracker.wait_smtp_connected() - ac1._configtracker.wait_finish() + ac1.wait_configure_finish() return ac1 def get_two_online_accounts(self, move=False, quiet=False): ac1 = self.get_online_configuring_account(move=True, quiet=quiet) ac2 = self.get_online_configuring_account(quiet=quiet) - ac1._configtracker.wait_finish() - ac2._configtracker.wait_finish() + ac1.wait_configure_finish() + ac2.wait_configure_finish() return ac1, ac2 def clone_online_account(self, account, pre_generated_key=True): @@ -339,7 +334,7 @@ def acfactory(pytestconfig, tmpdir, request, session_liveconfig, data): mvbox_move=account.get_config("mvbox_move"), sentbox_watch=account.get_config("sentbox_watch"), )) - ac.start() + ac.configure() return ac def run_bot_process(self, module, ffi=True): diff --git a/python/tests/conftest.py b/python/tests/conftest.py deleted file mode 100644 index 6cc65dc14..000000000 --- a/python/tests/conftest.py +++ /dev/null @@ -1,18 +0,0 @@ -from __future__ import print_function - - -def wait_configuration_progress(account, min_target, max_target=1001, check_error=True): - min_target = min(min_target, max_target) - while 1: - event = account._evtracker.get_matching("DC_EVENT_CONFIGURE_PROGRESS") - if event.data1 >= min_target and event.data1 <= max_target: - print("** CONFIG PROGRESS {}".format(min_target), account) - break - - -def wait_securejoin_inviter_progress(account, target): - while 1: - event = account._evtracker.get_matching("DC_EVENT_SECUREJOIN_INVITER_PROGRESS") - if event.data2 >= target: - print("** SECUREJOINT-INVITER PROGRESS {}".format(target), account) - break diff --git a/python/tests/test_account.py b/python/tests/test_account.py index 283a619af..0cd14a9cc 100644 --- a/python/tests/test_account.py +++ b/python/tests/test_account.py @@ -3,13 +3,10 @@ import pytest import os import queue import time -from deltachat import const, Account, capi +from deltachat import const, Account from deltachat.message import Message from deltachat.hookspec import account_hookimpl -from deltachat.tracker import ConfigureTracker from datetime import datetime, timedelta -from conftest import (wait_configuration_progress, - wait_securejoin_inviter_progress) @pytest.mark.parametrize("msgtext,res", [ @@ -535,8 +532,8 @@ class TestOnlineAccount: ) # rsa key gen can be slow especially on CI, adjust timeout ac1._evtracker.set_timeout(120) - wait_configuration_progress(ac1, 1000) - wait_configuration_progress(ac2, 1000) + ac1.wait_configure_finish() + ac2.wait_configure_finish() chat = self.get_chat(ac1, ac2, both_created=True) lp.sec("ac1: send unencrypted message to ac2") @@ -564,12 +561,13 @@ class TestOnlineAccount: assert msg3_in.is_encrypted() def test_configure_canceled(self, acfactory): - ac1 = acfactory.get_online_configuring_account(start=False) - with ac1.temp_plugin(ConfigureTracker()) as config_tracker: - capi.lib.dc_configure(ac1._dc_context) - config_tracker.wait_progress() - ac1.stop_ongoing() - config_tracker.wait_finish() + ac1 = acfactory.get_online_configuring_account() + ac1._configtracker.wait_progress() + ac1.stop_ongoing() + try: + ac1.wait_configure_finish() + except ac1._configtracker.ConfigureFailed: + pass def test_export_import_self_keys(self, acfactory, tmpdir): ac1, ac2 = acfactory.get_two_online_accounts() @@ -590,9 +588,9 @@ class TestOnlineAccount: # are copied to it via BCC. ac1_clone = acfactory.clone_online_account(ac1) - wait_configuration_progress(ac1, 1000) - wait_configuration_progress(ac2, 1000) - wait_configuration_progress(ac1_clone, 1000) + ac1.wait_configure_finish() + ac2.wait_configure_finish() + ac1_clone.wait_configure_finish() chat = self.get_chat(ac1, ac2) @@ -696,10 +694,10 @@ class TestOnlineAccount: ac2 = acfactory.get_online_configuring_account() lp.sec("ac2: waiting for configuration") - wait_configuration_progress(ac2, 1000) + ac2.wait_configure_finish() lp.sec("ac1: waiting for configuration") - wait_configuration_progress(ac1, 1000) + ac1.wait_configure_finish() lp.sec("ac1: send message and wait for ac2 to receive it") chat = self.get_chat(ac1, ac2) @@ -711,8 +709,8 @@ class TestOnlineAccount: def test_move_works(self, acfactory): ac1 = acfactory.get_online_configuring_account() ac2 = acfactory.get_online_configuring_account(mvbox=True, move=True) - wait_configuration_progress(ac2, 1000) - wait_configuration_progress(ac1, 1000) + ac2.wait_configure_finish() + ac1.wait_configure_finish() chat = self.get_chat(ac1, ac2) chat.send_text("message1") ev = ac2._evtracker.get_matching("DC_EVENT_INCOMING_MSG|DC_EVENT_MSGS_CHANGED") @@ -723,8 +721,8 @@ class TestOnlineAccount: ac1 = acfactory.get_online_configuring_account(mvbox=True, move=True) ac1.set_config("bcc_self", "1") ac2 = acfactory.get_online_configuring_account() - wait_configuration_progress(ac2, 1000) - wait_configuration_progress(ac1, 1000) + ac2.wait_configure_finish() + ac1.wait_configure_finish() chat = self.get_chat(ac1, ac2) chat.send_text("message1") chat.send_text("message2") @@ -1102,8 +1100,7 @@ class TestOnlineAccount: assert m == msg_in def test_import_export_online_all(self, acfactory, tmpdir, lp): - ac1 = acfactory.get_online_configuring_account() - wait_configuration_progress(ac1, 1000) + ac1 = acfactory.get_one_online_account() lp.sec("create some chat content") contact1 = ac1.create_contact("some1@hello.com", name="some1") @@ -1151,8 +1148,8 @@ class TestOnlineAccount: # as of Jul2019 ac1 = acfactory.get_online_configuring_account() ac2 = acfactory.clone_online_account(ac1) - wait_configuration_progress(ac2, 1000) - wait_configuration_progress(ac1, 1000) + ac2.wait_configure_finish() + ac1.wait_configure_finish() lp.sec("trigger ac setup message and return setupcode") assert ac1.get_info()["fingerprint"] != ac2.get_info()["fingerprint"] @@ -1175,8 +1172,8 @@ class TestOnlineAccount: ac1 = acfactory.get_online_configuring_account() ac2 = acfactory.clone_online_account(ac1) ac2._evtracker.set_timeout(30) - wait_configuration_progress(ac2, 1000) - wait_configuration_progress(ac1, 1000) + ac2.wait_configure_finish() + ac1.wait_configure_finish() lp.sec("trigger ac setup message but ignore") assert ac1.get_info()["fingerprint"] != ac2.get_info()["fingerprint"] @@ -1202,7 +1199,7 @@ class TestOnlineAccount: lp.sec("ac2: start QR-code based setup contact protocol") ch = ac2.qr_setup_contact(qr) assert ch.id >= 10 - wait_securejoin_inviter_progress(ac1, 1000) + ac1._evtracker.wait_securejoin_inviter_progress(1000) def test_qr_join_chat(self, acfactory, lp): ac1, ac2 = acfactory.get_two_online_accounts() @@ -1216,7 +1213,7 @@ class TestOnlineAccount: # check that at least some of the handshake messages are deleted ac1._evtracker.get_matching("DC_EVENT_IMAP_MESSAGE_DELETED") ac2._evtracker.get_matching("DC_EVENT_IMAP_MESSAGE_DELETED") - wait_securejoin_inviter_progress(ac1, 1000) + ac1._evtracker.wait_securejoin_inviter_progress(1000) def test_qr_verified_group_and_chatting(self, acfactory, lp): ac1, ac2 = acfactory.get_two_online_accounts() @@ -1227,7 +1224,7 @@ class TestOnlineAccount: lp.sec("ac2: start QR-code based join-group protocol") chat2 = ac2.qr_join_chat(qr) assert chat2.id >= 10 - wait_securejoin_inviter_progress(ac1, 1000) + ac1._evtracker.wait_securejoin_inviter_progress(1000) lp.sec("ac2: read member added message") msg = ac2._evtracker.wait_next_incoming_message() @@ -1487,7 +1484,7 @@ class TestGroupStressTests: lp.sec("creating and configuring five accounts") accounts = [acfactory.get_online_configuring_account() for i in range(5)] for acc in accounts: - wait_configuration_progress(acc, 1000) + acc.wait_configure_finish() ac1 = accounts.pop() lp.sec("ac1: setting up contacts with 4 other members") @@ -1591,7 +1588,7 @@ class TestGroupStressTests: lp.sec("creating and configuring five accounts") accounts = [acfactory.get_online_configuring_account() for i in range(3)] for acc in accounts: - wait_configuration_progress(acc, 1000) + acc.wait_configure_finish() ac1 = accounts.pop() lp.sec("ac1: setting up contacts with 2 other members") @@ -1660,27 +1657,26 @@ class TestOnlineConfigureFails: ac1, configdict = acfactory.get_online_config() ac1.update_config(dict(addr=configdict["addr"], mail_pw="123")) - with ac1.configure() as tracker: - tracker.wait_progress(500) - tracker.wait_progress(0) + ac1.configure() + ac1._configtracker.wait_progress(500) + ac1._configtracker.wait_progress(0) ev = ac1._evtracker.get_matching("DC_EVENT_ERROR_NETWORK") assert "cannot login" in ev.data2.lower() def test_invalid_user(self, acfactory): ac1, configdict = acfactory.get_online_config() ac1.update_config(dict(addr="x" + configdict["addr"], mail_pw=configdict["mail_pw"])) - with ac1.configure() as tracker: - tracker.wait_progress(500) - tracker.wait_progress(0) + ac1.configure() + ac1._configtracker.wait_progress(500) + ac1._configtracker.wait_progress(0) ev = ac1._evtracker.get_matching("DC_EVENT_ERROR_NETWORK") assert "cannot login" in ev.data2.lower() def test_invalid_domain(self, acfactory): ac1, configdict = acfactory.get_online_config() ac1.update_config((dict(addr=configdict["addr"] + "x", mail_pw=configdict["mail_pw"]))) - with ac1.configure() as tracker: - tracker.wait_progress(500) - tracker.wait_progress(0) - wait_configuration_progress(ac1, 500) + ac1.configure() + ac1._configtracker.wait_progress(500) + ac1._configtracker.wait_progress(0) ev = ac1._evtracker.get_matching("DC_EVENT_ERROR_NETWORK") assert "could not connect" in ev.data2.lower() diff --git a/python/tests/test_increation.py b/python/tests/test_increation.py index 6fb96e1fe..34b9050b0 100644 --- a/python/tests/test_increation.py +++ b/python/tests/test_increation.py @@ -6,24 +6,24 @@ import shutil import pytest from filecmp import cmp -from conftest import wait_configuration_progress from deltachat import const def wait_msgs_changed(account, chat_id, msg_id=None): - ev = account._evtracker.get_matching("DC_EVENT_MSGS_CHANGED") - assert ev.data1 == chat_id - if msg_id is not None: - assert ev.data2 == msg_id - return ev.data2 + account.log("waiting for chat_id={} msg_id={}".format(chat_id, msg_id)) + while 1: + ev = account._evtracker.get_matching("DC_EVENT_MSGS_CHANGED") + if ev.data1 != chat_id: + account.log("waiting got mismatched DC_EVENT_MSGS_CHANGED") + continue + if msg_id is not None: + assert ev.data2 == msg_id + return ev.data2 class TestOnlineInCreation: def test_increation_not_blobdir(self, tmpdir, acfactory, lp): - ac1 = acfactory.get_online_configuring_account() - ac2 = acfactory.get_online_configuring_account() - wait_configuration_progress(ac1, 1000) - wait_configuration_progress(ac2, 1000) + ac1, ac2 = acfactory.get_two_online_accounts() c2 = ac1.create_contact(email=ac2.get_config("addr")) chat = ac1.create_chat_by_contact(c2) @@ -35,10 +35,7 @@ class TestOnlineInCreation: chat.prepare_message_file(src.strpath) def test_no_increation_copies_to_blobdir(self, tmpdir, acfactory, lp): - ac1 = acfactory.get_online_configuring_account() - ac2 = acfactory.get_online_configuring_account() - wait_configuration_progress(ac1, 1000) - wait_configuration_progress(ac2, 1000) + ac1, ac2 = acfactory.get_two_online_accounts() c2 = ac1.create_contact(email=ac2.get_config("addr")) chat = ac1.create_chat_by_contact(c2) @@ -53,10 +50,7 @@ class TestOnlineInCreation: assert os.path.exists(blob_src), "file.txt not copied to blobdir" def test_forward_increation(self, acfactory, data, lp): - ac1 = acfactory.get_online_configuring_account() - ac2 = acfactory.get_online_configuring_account() - wait_configuration_progress(ac1, 1000) - wait_configuration_progress(ac2, 1000) + ac1, ac2 = acfactory.get_two_online_accounts() c2 = ac1.create_contact(email=ac2.get_config("addr")) chat = ac1.create_chat_by_contact(c2)