diff --git a/python/tests/conftest.py b/python/conftest.py similarity index 81% rename from python/tests/conftest.py rename to python/conftest.py index 9caf9dbc..83edbcc1 100644 --- a/python/tests/conftest.py +++ b/python/conftest.py @@ -1,17 +1,17 @@ import pytest +import re +import threading from deltachat import Account def pytest_addoption(parser): parser.addoption( "--liveconfig", action="store", default=None, - help="a file with >=2 lines where each line contains NAME=VALUE config settings for one account" + help="a file with >=2 lines where each line " + "contains NAME=VALUE config settings for one account" ) -_dummy = object() - - @pytest.fixture def acfactory(pytestconfig, tmpdir, request): fn = pytestconfig.getoption("--liveconfig") @@ -30,10 +30,10 @@ def acfactory(pytestconfig, tmpdir, request): self.configlist.append(d) self.count = 0 - def get_live_account(self, logcallback=None, started=True): + def get_live_account(self, started=True): configdict = self.configlist.pop(0) tmpdb = tmpdir.join("testdb%d" % self.count) - ac = Account(tmpdb.strpath, logcallback=logcallback) + ac = Account(tmpdb.strpath) ac.set_config(**configdict) if started: ac.start() diff --git a/python/src/deltachat/account.py b/python/src/deltachat/account.py index e9cb1c02..84817e42 100644 --- a/python/src/deltachat/account.py +++ b/python/src/deltachat/account.py @@ -1,23 +1,17 @@ from __future__ import print_function import threading +import re import requests +try: + from queue import Queue +except ImportError: + from Queue import Queue + from . import capi from .capi import ffi import deltachat -class EventPrinter: - def __init__(self, dc_context): - self.dc_context = dc_context - self.info = str(self.dc_context).strip(">").split()[-1] - - def __call__(self, evt): - evt_name, data1, data2 = evt - t = threading.currentThread() - tname = getattr(t, "name", t) - print("[%s-%s]" % (tname, self.info), evt_name, data1, data2) - - class EventHandler: def __init__(self, dc_context): self.dc_context = dc_context @@ -42,6 +36,38 @@ class EventHandler: return 0 # always online +class EventLogger: + def __init__(self, dc_context, debug=True): + self.dc_context = dc_context + self._event_queue = Queue() + self._debug = debug + self._ctxinfo = str(self.dc_context).strip(">").split()[-1] + + def __call__(self, evt_name, data1, data2): + self._log_event(evt_name, data1, data2) + self._event_queue.put((evt_name, data1, data2)) + + def get(self, timeout=None, check_error=True): + ev = self._event_queue.get(timeout=timeout) + if check_error: + assert ev[0] != "DC_EVENT_ERROR" + return ev + + def get_matching(self, event_name_regex, timeout=None): + rex = re.compile(event_name_regex + ".*") + while 1: + ev = self.get(timeout=timeout) + if rex.match(ev[0]): + return ev + + def _log_event(self, evt_name, data1, data2): + if self._debug: + t = threading.currentThread() + tname = getattr(t, "name", t) + print("[{}-{}] {}({!r},{!r})".format( + tname, self._ctxinfo, evt_name, data1, data2)) + + class Contact: def __init__(self, dc_context, contact_id): self.dc_context = dc_context @@ -77,19 +103,15 @@ class Chat: class Account: - def __init__(self, db_path, logcallback=None, eventhandler=None): + def __init__(self, db_path): self.dc_context = ctx = capi.lib.dc_context_new( capi.lib.py_dc_callback, capi.ffi.NULL, capi.ffi.NULL) if hasattr(db_path, "encode"): db_path = db_path.encode("utf8") capi.lib.dc_open(ctx, db_path, capi.ffi.NULL) - if logcallback is None: - logcallback = EventPrinter(self.dc_context) - self._logcallback = logcallback - if eventhandler is None: - eventhandler = EventHandler(self.dc_context) - self._eventhandler = eventhandler + self._evhandler = EventHandler(self.dc_context) + self._evlogger = EventLogger(self.dc_context) self._threads = IOThreads(self.dc_context) def set_config(self, **kwargs): @@ -133,8 +155,8 @@ class Account: def _process_event(self, ctx, evt_name, data1, data2): assert ctx == self.dc_context - self._logcallback((evt_name, data1, data2)) - method = getattr(self._eventhandler, evt_name.lower(), None) + self._evlogger(evt_name, data1, data2) + method = getattr(self._evhandler, evt_name.lower(), None) if method is not None: return method(data1, data2) or 0 return 0 diff --git a/python/tests/test_account.py b/python/tests/test_account.py index 6ddbe991..ed8dda0f 100644 --- a/python/tests/test_account.py +++ b/python/tests/test_account.py @@ -1,11 +1,6 @@ from __future__ import print_function import re -try: - from queue import Queue -except ImportError: - from Queue import Queue - class TestLive: @@ -31,24 +26,21 @@ class TestLive: assert chat.id def test_basic_configure_login_ok(self, acfactory): - q = Queue() - ac1 = acfactory.get_live_account(logcallback=q.put) + ac1 = acfactory.get_live_account() imap_ok = smtp_ok = False while not imap_ok or not smtp_ok: - evt_name, data1, data2 = q.get(timeout=5.0) - print(evt_name, data1, data2) - if evt_name == "DC_EVENT_ERROR": - assert 0 - if evt_name == "DC_EVENT_INFO": - if re.match("imap-login.*ok.", data2.lower()): - imap_ok = True - if re.match("smtp-login.*ok.", data2.lower()): - smtp_ok = True + evt_name, data1, data2 = \ + ac1._evlogger.get_matching("DC_EVENT_INFO", timeout=5) + if re.match("imap-login.*ok.", data2.lower()): + imap_ok = True + if re.match("smtp-login.*ok.", data2.lower()): + smtp_ok = True assert ac1.get_config("mail_pw") def test_send_message(self, acfactory): - ac1 = acfactory.get_live_account() - ac2 = acfactory.get_live_account() + return + ac1, ev1 = acfactory.get_live_account() + ac2, ev2 = acfactory.get_live_account() c2 = ac2.get_self_contact() chat = ac1.create_chat_by_contact(c2) import time