update
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run

This commit is contained in:
emdee@spm.plastiras.org 2024-02-10 20:43:34 +00:00
parent 4fc9a23961
commit eb7287e659
6 changed files with 226 additions and 192 deletions

View File

@ -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 \

View File

@ -8,7 +8,7 @@ import urllib
import traceback
global LOG
LOG = logging.getLogger('app.'+'ts')
LOG = logging.getLogger('TestS')
try:
import pycurl

View File

@ -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)

View File

@ -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:

View File

@ -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)

View File

@ -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: