diff --git a/Makefile b/Makefile
index 4b280f5..cd89ea8 100644
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,7 @@ check::
install::
${PIP_EXE_MSYS} --python ${PYTHON_EXE_MSYS} install \
+ --no-deps \
--target ${PREFIX}/lib/python${PYTHON_MINOR}/site-packages/ \
--upgrade .
@@ -30,16 +31,20 @@ test::
test_direct::
cp -p ${HOME}/.config/tox/DHTnodes.json /tmp/toxygen_nodes.json
PYTHONPATH=$${PWD}/src \
+ TOR_CONTROLLER_PASSWORD=${PASS} \
sudo -u bin $(PYTHON_EXE_MSYS) src/toxygen_wrapper/tests/tests_wrapper.py \
+ --norequest=True \
--socket_timeout=10.0 \
--test_timeout=${iTEST_TIMEOUT} \
--nodes_json=/tmp/toxygen_nodes.json \
--udp_enabled=True \
- --trace_enabled=False --loglevel=10
+ --trace_enabled=False --loglevel=10
test_proxy::
PYTHONPATH=$${PWD}/src \
+ TOR_CONTROLLER_PASSWORD=${PASS} \
${PYTHON_EXE_MSYS} src/toxygen_wrapper/tests/tests_wrapper.py \
+ --norequest=True \
--socket_timeout=15.0 \
--test_timeout=${iTEST_TIMEOUT} \
--proxy_host=127.0.0.1 \
diff --git a/src/toxygen_wrapper/tests/support_http.py b/src/toxygen_wrapper/tests/support_http.py
index f3bc975..6dc7ffd 100644
--- a/src/toxygen_wrapper/tests/support_http.py
+++ b/src/toxygen_wrapper/tests/support_http.py
@@ -8,7 +8,7 @@ import urllib
import traceback
global LOG
-LOG = logging.getLogger('app.'+'ts')
+LOG = logging.getLogger('TestS')
try:
import pycurl
diff --git a/src/toxygen_wrapper/tests/support_onions.py b/src/toxygen_wrapper/tests/support_onions.py
index 324c889..4c2d6a0 100644
--- a/src/toxygen_wrapper/tests/support_onions.py
+++ b/src/toxygen_wrapper/tests/support_onions.py
@@ -1,4 +1,7 @@
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
+"""
+Code to interact with a running to using the stem library.
+"""
import getpass
import os
@@ -9,31 +12,26 @@ import socket
import sys
import time
from typing import Union, Callable, Union
+import warnings
-if False:
- import cepa as stem
- from cepa.connection import MissingPassword
- from cepa.control import Controller
- from cepa.util.tor_tools import is_valid_fingerprint
-else:
- import stem
- from stem.connection import MissingPassword
- from stem.control import Controller
- from stem.util.tor_tools import is_valid_fingerprint
+import stem
+from stem.connection import MissingPassword
+from stem.control import Controller
+from stem.util.tor_tools import is_valid_fingerprint
global LOG
import logging
-import warnings
+from toxygen_wrapper.tests.support_http import bAreWeConnected
warnings.filterwarnings('ignore')
-LOG = logging.getLogger()
+LOG = logging.getLogger('TestS')
bHAVE_TORR = shutil.which('tor-resolve')
-
+oSTEM_CONTROLER = None
yKNOWN_ONIONS = """
- facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd # facebook
- duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad # ddg
- - zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad # hks
+ - zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad # keys.openpgp
"""
# grep -B 1 '
bool:
- # FixMe: Linux only
- sFile = f"/proc/{os.getpid()}/net/route"
- if not os.path.isfile(sFile): return None
- i = 0
- for elt in open(sFile, "r").readlines():
- if elt.startswith('Iface'): continue
- if elt.startswith('lo'): continue
- i += 1
- return i > 0
-
-def sMapaddressResolv(target:str, iPort:int = 9051, log_level:int = 10) -> str:
+def sMapaddressResolv(target:str, iPort:int = 9051, log_level:int = 10, password:[str,None] = None) -> str:
if not stem:
LOG.warn('please install the stem Python package')
return ''
try:
- controller = oGetStemController(log_level=log_level)
-
+ controller = oGetStemController(log_level=log_level, password=password)
map_dict = {"0.0.0.0": target}
map_ret = controller.map_address(map_dict)
-
return map_ret
except Exception as e:
LOG.exception(e)
@@ -298,7 +297,7 @@ def sMapaddressResolv(target:str, iPort:int = 9051, log_level:int = 10) -> str:
def vwait_for_controller(controller, wait_boot:int = 10) -> None:
if bAreWeConnected() is False:
- raise SystemExit("we are not connected")
+ raise RuntimeError("we are not connected")
percent = i = 0
# You can call this while boostrapping
while percent < 100 and i < wait_boot:
@@ -314,17 +313,17 @@ def bin_to_hex(raw_id:int, length: Union[int, None] = None) -> str:
res = ''.join('{:02x}'.format(raw_id[i]) for i in range(length))
return res.upper()
-def lIntroductionPoints(controller=None, lOnions:list = [], itimeout:int = 120, log_level:int = 10):
+def lIntroductionPoints(controller=None, lOnions:[list,None] = None, itimeout:int = 120, log_level:int = 10, password:[str,None] = None):
"""now working !!! stem 1.8.x timeout must be huge >120
'Provides the descriptor for a hidden service. The **address** is the
'.onion' address of the hidden service '
What about Services?
"""
+ if lOnions is None: lOnions = []
try:
from cryptography.utils import int_from_bytes
except ImportError:
import cryptography.utils
-
# guessing - not in the current cryptography but stem expects it
def int_from_bytes(**args): return int.to_bytes(*args)
cryptography.utils.int_from_bytes = int_from_bytes
@@ -341,7 +340,7 @@ def lIntroductionPoints(controller=None, lOnions:list = [], itimeout:int = 120,
if type(lOnions) not in [set, tuple, list]:
lOnions = list(lOnions)
if controller is None:
- controller = oGetStemController(log_level=log_level)
+ controller = oGetStemController(log_level=log_level, password=password)
l = []
for elt in lOnions:
LOG.info(f"controller.get_hidden_service_descriptor {elt}")
@@ -529,7 +528,7 @@ def icheck_torrc(sFile:str, oArgs) -> int:
print('VirtualAddrNetworkIPv4 172.16.0.0/12')
return 0
-def lExitExcluder(oArgs, iPort:int = 9051, log_level:int = 10) -> list:
+def lExitExcluder(oArgs, iPort:int = 9051, log_level:int = 10, password:[str,None] = None) -> list:
"""
https://raw.githubusercontent.com/nusenu/noContactInfo_Exit_Excluder/main/exclude_noContactInfo_Exits.py
"""
@@ -539,7 +538,7 @@ def lExitExcluder(oArgs, iPort:int = 9051, log_level:int = 10) -> list:
LOG.debug('lExcludeExitNodes')
try:
- controller = oGetStemController(log_level=log_level)
+ controller = oGetStemController(log_level=log_level, password=password)
# generator
relays = controller.get_server_descriptors()
except Exception as e:
@@ -568,6 +567,6 @@ def lExitExcluder(oArgs, iPort:int = 9051, log_level:int = 10) -> list:
return exit_excludelist
if __name__ == '__main__':
- target = 'duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad'
+ target = 'zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad'
controller = oGetStemController(log_level=10)
lIntroductionPoints(controller, [target], itimeout=120)
diff --git a/src/toxygen_wrapper/tests/support_testing.py b/src/toxygen_wrapper/tests/support_testing.py
index bb20ed5..d88f1a8 100644
--- a/src/toxygen_wrapper/tests/support_testing.py
+++ b/src/toxygen_wrapper/tests/support_testing.py
@@ -49,7 +49,7 @@ from tox_wrapper.tests.support_onions import (is_valid_fingerprint,
# LOG=util.log
global LOG
-LOG = logging.getLogger()
+LOG = logging.getLogger('TestS')
# callbacks can be called in any thread so were being careful
def LOG_ERROR(l): print('EROR< '+l)
@@ -148,10 +148,12 @@ def assert_main_thread() -> None:
from qtpy.QtWidgets import QApplication
# this "instance" method is very useful!
- app_thread = QtWidgets.QApplication.instance().thread()
- curr_thread = QtCore.QThread.currentThread()
- if app_thread != curr_thread:
- raise RuntimeError('attempt to call MainWindow.append_message from non-app thread')
+ app_instance = QtWidgets.QApplication.instance()
+ if app_instance:
+ app_thread = QtWidgets.QApplication.instance().thread()
+ curr_thread = QtCore.QThread.currentThread()
+ if app_thread != curr_thread:
+ raise RuntimeError('attempt to call MainWindow.append_message from non-app thread')
@contextlib.contextmanager
def ignoreStdout() -> None:
diff --git a/src/toxygen_wrapper/tests/tests_wrapper.py b/src/toxygen_wrapper/tests/tests_wrapper.py
index daeb23d..e3121cc 100644
--- a/src/toxygen_wrapper/tests/tests_wrapper.py
+++ b/src/toxygen_wrapper/tests/tests_wrapper.py
@@ -23,21 +23,24 @@
"""Originaly from https://github.com/oxij/PyTox c-toxcore-02 branch
which itself was forked from https://github.com/aitjcize/PyTox/
-
Modified to work with toxygen_wrapper
+Unlike almost all of the c-toxcore ctests, these are real tests that
+take place over and Internet connection.
-these tests create the alice and bob Toxes for each testcase.
+These tests create the alice and bob Toxes for each testcase.
We could do it once for the testsuite but we are testing a ctypes wrapper
and what we think we've seen is errors in the wrapper can corrupt memory
that shows as a SEGV but not nesessarily right-away: could be a little later.
So for cleanliness and purity we remake the Toxes, which means we have to
-wait in each test to get connected, which can be slow over tor: ~40 sec. is
-not unusual, but less for directly connected.
+wait in each test to get connected on tests that require connectivity,
+which can be slow over tor: ~40 sec. is not unusual, but less for
+directly connected. The other advantage of a fresh tox each time is
+that the tests are more reproducible and comparable.
-So typically this testsuite takes ~1000 sec. direct and 1300 sec. over Tor,
-but Tor can have bad weeks so these Tor times could double or triple.
+So typically this testsuite takes ~1000 sec. direct and 1500 sec. over Tor,
+but Tor can have bad weeks so these Tor times could double or more.
-We should consirder reusing a tox profile between testcases to cache the peers.
+We should consider reusing a tox profile between testcases to cache the peers.
"""
@@ -85,17 +88,21 @@ except ImportError as e:
import tox_wrapper
import tox_wrapper.toxcore_enums_and_consts as enums
from tox_wrapper.tox import Tox, UINT32_MAX, ToxError
-
-from tox_wrapper.toxcore_enums_and_consts import (TOX_ADDRESS_SIZE, TOX_CONNECTION,
- TOX_FILE_CONTROL,
- TOX_MESSAGE_TYPE,
- TOX_SECRET_KEY_SIZE,
- TOX_USER_STATUS)
+from tox_wrapper.toxcore_enums_and_consts import (TOX_ADDRESS_SIZE,
+ TOX_CONNECTION,
+ TOX_FILE_CONTROL,
+ TOX_MESSAGE_TYPE,
+ TOX_SECRET_KEY_SIZE,
+ TOX_USER_STATUS)
try:
import support_testing as ts
+ import support_onions as so
except ImportError:
import tox_wrapper.tests.support_testing as ts
+ import tox_wrapper.tests.support_onions as so
+
+from wrapper_mixin import WrapperMixin
try:
from tests.toxygen_tests import test_sound_notification
@@ -105,7 +112,6 @@ except ImportError:
# from PyQt5 import QtCore
import time
-
sleep = time.sleep
global LOG
@@ -248,7 +254,6 @@ def prepare(self):
LOG_WARN(f"bobs_on_self_connection_status DISAGREE {status}")
def alices_on_self_connection_status(iTox, connection_state: int, *args) -> None:
- global oTOX_OARGS
#FixMe connection_num
status = connection_state
self.alice.dht_connected = status
@@ -289,8 +294,6 @@ def prepare(self):
LOG.warning(f"doOnce not local and NOT CONNECTED")
return [bob, alice]
-from wrapper_mixin import WrapperMixin
-
class ToxSuite(unittest.TestCase, WrapperMixin):
failureException = AssertionError
@@ -440,7 +443,8 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
t:callback_group_custom_packet
t:callback_group_invite
"""
- if oTOX_OARGS.network not in ['new', 'newlocal', 'local']:
+ otox = self.bob
+ if otox._args.network not in ['new', 'newlocal', 'local']:
return
port = ts.tox_bootstrapd_port()
@@ -492,21 +496,22 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
@unittest.skipIf(os.geteuid() != 0, 'must be root')
def test_bootstrap_iNmapInfo(self) -> None: # works
- global oTOX_OARGS
+
# if os.environ['USER'] != 'root':
# return
iStatus = self.bob.self_get_connection_status()
LOG.info(f"test_bootstrap_iNmapInfo connected bob iStatus={iStatus}")
- if oTOX_OARGS.network in ['new', 'newlocal', 'localnew']:
+ otox = self.bob
+ if otox._args.network in ['new', 'newlocal', 'localnew']:
lElts = self.lUdp
- elif oTOX_OARGS.proxy_port > 0:
+ elif otox._args.proxy_port > 0:
lElts = self.lTcp
else:
lElts = self.lUdp
lRetval = []
random.shuffle(lElts)
# assert
- ts.bootstrap_iNmapInfo(lElts, oTOX_OARGS, "tcp4", bIS_LOCAL=bIS_LOCAL, iNODES=8)
+ ts.bootstrap_iNmapInfo(lElts, otox._args, "tcp4", bIS_LOCAL=bIS_LOCAL, iNODES=8)
def test_self_get_secret_key(self) -> None: # works
"""
@@ -593,6 +598,7 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
"""
t:self_get_udp_port
"""
+ otox = self.bob
if hasattr(oTOX_OPTIONS, 'udp_port') and oTOX_OPTIONS.udp_port:
o = self.alice.self_get_udp_port()
LOG.info('self_get_udp_port alice ' +repr(o))
@@ -893,7 +899,7 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
status_message = bytes(MSG, 'utf-8')
self.alice.self_set_status_message(status_message)
if not self.wait_otox_attrs(self.bob, [sSlot]):
- LOG_WARN(f"on_friend_status_message NO {sSlot}")
+ raise AssertionError(f"on_friend_status_message NO {sSlot}")
assert self.bob.friend_get_status_message(self.baid) == MSG, \
f"message={self.bob.friend_get_status_message(self.baid)}"
@@ -979,7 +985,6 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
else:
assert self.bob_add_alice_as_friend()
if not self.get_connection_status():
- LOG.warning(f"test_user_status NOT CONNECTED self.get_connection_status")
self.loop_until_connected(self.bob)
self.bob.callback_friend_status(bobs_on_friend_set_status)
@@ -987,8 +992,8 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
sSTATUS = TOX_USER_STATUS['BUSY']
self.alice.self_set_status(sSTATUS)
if not self.wait_otox_attrs(self.bob, [sSlot]):
- # malloc(): unaligned tcache chunk detected
- LOG_WARN(f'test_user_status NO {sSlot}')
+ # malloc(): unaligned tcache chunk detected LOG_WARN
+ raise AssertionError(f'test_user_status NO {sSlot}')
assert self.bob.friend_get_status(self.baid) == TOX_USER_STATUS['BUSY'], \
f"friend_get_status {self.bob.friend_get_status(self.baid)} != {TOX_USER_STATUS['BUSY']}"
@@ -1011,7 +1016,6 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
t:friend_get_kill_remake
t:on_friend_connection_status
"""
- global oTOX_OARGS
sSlot = 'friend_connection_status'
setattr(self.bob, sSlot, None)
def bobs_on_friend_connection_status(iTox, friend_id, iStatus, *largs):
@@ -1022,7 +1026,8 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
LOG_ERROR(f"bobs_on_friend_connection_status ERROR {e}")
setattr(self.bob, sSlot, True)
- opts = oTestsToxOptions(oTOX_OARGS)
+ otox = self.bob
+ opts = oTestsToxOptions(otox._args)
setattr(self.bob, sSlot, True)
try:
if self.bob._args.norequest:
@@ -1039,7 +1044,7 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
LOG.info("test_kill_remake maked alice")
if not self.wait_otox_attrs(self.bob, [sSlot]):
- LOG_WARN(f'test_kill_remake NO {sSlot}')
+ raise AssertionError(f'test_kill_remake NO {sSlot}')
except AssertionError as e:
LOG.error(f"test_kill_remake Failed test {e}")
raise
@@ -1081,14 +1086,13 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
assert self.both_add_as_friend()
if not self.get_connection_status():
- LOG.warning(f"test_friend_typing NOT CONNECTED")
self.loop_until_connected(self.bob)
self.bob.callback_friend_typing(bob_on_friend_typing)
self.warn_if_no_cb(self.bob, sSlot)
self.alice.self_set_typing(self.abid, False)
if not self.wait_otox_attrs(self.bob, [sSlot]):
- LOG_WARN(f"bobs_on_friend_typing NO {sSlot}")
+ raise AssertionError(f"bobs_on_friend_typing NO {sSlot}")
except AssertionError as e:
LOG.error(f"Failed test {e}")
raise
@@ -1141,7 +1145,7 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
self.warn_if_no_cb(self.bob, sSlot)
self.alice.self_set_name(NEWNAME)
if not self.wait_otox_attrs(self.bob, [sSlot]):
- LOG_WARN(f"bobs_on_friend_name NO {sSlot}")
+ raise AssertionError(f"bobs_on_friend_name NO {sSlot}")
# name=None
assert self.bob.friend_get_name(self.baid) == NEWNAME, \
@@ -1161,75 +1165,16 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
self.bob.callback_friend_name(None)
self.warn_if_cb(self.bob, sSlot)
-#! @expectedFail('fails') # This client is currently not connected to the friend.
- def test_friend_message(self) -> None: # fails intermittently
- """
- t:on_friend_action
- t:on_friend_message
- t:friend_send_message
- """
-
- #: Test message
- MSG = 'Hi, Bob!'
- sSlot = 'friend_message'
-
- def alices_on_friend_message(iTox, fid:int, msg_type, message, iSize, *largs) -> None:
- LOG_DEBUG(f"alices_on_friend_message {fid} {message}")
- try:
- assert fid == self.alice.abid
- assert msg_type == TOX_MESSAGE_TYPE['NORMAL']
- assert str(message, 'UTF-8') == MSG
- except Exception as e:
- LOG_ERROR(f"alices_on_friend_message EXCEPTION {e}")
- else:
- LOG_INFO(f"alices_on_friend_message {message}")
- setattr(self.alice, sSlot, True)
-
- setattr(self.alice, sSlot, None)
- self.alice.callback_friend_message(None)
- try:
- if self.bob._args.norequest:
- assert self.both_add_as_friend_norequest()
- else:
- assert self.both_add_as_friend()
- assert hasattr(self, 'baid'), \
- "both_add_as_friend_norequest no bob, baid"
- assert hasattr(self, 'abid'), \
- "both_add_as_friend_norequest no alice, abid"
- if not self.wait_friend_get_connection_status(self.bob, self.baid, n=2*iN):
- LOG.warn('baid not connected')
- if not self.wait_friend_get_connection_status(self.alice, self.abid, n=2*iN):
- LOG.warn('abid not connected')
- self.alice.callback_friend_message(alices_on_friend_message)
- self.warn_if_no_cb(self.alice, sSlot)
-
- # dunno - both This client is currently NOT CONNECTED to the friend.
- iMesId = self.bob.friend_send_message(self.baid,
- TOX_MESSAGE_TYPE['NORMAL'],
- bytes(MSG, 'UTF-8'))
- assert iMesId >= 0, "iMesId >= 0"
- if not self.wait_otox_attrs(self.alice, [sSlot]):
- LOG_WARN(f"alices_on_friend_message NO {sSlot}")
- except ArgumentError as e:
- # ArgumentError('This client is currently NOT CONNECTED to the friend.')
- # dunno
- LOG.error(f"test_friend_message ArgumentError {e}")
- raise
- except AssertionError as e:
- LOG.error(f"test_friend_message AssertionError {e}")
- raise
- except Exception as e:
- LOG.error(f"test_friend_message EXCEPTION {e}")
- raise
- finally:
- self.alice.callback_friend_message(None)
- self.warn_if_cb(self.alice, sSlot)
- if hasattr(self, 'baid') and self.baid >= 0:
- self.bob.friend_delete(self.baid)
- if hasattr(self, 'abid') and self.abid >= 0:
- self.alice.friend_delete(self.abid)
-
+# https://github.com/TokTok/c-toxcore/issues/1338
+# If you node is on the internet, you can check if it works with this test page https://nodes.tox.chat/test. It sends some packets to you node and checks if it gets the correct response back. If it's in a private network, you can telnet into your node telnet 33445 to at least make sure there is something accepting TCP connections on there (I guess nmap works too).
+# torsocks telnet 198.199.93.42 33445
+# ERROR torsocks[2573639]: Unable to resolve. Status reply: 4 (in socks5_recv_resolve_reply() at socks5.c:677)
+# Trying 198.199.93.42...
+# ERROR torsocks[2573639]: General SOCKS server failure (in socks5_recv_connect_reply() at socks5.c:527)
+# telnet: connect to address 198.199.93.42: Connection refused
+#
# This client is currently not connected to the friend.
+ @expectedFail('fails works! sometimes?')
def test_friend_action(self) -> None: # works! sometimes?
"""
t:on_friend_action
@@ -1277,10 +1222,11 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
else:
assert self.both_add_as_friend()
- if not self.wait_friend_get_connection_status(self.bob, self.baid, n=iN):
- LOG.warn('baid not connected')
- if not self.wait_friend_get_connection_status(self.alice, self.abid, n=iN):
- LOG.warn('abid not connected')
+ if not self.wait_friend_get_connection_status(self.bob, self.baid, n=2*iN):
+ raise AssertionError(f"bob NOT CONNECTED baid={self.baid}, n={2*iN}")
+
+ if not self.wait_friend_get_connection_status(self.alice, self.abid, n=2*iN):
+ raise AssertionError(f"alice NOT CONNECTED abid={self.abid}, n={2*iN}")
self.bob.callback_friend_read_receipt(their_on_read_reciept) #was their_on_friend_action
self.alice.callback_friend_read_receipt(their_on_read_reciept) #was their_on_friend_action
@@ -1297,7 +1243,7 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
TOX_MESSAGE_TYPE['ACTION'],
bytes(ACTION, 'UTF-8')])
if not self.wait_otox_attrs(self.alice, [sSlot]):
- LOG_WARN(f"alice test_friend_action NO {sSlot}")
+ raise AssertionError(f"alice test_friend_action NO {sSlot}")
except AssertionError as e:
LOG.error(f"Failed test {e}")
raise
@@ -1315,7 +1261,88 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
if hasattr(self, 'abid') and self.abid >= 0:
self.alice.friend_delete(self.abid)
- @expectedFail('fails') # @unittest.skip('unfinished')
+ def test_onion_intros(self) -> None: # timeout intermittently
+ # introduction points are needed for onion services
+ if self.bob._args.proxy_type == 2:
+ target = 'zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad'
+ controller = so.oGetStemController(log_level=10)
+ i = self.bob._args.test_timeout
+ l = so.lIntroductionPoints(controller, [target], itimeout=i)
+ if l:
+ LOG_INFO(f"test_onion_intros len={len(l)}")
+ else:
+ LOG_WARN(f"test_onion_intros len={len(l)}")
+
+ # This client is currently not connected to the friend.
+ @expectedFail('bob NOT CONNECTED baid') # passes clearnet fails tor = no
+ def test_friend_message(self) -> None: # fails intermittently
+ """
+ t:on_friend_action
+ t:on_friend_message
+ t:friend_send_message
+ """
+ # @unittest.skipIf( oTOX_OARGS.proxy_type == 2, 'Fails over Tor')
+
+ #: Test message
+ MSG = 'Hi, Bob!'
+ sSlot = 'friend_message'
+
+ def alices_on_friend_message(iTox, fid:int, msg_type, message, iSize, *largs) -> None:
+ LOG_DEBUG(f"alices_on_friend_message {fid} {message}")
+ try:
+ assert fid == self.alice.abid
+ assert msg_type == TOX_MESSAGE_TYPE['NORMAL']
+ assert str(message, 'UTF-8') == MSG
+ except Exception as e:
+ LOG_ERROR(f"alices_on_friend_message EXCEPTION {e}")
+ else:
+ LOG_INFO(f"alices_on_friend_message {message}")
+ setattr(self.alice, sSlot, True)
+
+ setattr(self.alice, sSlot, None)
+ self.alice.callback_friend_message(None)
+ try:
+ if self.bob._args.norequest:
+ assert self.both_add_as_friend_norequest()
+ else:
+ assert self.both_add_as_friend()
+ # should we loop until connection status
+ if not self.wait_friend_get_connection_status(self.bob, self.baid, n=3*iN):
+ raise AssertionError(f"bob NOT CONNECTED baid={self.baid}, n={3*iN}")
+ if not self.wait_friend_get_connection_status(self.alice, self.abid, n=3*iN):
+ raise AssertionError(f"alice NOT CONNECTED baid={self.abid}, n={3*iN}")
+
+ self.alice.callback_friend_message(alices_on_friend_message)
+ self.warn_if_no_cb(self.alice, sSlot)
+
+ # dunno - both This client is currently NOT CONNECTED to the friend
+ # ArgumentError: This client is currently not connected to the friend.
+ iMesId = self.bob.friend_send_message(self.baid,
+ TOX_MESSAGE_TYPE['NORMAL'],
+ bytes(MSG, 'UTF-8'))
+ assert iMesId >= 0, "iMesId >= 0"
+ if not self.wait_otox_attrs(self.alice, [sSlot]):
+ raise AssertionError(f"alices_on_friend_message NO {sSlot}")
+ except ArgumentError as e:
+ # ArgumentError('This client is currently NOT CONNECTED to the friend.')
+ # dunno
+ LOG.error(f"test_friend_message ArgumentError {e}")
+ raise
+ except AssertionError as e:
+ LOG.error(f"test_friend_message AssertionError {e}")
+ raise
+ except Exception as e:
+ LOG.error(f"test_friend_message EXCEPTION {e}")
+ raise
+ finally:
+ self.alice.callback_friend_message(None)
+ self.warn_if_cb(self.alice, sSlot)
+ if hasattr(self, 'baid') and self.baid >= 0:
+ self.bob.friend_delete(self.baid)
+ if hasattr(self, 'abid') and self.abid >= 0:
+ self.alice.friend_delete(self.abid)
+
+ @expectedFail('unfinished')
def test_file_transfer(self) -> None: # unfinished
"""
t:file_send
@@ -1526,7 +1553,7 @@ class ToxSuite(unittest.TestCase, WrapperMixin):
except:
pass
- oArgs = oTOX_OARGS
+ oArgs = self.alice._args
opts = oTestsToxOptions(oArgs)
opts.savedata_data = data
opts.savedata_length = len(data)
diff --git a/src/toxygen_wrapper/tests/wrapper_mixin.py b/src/toxygen_wrapper/tests/wrapper_mixin.py
index d56f05f..cfeff60 100644
--- a/src/toxygen_wrapper/tests/wrapper_mixin.py
+++ b/src/toxygen_wrapper/tests/wrapper_mixin.py
@@ -1,5 +1,5 @@
-import ctypes
-import hashlib
+# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
+
import logging
import os
import random
@@ -9,7 +9,7 @@ import time
import threading
from ctypes import *
from typing import Union, Callable
-import tox_wrapper
+
import tox_wrapper.toxcore_enums_and_consts as enums
from tox_wrapper.tox import Tox, UINT32_MAX, ToxError
@@ -29,6 +29,7 @@ ADDR_SIZE = 38 * 2
CLIENT_ID_SIZE = 32 * 2
THRESHOLD = 120 # >25
fSOCKET_TIMEOUT = 15.0
+iLOOP_N = 50
iN = 6
@@ -67,7 +68,7 @@ class WrapperMixin():
self.abid in self.alice.self_get_friend_list():
LOG.warn(f"setUp BOB IS ALREADY IN ALICES FRIEND LIST")
return False
- elif self.alice.self_get_friend_list_size() >= 1:
+ if self.alice.self_get_friend_list_size() >= 1:
LOG.warn(f"setUp ALICE STILL HAS A FRIEND LIST")
return False
return True
@@ -128,6 +129,7 @@ class WrapperMixin():
i = 0
bRet = None
while i <= iMax :
+ i += 1
iRet = otox.group_is_connected(group_number)
if iRet == True or iRet == 0:
bRet = True
@@ -142,8 +144,7 @@ class WrapperMixin():
+" iRet=" +repr(iRet) \
+f" BOBS={otox.mycon_status}" \
+f" last={int(otox.mycon_time)}" )
- i += 1
- self.loop(100)
+ self.loop(iLOOP_N)
else:
bRet = False
@@ -166,9 +167,11 @@ class WrapperMixin():
t:self_get_connection_status
"""
i = 0
+ num = 4
bRet = None
if otox is None: otox = self.bob
while i <= otox._args.test_timeout :
+ i += 1
if (self.alice.mycon_status and self.bob.mycon_status):
bRet = True
break
@@ -195,31 +198,31 @@ class WrapperMixin():
+f" last={int(self.bob.mycon_time)}" )
bRet = True
break
- i += 1
- self.loop(100)
+ self.loop(iLOOP_N)
else:
bRet = False
if bRet or \
( self.bob.self_get_connection_status() != TOX_CONNECTION['NONE'] and \
self.alice.self_get_connection_status() != TOX_CONNECTION['NONE'] ):
- LOG.info(f"loop_until_connected returning True {i}" \
+ LOG.info(f"loop_until_connected returning True i={i}" \
+f" BOB={self.bob.self_get_connection_status()}" \
+f" ALICE={self.alice.self_get_connection_status()}" \
+f" last={int(self.bob.mycon_time)}" )
return True
- else:
- otox._args.test_timeout += 5
- LOG.warning(f"loop_until_connected returning False {i}" \
- +f" BOB={self.bob.self_get_connection_status()}" \
- +f" ALICE={self.alice.self_get_connection_status()}" \
- +f" last={int(self.bob.mycon_time)}" )
- return False
+
+ otox._args.test_timeout += 5
+ LOG.warning(f"loop_until_connected returning False i={i}" \
+ +f" BOB={self.bob.self_get_connection_status()}" \
+ +f" ALICE={self.alice.self_get_connection_status()}" \
+ +f" last={int(self.bob.mycon_time)}" )
+ return False
def wait_objs_attr(self, objs: list, attr: str, fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool:
i = 0
otox = objs[0]
while i <= otox._args.test_timeout:
+ i += 1
if i % 5 == 0:
num = None
j = 0
@@ -228,8 +231,7 @@ class WrapperMixin():
LOG.debug(f"wait_objs_attr {objs} for {attr} {i}")
if all([getattr(obj, attr) for obj in objs]):
return True
- self.loop(100)
- i += 1
+ self.loop(iLOOP_N)
else:
otox._args.test_timeout += 1
LOG.warn(f"wait_objs_attr for {attr} i >= {otox._args.test_timeout}")
@@ -241,6 +243,7 @@ class WrapperMixin():
i = 0
otox = obj
while i <= otox._args.test_timeout:
+ i += 1
if i % 5 == 0:
num = None
j = 0
@@ -255,8 +258,7 @@ class WrapperMixin():
+f" last={int(obj.mycon_time)}")
if all([getattr(obj, attr) is not None for attr in attrs]):
return True
- self.loop(100)
- i += 1
+ self.loop(iLOOP_N)
else:
LOG.warning(f"wait_otox_attrs i >= {otox._args.test_timeout} attrs={attrs} results={[getattr(obj, attr) for attr in attrs]}")
@@ -266,6 +268,7 @@ class WrapperMixin():
i = 0
oRet = None
while i <= self.bob._args.test_timeout:
+ i += 1
if i % 5 == 0:
# every 10 sec add another random nodes to bootstrap
j = i//10 + 1
@@ -287,7 +290,6 @@ class WrapperMixin():
LOG.warning(f"wait_ensure_exec EXCEPTION {e}")
return False
sleep(3)
- i += 1
else:
LOG.error(f"wait_ensure_exec i >= {1*self.bob._args.test_timeout}")
return False
@@ -324,11 +326,11 @@ class WrapperMixin():
def both_add_as_friend(self) -> bool:
if self.bob._args.norequest:
- assert self.bob_add_alice_as_friend()
- assert self.alice_add_bob_as_friend_norequest()
- else:
assert self.bob_add_alice_as_friend_norequest()
assert self.alice_add_bob_as_friend_norequest()
+ else:
+ assert self.bob_add_alice_as_friend()
+ assert self.alice_add_bob_as_friend()
if not hasattr(self, 'baid') or self.baid < 0:
LOG.warn("both_add_as_friend no bob, baid")
if not hasattr(self, 'abid') or self.abid < 0:
@@ -340,9 +342,9 @@ class WrapperMixin():
assert self.bob_add_alice_as_friend_norequest()
if self.bAliceNeedAddBob():
assert self.alice_add_bob_as_friend_norequest()
- if not hasattr(self, 'baid') or self.baid < 0:
+ if not hasattr(self.bob, 'baid') or self.bob.baid < 0:
LOG.warn("both_add_as_friend_norequest no bob, baid")
- if not hasattr(self, 'abid') or self.abid < 0:
+ if not hasattr(self.alice, 'abid') or self.alice.abid < 0:
LOG.warn("both_add_as_friend_norequest no alice, abid")
#: Test last online
@@ -462,7 +464,7 @@ class WrapperMixin():
sSlot = 'friend_status'
setattr(self.bob, sSlot, None)
def bobs_on_friend_status(iTox, friend_id, iStatus, *largs) -> None:
- LOG_INFO(f"bobs_on_friend_status {friend_id} ?>=0" +repr(iStatus))
+ LOG_INFO(f"bobs_on_friend_status {friend_id} ?>=0 iS={iStatus}")
setattr(self.bob, sSlot, False)
sSlot = 'friend_conn_status'
@@ -474,13 +476,12 @@ class WrapperMixin():
sSlot = 'friend_status'
setattr(self.alice, sSlot, None)
def alices_on_friend_status(iTox, friend_id, iStatus, *largs) -> None:
- LOG_INFO(f"alices_on_friend_status {friend_id} ?>=0 " +repr(iStatus))
+ LOG_INFO(f"alices_on_friend_status {friend_id} ?>=0 iS={iStatus}")
setattr(self.alice, sSlot, False)
try:
# need a friend connected?
if not self.get_connection_status():
- LOG.warning(f"test_groups_join NOT CONNECTED")
self.loop_until_connected(self.bob)
LOG.info("bob_add_alice_as_friend_and_status waiting for alice connections")
if not self.wait_otox_attrs(self.alice,
@@ -661,16 +662,16 @@ class WrapperMixin():
def wait_friend_get_connection_status(self, otox, fid:int, n:int = iN) -> int:
i = 0
while i < n:
+ i += 1
iRet = otox.friend_get_connection_status(fid)
if iRet == TOX_CONNECTION['NONE']:
-# LOG.debug(f"wait_friend_get_connection_status NOT CONNECTED i={i} {iRet}")
+ LOG.debug(f"wait_friend_get_connection_status NOT CONNECTED i={i} fid={fid} {iRet}")
self.loop_until_connected(otox)
else:
- LOG.info(f"wait_friend_get_connection_status {iRet}")
+ LOG.info(f"wait_friend_get_connection_status fid={fid} {iRet}")
return True
- i += 1
else:
- LOG.error(f"wait_friend_get_connection_status n={n}")
+ LOG.error(f"wait_friend_get_connection_status fid={fid} n={n}")
return False
def warn_if_no_cb(self, alice, sSlot:str) -> None: