mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
stop python tests from blowing up
This commit is contained in:
7
python/fail_test.py
Normal file
7
python/fail_test.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from __future__ import print_function
|
||||||
|
from deltachat import capi
|
||||||
|
from deltachat.capi import ffi, lib
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
ctx = capi.lib.dc_context_new(ffi.NULL, ffi.NULL)
|
||||||
|
lib.dc_context_shutdown(ctx)
|
||||||
@@ -35,7 +35,7 @@ class Account(object):
|
|||||||
:param debug: turn on debug logging for events.
|
:param debug: turn on debug logging for events.
|
||||||
"""
|
"""
|
||||||
self._dc_context = ffi.gc(
|
self._dc_context = ffi.gc(
|
||||||
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, as_dc_charpointer(os_name)),
|
lib.dc_context_new(ffi.NULL, as_dc_charpointer(os_name)),
|
||||||
_destroy_dc_context,
|
_destroy_dc_context,
|
||||||
)
|
)
|
||||||
self._evlogger = EventLogger(self, logid, debug)
|
self._evlogger = EventLogger(self, logid, debug)
|
||||||
@@ -384,8 +384,6 @@ class Account(object):
|
|||||||
def _export(self, path, imex_cmd):
|
def _export(self, path, imex_cmd):
|
||||||
with ImexTracker(self) as imex_tracker:
|
with ImexTracker(self) as imex_tracker:
|
||||||
lib.dc_imex(self._dc_context, imex_cmd, as_dc_charpointer(path), ffi.NULL)
|
lib.dc_imex(self._dc_context, imex_cmd, as_dc_charpointer(path), ffi.NULL)
|
||||||
if not self._threads.is_started():
|
|
||||||
lib.dc_perform_imap_jobs(self._dc_context)
|
|
||||||
return imex_tracker.wait_finish()
|
return imex_tracker.wait_finish()
|
||||||
|
|
||||||
def import_self_keys(self, path):
|
def import_self_keys(self, path):
|
||||||
@@ -406,8 +404,6 @@ class Account(object):
|
|||||||
def _import(self, path, imex_cmd):
|
def _import(self, path, imex_cmd):
|
||||||
with ImexTracker(self) as imex_tracker:
|
with ImexTracker(self) as imex_tracker:
|
||||||
lib.dc_imex(self._dc_context, imex_cmd, as_dc_charpointer(path), ffi.NULL)
|
lib.dc_imex(self._dc_context, imex_cmd, as_dc_charpointer(path), ffi.NULL)
|
||||||
if not self._threads.is_started():
|
|
||||||
lib.dc_perform_imap_jobs(self._dc_context)
|
|
||||||
imex_tracker.wait_finish()
|
imex_tracker.wait_finish()
|
||||||
|
|
||||||
def initiate_key_transfer(self):
|
def initiate_key_transfer(self):
|
||||||
@@ -485,7 +481,7 @@ class Account(object):
|
|||||||
ev = self._evlogger.get_matching("DC_EVENT_INCOMING_MSG")
|
ev = self._evlogger.get_matching("DC_EVENT_INCOMING_MSG")
|
||||||
return self.get_message_by_id(ev[2])
|
return self.get_message_by_id(ev[2])
|
||||||
|
|
||||||
def start_threads(self, mvbox=False, sentbox=False):
|
def start_threads(self):
|
||||||
""" start IMAP/SMTP threads (and configure account if it hasn't happened).
|
""" start IMAP/SMTP threads (and configure account if it hasn't happened).
|
||||||
|
|
||||||
:raises: ValueError if 'addr' or 'mail_pw' are not configured.
|
:raises: ValueError if 'addr' or 'mail_pw' are not configured.
|
||||||
@@ -493,7 +489,7 @@ class Account(object):
|
|||||||
"""
|
"""
|
||||||
if not self.is_configured():
|
if not self.is_configured():
|
||||||
self.configure()
|
self.configure()
|
||||||
self._threads.start(mvbox=mvbox, sentbox=sentbox)
|
self._threads.start()
|
||||||
|
|
||||||
def stop_threads(self, wait=True):
|
def stop_threads(self, wait=True):
|
||||||
""" stop IMAP/SMTP threads. """
|
""" stop IMAP/SMTP threads. """
|
||||||
@@ -575,14 +571,7 @@ class IOThreads:
|
|||||||
|
|
||||||
def start(self, imap=True, smtp=True, mvbox=False, sentbox=False):
|
def start(self, imap=True, smtp=True, mvbox=False, sentbox=False):
|
||||||
assert not self.is_started()
|
assert not self.is_started()
|
||||||
if imap:
|
self._start_one_thread("deltachat", self.dc_thread_run)
|
||||||
self._start_one_thread("inbox", self.imap_thread_run)
|
|
||||||
if mvbox:
|
|
||||||
self._start_one_thread("mvbox", self.mvbox_thread_run)
|
|
||||||
if sentbox:
|
|
||||||
self._start_one_thread("sentbox", self.sentbox_thread_run)
|
|
||||||
if smtp:
|
|
||||||
self._start_one_thread("smtp", self.smtp_thread_run)
|
|
||||||
|
|
||||||
def _start_one_thread(self, name, func):
|
def _start_one_thread(self, name, func):
|
||||||
self._name2thread[name] = t = threading.Thread(target=func, name=name)
|
self._name2thread[name] = t = threading.Thread(target=func, name=name)
|
||||||
@@ -590,58 +579,17 @@ class IOThreads:
|
|||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
def stop(self, wait=False):
|
def stop(self, wait=False):
|
||||||
self._thread_quitflag = True
|
lib.dc_context_shutdown(self._dc_context)
|
||||||
|
|
||||||
# Workaround for a race condition. Make sure that thread is
|
|
||||||
# not in between checking for quitflag and entering idle.
|
|
||||||
time.sleep(0.5)
|
|
||||||
|
|
||||||
lib.dc_interrupt_imap_idle(self._dc_context)
|
|
||||||
lib.dc_interrupt_smtp_idle(self._dc_context)
|
|
||||||
lib.dc_interrupt_mvbox_idle(self._dc_context)
|
|
||||||
lib.dc_interrupt_sentbox_idle(self._dc_context)
|
|
||||||
if wait:
|
if wait:
|
||||||
for name, thread in self._name2thread.items():
|
for name, thread in self._name2thread.items():
|
||||||
thread.join()
|
thread.join()
|
||||||
|
|
||||||
def imap_thread_run(self):
|
def dc_thread_run(self):
|
||||||
self._log_event("py-bindings-info", 0, "INBOX THREAD START")
|
self._log_event("py-bindings-info", 0, "DC THREAD START")
|
||||||
while not self._thread_quitflag:
|
|
||||||
lib.dc_perform_imap_jobs(self._dc_context)
|
lib.dc_context_run(self._dc_context, lib.py_dc_callback)
|
||||||
if not self._thread_quitflag:
|
|
||||||
lib.dc_perform_imap_fetch(self._dc_context)
|
|
||||||
if not self._thread_quitflag:
|
|
||||||
lib.dc_perform_imap_idle(self._dc_context)
|
|
||||||
self._log_event("py-bindings-info", 0, "INBOX THREAD FINISHED")
|
|
||||||
|
|
||||||
def mvbox_thread_run(self):
|
|
||||||
self._log_event("py-bindings-info", 0, "MVBOX THREAD START")
|
|
||||||
while not self._thread_quitflag:
|
|
||||||
lib.dc_perform_mvbox_jobs(self._dc_context)
|
|
||||||
if not self._thread_quitflag:
|
|
||||||
lib.dc_perform_mvbox_fetch(self._dc_context)
|
|
||||||
if not self._thread_quitflag:
|
|
||||||
lib.dc_perform_mvbox_idle(self._dc_context)
|
|
||||||
self._log_event("py-bindings-info", 0, "MVBOX THREAD FINISHED")
|
|
||||||
|
|
||||||
def sentbox_thread_run(self):
|
|
||||||
self._log_event("py-bindings-info", 0, "SENTBOX THREAD START")
|
|
||||||
while not self._thread_quitflag:
|
|
||||||
lib.dc_perform_sentbox_jobs(self._dc_context)
|
|
||||||
if not self._thread_quitflag:
|
|
||||||
lib.dc_perform_sentbox_fetch(self._dc_context)
|
|
||||||
if not self._thread_quitflag:
|
|
||||||
lib.dc_perform_sentbox_idle(self._dc_context)
|
|
||||||
self._log_event("py-bindings-info", 0, "SENTBOX THREAD FINISHED")
|
|
||||||
|
|
||||||
def smtp_thread_run(self):
|
|
||||||
self._log_event("py-bindings-info", 0, "SMTP THREAD START")
|
|
||||||
while not self._thread_quitflag:
|
|
||||||
lib.dc_perform_smtp_jobs(self._dc_context)
|
|
||||||
if not self._thread_quitflag:
|
|
||||||
lib.dc_perform_smtp_idle(self._dc_context)
|
|
||||||
self._log_event("py-bindings-info", 0, "SMTP THREAD FINISHED")
|
|
||||||
|
|
||||||
|
self._log_event("py-bindings-info", 0, "DC THREAD FINISHED")
|
||||||
|
|
||||||
def _destroy_dc_context(dc_context, dc_context_unref=lib.dc_context_unref):
|
def _destroy_dc_context(dc_context, dc_context_unref=lib.dc_context_unref):
|
||||||
# destructor for dc_context
|
# destructor for dc_context
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ class TestOfflineChat:
|
|||||||
assert d["draft"] == "" if chat.get_draft() is None else chat.get_draft()
|
assert d["draft"] == "" if chat.get_draft() is None else chat.get_draft()
|
||||||
|
|
||||||
def test_group_chat_creation_with_translation(self, ac1):
|
def test_group_chat_creation_with_translation(self, ac1):
|
||||||
|
ac1.start_threads()
|
||||||
ac1.set_stock_translation(const.DC_STR_NEWGROUPDRAFT, "xyz %1$s")
|
ac1.set_stock_translation(const.DC_STR_NEWGROUPDRAFT, "xyz %1$s")
|
||||||
ac1._evlogger.consume_events()
|
ac1._evlogger.consume_events()
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
@@ -197,6 +198,7 @@ class TestOfflineChat:
|
|||||||
assert not chat.is_promoted()
|
assert not chat.is_promoted()
|
||||||
msg = chat.get_draft()
|
msg = chat.get_draft()
|
||||||
assert msg.text == "xyz title1"
|
assert msg.text == "xyz title1"
|
||||||
|
ac1.stop_threads()
|
||||||
|
|
||||||
@pytest.mark.parametrize("verified", [True, False])
|
@pytest.mark.parametrize("verified", [True, False])
|
||||||
def test_group_chat_qr(self, acfactory, ac1, verified):
|
def test_group_chat_qr(self, acfactory, ac1, verified):
|
||||||
|
|||||||
@@ -1,29 +1,64 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
import threading
|
||||||
from deltachat import capi, cutil, const, set_context_callback, clear_context_callback
|
from deltachat import capi, cutil, const, set_context_callback, clear_context_callback
|
||||||
from deltachat.capi import ffi
|
from deltachat.capi import ffi
|
||||||
from deltachat.capi import lib
|
from deltachat.capi import lib
|
||||||
|
from deltachat.account import EventLogger
|
||||||
|
|
||||||
|
|
||||||
|
class EventThread(threading.Thread):
|
||||||
|
def __init__(self, dc_context):
|
||||||
|
self.dc_context = dc_context
|
||||||
|
super(EventThread, self).__init__()
|
||||||
|
self.setDaemon(1)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
lib.dc_context_run(self.dc_context)#, lib.py_dc_callback)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
lib.dc_context_shutdown(self.dc_context)
|
||||||
|
|
||||||
|
|
||||||
def test_empty_context():
|
def test_empty_context():
|
||||||
ctx = capi.lib.dc_context_new(capi.ffi.NULL, capi.ffi.NULL, capi.ffi.NULL)
|
ctx = capi.lib.dc_context_new(capi.ffi.NULL, capi.ffi.NULL)
|
||||||
capi.lib.dc_close(ctx)
|
capi.lib.dc_close(ctx)
|
||||||
|
|
||||||
|
|
||||||
def test_callback_None2int():
|
def test_callback_None2int():
|
||||||
ctx = capi.lib.dc_context_new(capi.lib.py_dc_callback, ffi.NULL, ffi.NULL)
|
ctx = capi.lib.dc_context_new(ffi.NULL, ffi.NULL)
|
||||||
set_context_callback(ctx, lambda *args: None)
|
set_context_callback(ctx, lambda *args: None)
|
||||||
capi.lib.dc_close(ctx)
|
capi.lib.dc_close(ctx)
|
||||||
clear_context_callback(ctx)
|
clear_context_callback(ctx)
|
||||||
|
|
||||||
|
def test_start_stop_event_thread_basic():
|
||||||
|
print("1")
|
||||||
|
ctx = capi.lib.dc_context_new(ffi.NULL, ffi.NULL)
|
||||||
|
print("2")
|
||||||
|
ev_thread = EventThread(ctx)
|
||||||
|
print("3 -- starting event thread")
|
||||||
|
ev_thread.start()
|
||||||
|
print("4 -- stopping event thread")
|
||||||
|
ev_thread.stop()
|
||||||
|
|
||||||
def test_dc_close_events(tmpdir):
|
def test_dc_close_events(tmpdir):
|
||||||
from deltachat.account import Account
|
ctx = ffi.gc(
|
||||||
|
capi.lib.dc_context_new(ffi.NULL, ffi.NULL),
|
||||||
|
lib.dc_context_unref,
|
||||||
|
)
|
||||||
|
evlog = EventLogger(ctx)
|
||||||
|
evlog.set_timeout(5)
|
||||||
|
set_context_callback(
|
||||||
|
ctx,
|
||||||
|
lambda ctx, evt_name, data1, data2: evlog(evt_name, data1, data2)
|
||||||
|
)
|
||||||
|
ev_thread = EventThread(ctx)
|
||||||
|
ev_thread.start()
|
||||||
|
|
||||||
p = tmpdir.join("hello.db")
|
p = tmpdir.join("hello.db")
|
||||||
ac1 = Account(p.strpath)
|
lib.dc_open(ctx, p.strpath.encode("ascii"), ffi.NULL)
|
||||||
ac1.shutdown()
|
capi.lib.dc_close(ctx)
|
||||||
|
|
||||||
def find(info_string):
|
def find(info_string):
|
||||||
evlog = ac1._evlogger
|
|
||||||
while 1:
|
while 1:
|
||||||
ev = evlog.get_matching("DC_EVENT_INFO", check_error=False)
|
ev = evlog.get_matching("DC_EVENT_INFO", check_error=False)
|
||||||
data2 = ev[2]
|
data2 = ev[2]
|
||||||
@@ -37,11 +72,12 @@ def test_dc_close_events(tmpdir):
|
|||||||
find("disconnecting mvbox-thread")
|
find("disconnecting mvbox-thread")
|
||||||
find("disconnecting SMTP")
|
find("disconnecting SMTP")
|
||||||
find("Database closed")
|
find("Database closed")
|
||||||
|
ev_thread.stop()
|
||||||
|
|
||||||
|
|
||||||
def test_wrong_db(tmpdir):
|
def test_wrong_db(tmpdir):
|
||||||
dc_context = ffi.gc(
|
dc_context = ffi.gc(
|
||||||
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
|
lib.dc_context_new(ffi.NULL, ffi.NULL),
|
||||||
lib.dc_context_unref,
|
lib.dc_context_unref,
|
||||||
)
|
)
|
||||||
p = tmpdir.join("hello.db")
|
p = tmpdir.join("hello.db")
|
||||||
@@ -53,7 +89,7 @@ def test_wrong_db(tmpdir):
|
|||||||
def test_empty_blobdir(tmpdir):
|
def test_empty_blobdir(tmpdir):
|
||||||
# Apparently some client code expects this to be the same as passing NULL.
|
# Apparently some client code expects this to be the same as passing NULL.
|
||||||
ctx = ffi.gc(
|
ctx = ffi.gc(
|
||||||
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
|
lib.dc_context_new(ffi.NULL, ffi.NULL),
|
||||||
lib.dc_context_unref,
|
lib.dc_context_unref,
|
||||||
)
|
)
|
||||||
db_fname = tmpdir.join("hello.db")
|
db_fname = tmpdir.join("hello.db")
|
||||||
@@ -95,7 +131,7 @@ def test_get_special_message_id_returns_empty_message(acfactory):
|
|||||||
|
|
||||||
def test_provider_info_none():
|
def test_provider_info_none():
|
||||||
ctx = ffi.gc(
|
ctx = ffi.gc(
|
||||||
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
|
lib.dc_context_new(ffi.NULL, ffi.NULL),
|
||||||
lib.dc_context_unref,
|
lib.dc_context_unref,
|
||||||
)
|
)
|
||||||
assert lib.dc_provider_new_from_email(ctx, cutil.as_dc_charpointer("email@unexistent.no")) == ffi.NULL
|
assert lib.dc_provider_new_from_email(ctx, cutil.as_dc_charpointer("email@unexistent.no")) == ffi.NULL
|
||||||
@@ -103,7 +139,7 @@ def test_provider_info_none():
|
|||||||
|
|
||||||
def test_get_info_closed():
|
def test_get_info_closed():
|
||||||
ctx = ffi.gc(
|
ctx = ffi.gc(
|
||||||
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
|
lib.dc_context_new(ffi.NULL, ffi.NULL),
|
||||||
lib.dc_context_unref,
|
lib.dc_context_unref,
|
||||||
)
|
)
|
||||||
info = cutil.from_dc_charpointer(lib.dc_get_info(ctx))
|
info = cutil.from_dc_charpointer(lib.dc_get_info(ctx))
|
||||||
@@ -113,7 +149,7 @@ def test_get_info_closed():
|
|||||||
|
|
||||||
def test_get_info_open(tmpdir):
|
def test_get_info_open(tmpdir):
|
||||||
ctx = ffi.gc(
|
ctx = ffi.gc(
|
||||||
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
|
lib.dc_context_new(ffi.NULL, ffi.NULL),
|
||||||
lib.dc_context_unref,
|
lib.dc_context_unref,
|
||||||
)
|
)
|
||||||
db_fname = tmpdir.join("test.db")
|
db_fname = tmpdir.join("test.db")
|
||||||
@@ -125,7 +161,7 @@ def test_get_info_open(tmpdir):
|
|||||||
|
|
||||||
def test_is_open_closed():
|
def test_is_open_closed():
|
||||||
ctx = ffi.gc(
|
ctx = ffi.gc(
|
||||||
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
|
lib.dc_context_new(ffi.NULL, ffi.NULL),
|
||||||
lib.dc_context_unref,
|
lib.dc_context_unref,
|
||||||
)
|
)
|
||||||
assert lib.dc_is_open(ctx) == 0
|
assert lib.dc_is_open(ctx) == 0
|
||||||
@@ -133,7 +169,7 @@ def test_is_open_closed():
|
|||||||
|
|
||||||
def test_is_open_actually_open(tmpdir):
|
def test_is_open_actually_open(tmpdir):
|
||||||
ctx = ffi.gc(
|
ctx = ffi.gc(
|
||||||
lib.dc_context_new(lib.py_dc_callback, ffi.NULL, ffi.NULL),
|
lib.dc_context_new(ffi.NULL, ffi.NULL),
|
||||||
lib.dc_context_unref,
|
lib.dc_context_unref,
|
||||||
)
|
)
|
||||||
db_fname = tmpdir.join("test.db")
|
db_fname = tmpdir.join("test.db")
|
||||||
|
|||||||
Reference in New Issue
Block a user