This commit is contained in:
parent
4fc9a23961
commit
eb7287e659
7
Makefile
7
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 \
|
||||
|
@ -8,7 +8,7 @@ import urllib
|
||||
import traceback
|
||||
|
||||
global LOG
|
||||
LOG = logging.getLogger('app.'+'ts')
|
||||
LOG = logging.getLogger('TestS')
|
||||
|
||||
try:
|
||||
import pycurl
|
||||
|
@ -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 '<li><a href="' /tmp/tor.html |sed -e 's/<li><a href="http:../ - /' -e 's/.onion.*//' -e 's/<li id=./ # /' -e 's/".*//' -e '/^--/d' -e '/<li id/d'
|
||||
# This will slow things down 1-2 min each
|
||||
@ -225,19 +223,28 @@ yKNOWN_NODNS = """
|
||||
# - w.digidow.eu
|
||||
# - w.cccs.de
|
||||
|
||||
def oMakeController(sSock:str = '', port:int = 9051):
|
||||
import getpass
|
||||
def oMakeController(sSock:str = '', port:int = 9051, password:[str,None] = None):
|
||||
global oSTEM_CONTROLER
|
||||
from getpass import unix_getpass
|
||||
if sSock and os.path.exists(sSock):
|
||||
controller = Controller.from_socket_file(path=sSock)
|
||||
else:
|
||||
controller = Controller.from_port(port=port)
|
||||
sys.stdout.flush()
|
||||
p = getpass.unix_getpass(prompt='Controller Password: ', stream=sys.stderr)
|
||||
controller.authenticate(p)
|
||||
try:
|
||||
controller.authenticate()
|
||||
except (Exception, MissingPassword):
|
||||
if password is None:
|
||||
password = os.environ.get('TOR_CONTROLLER_PASSWORD', '')
|
||||
if password:
|
||||
p = password
|
||||
else:
|
||||
sys.stdout.flush()
|
||||
p = unix_getpass(prompt='Controller Password: ', stream=sys.stderr)
|
||||
controller.authenticate(p)
|
||||
oSTEM_CONTROLER = controller
|
||||
return controller
|
||||
|
||||
oSTEM_CONTROLER = None
|
||||
def oGetStemController(log_level:int = 10, sock_or_pair:str = '/run/tor/control'):
|
||||
def oGetStemController(log_level:int = 10, sock_or_pair:str = '/run/tor/control', password:[str,None] = None):
|
||||
|
||||
global oSTEM_CONTROLER
|
||||
if oSTEM_CONTROLER: return oSTEM_CONTROLER
|
||||
@ -262,35 +269,27 @@ def oGetStemController(log_level:int = 10, sock_or_pair:str = '/run/tor/control'
|
||||
try:
|
||||
controller.authenticate()
|
||||
except (Exception, MissingPassword):
|
||||
sys.stdout.flush()
|
||||
p = getpass.unix_getpass(prompt='Controller Password: ', stream=sys.stderr)
|
||||
if password is None:
|
||||
password = os.environ.get('TOR_CONTROLLER_PASSWORD', '')
|
||||
if password:
|
||||
p = password
|
||||
else:
|
||||
sys.stdout.flush()
|
||||
p = getpass.unix_getpass(prompt='Controller Password: ', stream=sys.stderr)
|
||||
controller.authenticate(p)
|
||||
oSTEM_CONTROLER = controller
|
||||
LOG.debug(f"{controller}")
|
||||
return oSTEM_CONTROLER
|
||||
|
||||
def bAreWeConnected() -> 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)
|
||||
|
@ -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:
|
||||
|
@ -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 <ip> 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)
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user