update
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled

This commit is contained in:
emdee@spm.plastiras.org 2024-02-04 01:07:37 +00:00
parent 74a29f7ce3
commit 75ac0b2e07
8 changed files with 122 additions and 88 deletions

1
.gitignore vendored
View File

@ -172,3 +172,4 @@ cython_debug/
*~ *~
.rsync.sh .rsync.sh
.pyanal.out

View File

@ -2,7 +2,7 @@
ROLE=logging ROLE=logging
PYTHONPATH=$PWD/wrapper /var/local/bin/python3.bash `which pyanalyze` \ PYTHONPATH=$PWD/src /var/local/bin/python3.bash `which pyanalyze` \
tox_wrapper/tox.py tox_wrapper/tests/tests_wrapper.py \ src/tox_wrapper/tox.py src/tox_wrapper/tests/tests_wrapper.py \
> .pyanal.out 2>&1 > .pyanal.out 2>&1

View File

@ -1,16 +1,16 @@
#!/bin/sh #!/bin/sh
EXE=/var/local/bin/pydev_pylint.bash EXE=/usr/local/bin/toxcore_pylint.bash
ROLE=logging ROLE=toxcore
$EXE --recursive y --verbose --py-version 3.11 \ $EXE --recursive y --verbose --py-version 3.11 \
--output-format colorized --rcfile .pylint.rc \ --output-format colorized --rcfile .pylint.rc \
-E -f text tox_wrapper/*py tox_wrapper/tests/*py > .pylint.err -E -f text src/tox_wrapper/*py src/tox_wrapper/tests/*py > .pylint.err
retval=$? retval=$?
$EXE --recursive y --verbose --py-version 3.11 \ $EXE --recursive y --verbose --py-version 3.11 \
--output-format colorized --rcfile .pylint.rc \ --output-format colorized --rcfile .pylint.rc \
tox_wrapper/*py tox_wrapper/tests/*py > .pylint.out src/tox_wrapper/*py src/tox_wrapper/tests/*py > .pylint.out
sed -e "/Module 'os' has no/d" \ sed -e "/Module 'os' has no/d" \
-e "/Undefined variable 'app'/d" \ -e "/Undefined variable 'app'/d" \

View File

@ -1,6 +1,8 @@
PREFIX=/usr/local PREFIX=/usr/local
PYTHON=python3.sh PYTHON=python3.sh
PIP=pip3.sh PIP=pip3.sh
iTEST_TIMEOUT=60
fSOCKET_TIMEOUT=15.0
prepare:: prepare::
bash .pylint.sh bash .pylint.sh
@ -21,8 +23,23 @@ help::
$(PYTHON) src/tox_wrapper/tests/tests_wrapper.py --help $(PYTHON) src/tox_wrapper/tests/tests_wrapper.py --help
test:: test::
test_direct::
PYTHONPATH=$${PWD}/src \ PYTHONPATH=$${PWD}/src \
$(PYTHON) src/tox_wrapper/tests/tests_wrapper.py sudo -u bin $(PYTHON) src/tox_wrapper/tests/tests_wrapper.py \
--test_timeout=${iTEST_TIMEOUT} \
--nodes_json=/tmp/toxygen_nodes.json \
--udp_enabled=True \
--trace_enabled=False --loglevel=10
test_proxy::
PYTHONPATH=$${PWD}/src \
$(PYTHON) src/tox_wrapper/tests/tests_wrapper.py \
--test_timeout=${iTEST_TIMEOUT} \
--proxy_host=127.0.0.1 \
--proxy_port=9050 \
--proxy_type=2 \
--nodes_json=$$HOME/.config/tox/DHTnodes.json \
--trace_enabled=False --loglevel=10
clean:: clean::
rm -f .[a-z]* *~ */*~ */*/*~ rm -f .[a-z]* *~ */*~ */*/*~

View File

@ -89,5 +89,8 @@ Others include:
To our point of view, the ability of CTYPEs to follow code in the To our point of view, the ability of CTYPEs to follow code in the
debugger is a crucial advantage. debugger is a crucial advantage.
Up-to-date code is on https://git.plastiras.org/emdee/toxygen_wrapper
Work on this project is suspended until the Work on this project is suspended until the
[MultiDevice](https://git.plastiras.org/emdee/tox_profile/wiki/MultiDevice-Announcements-POC) problem is solved. Fork me! [MultiDevice](https://git.plastiras.org/emdee/tox_profile/wiki/MultiDevice-Announcements-POC) problem is solved. Fork me!

View File

@ -14,6 +14,7 @@ import sys
import time import time
import traceback import traceback
import unittest import unittest
import traceback
from ctypes import * from ctypes import *
from random import Random from random import Random
import functools import functools
@ -46,11 +47,6 @@ from tox_wrapper.tests.support_onions import (is_valid_fingerprint,
oGetStemController, oGetStemController,
sMapaddressResolv, sTorResolve) sMapaddressResolv, sTorResolve)
try:
from user_data.settings import get_user_config_path
except ImportError:
get_user_config_path = None
# LOG=util.log # LOG=util.log
global LOG global LOG
LOG = logging.getLogger() LOG = logging.getLogger()
@ -96,6 +92,7 @@ iTHREAD_TIMEOUT = 1
iTHREAD_SLEEP = 1 iTHREAD_SLEEP = 1
iTHREAD_JOINS = 8 iTHREAD_JOINS = 8
iNODES = 6 iNODES = 6
fSOCKET_TIMEOUT = 15.0
lToxSamplerates = [8000, 12000, 16000, 24000, 48000] lToxSamplerates = [8000, 12000, 16000, 24000, 48000]
lToxSampleratesK = [8, 12, 16, 24, 48] lToxSampleratesK = [8, 12, 16, 24, 48]
@ -192,7 +189,6 @@ def clean_booleans(oArgs) -> None:
else: else:
setattr(oArgs, key, True) setattr(oArgs, key, True)
import traceback
def toxygen_log_cb(_, level: int, source, line: int, func, message, userdata=None): def toxygen_log_cb(_, level: int, source, line: int, func, message, userdata=None):
""" """
* @param level The severity of the log message. * @param level The severity of the log message.
@ -210,6 +206,7 @@ def toxygen_log_cb(_, level: int, source, line: int, func, message, userdata=Non
if type(message) == bytes: if type(message) == bytes:
message = str(message, 'UTF-8') message = str(message, 'UTF-8')
if source == 'network.c': if source == 'network.c':
if line in [944, 660, 781, 789]: return
squelch='network family 10 (probably IPv6) on IPv4 socket' squelch='network family 10 (probably IPv6) on IPv4 socket'
if message.find(squelch) > 0: return if message.find(squelch) > 0: return
if message.find('07 = GET_NODES') > 0: return if message.find('07 = GET_NODES') > 0: return
@ -217,6 +214,8 @@ def toxygen_log_cb(_, level: int, source, line: int, func, message, userdata=Non
squelch='read_tcp_packet recv buffer has' squelch='read_tcp_packet recv buffer has'
if message.find(squelch) > 0: return if message.find(squelch) > 0: return
return return
elif source == 'Messenger.c':
if line in [2691, 2764]: return
LOG_LOG(f"{source}#{line}:{func} {message}") LOG_LOG(f"{source}#{line}:{func} {message}")
except Exception as e: except Exception as e:
LOG_WARN(f"toxygen_log_cb EXCEPTION {e}\n{traceback.format_exc()}") LOG_WARN(f"toxygen_log_cb EXCEPTION {e}\n{traceback.format_exc()}")
@ -240,7 +239,9 @@ def tox_log_cb(_, level:int, source, line:int , func, message, userdata=None) ->
source = str(source, 'UTF-8') source = str(source, 'UTF-8')
if source == 'network.c': if source == 'network.c':
if line in [944, 660]: return if line in [944, 660, 781, 789]: return
# CORE: network.c#789:loglogdata [05 = <unknown> ] T=> 10= 81.169.136.229:33445 (0: OK) | 01000151a988e582...a5x
# CORE: network.c#781:loglogdata [dd = <unknown> ] T=> 128E 51.15.227.109:33445 (11: Resource temporarily unavailable) | d4f98b02ddf79693...76
# root WARNING 3network.c#944:b'send_packet'attempted to send message with network family 10 (probably IPv6) on IPv4 socket # root WARNING 3network.c#944:b'send_packet'attempted to send message with network family 10 (probably IPv6) on IPv4 socket
if message.find('07 = GET_NODES') > 0: return if message.find('07 = GET_NODES') > 0: return
if source == 'TCP_common.c': return if source == 'TCP_common.c': return
@ -298,6 +299,14 @@ def vAddLoggerCallback(tox_options, callback=toxygen_log_cb) -> None:
tox_options.self_logger_cb) tox_options.self_logger_cb)
LOG.debug("toxcore logging enabled") LOG.debug("toxcore logging enabled")
def get_user_config_path():
system = sys.platform
if system == 'windows':
return os.path.join(os.getenv('APPDATA'), 'Tox/')
elif system == 'darwin':
return os.path.join(os.getenv('HOME'), 'Library/Application Support/Tox/')
else:
return os.path.join(os.getenv('HOME'), '.config/tox/')
def oMainArgparser(_=None, iMode=0): def oMainArgparser(_=None, iMode=0):
# 'Mode: 0=chat 1=chat+audio 2=chat+audio+video default: 0' # 'Mode: 0=chat 1=chat+audio 2=chat+audio+video default: 0'
@ -307,11 +316,10 @@ def oMainArgparser(_=None, iMode=0):
bIpV6 = 'True' bIpV6 = 'True'
lIpV6Choices=[bIpV6, 'False'] lIpV6Choices=[bIpV6, 'False']
sNodesJson = os.path.join(os.environ['HOME'], '.config', 'tox', 'DHTnodes.json') sNodesJson = _get_nodes_path(None)
if not os.path.exists(sNodesJson): sNodesJson = '' if not os.path.exists(sNodesJson): sNodesJson = ''
logfile = os.path.join(os.environ.get('TMPDIR', '/tmp'), 'toxygen.log') logfile = os.path.join(os.environ.get('TMPDIR', '/tmp'), 'toxygen.log')
if not os.path.exists(logfile): logfile = ''
parser = argparse.ArgumentParser(add_help=True) parser = argparse.ArgumentParser(add_help=True)
parser.add_argument('--proxy_host', '--proxy-host', type=str, parser.add_argument('--proxy_host', '--proxy-host', type=str,
@ -322,9 +330,9 @@ def oMainArgparser(_=None, iMode=0):
help='proxy port') help='proxy port')
parser.add_argument('--proxy_type', '--proxy-type', default=0, type=int, parser.add_argument('--proxy_type', '--proxy-type', default=0, type=int,
choices=[0,1,2], choices=[0,1,2],
help='proxy type 1=http, 2=socks') help='proxy type 0=noproxy, 1=http, 2=socks')
parser.add_argument('--tcp_port', '--tcp-port', default=0, type=int, parser.add_argument('--tcp_port', '--tcp-port', default=0, type=int,
help='tcp port') help='tcp relay server port')
parser.add_argument('--udp_enabled', type=str, default='True', parser.add_argument('--udp_enabled', type=str, default='True',
choices=['True', 'False'], choices=['True', 'False'],
help='En/Disable udp') help='En/Disable udp')
@ -363,6 +371,8 @@ def oMainArgparser(_=None, iMode=0):
# parser.add_argument('--save_history', type=str, default='True', # parser.add_argument('--save_history', type=str, default='True',
# choices=['True', 'False'], # choices=['True', 'False'],
# help='En/Disable saving history') # help='En/Disable saving history')
parser.add_argument('--socket_timeout',type=float, default=fSOCKET_TIMEOUT,
help='Socket timeout set during bootstrap')
return parser return parser
def get_video_indexes() -> list: def get_video_indexes() -> list:
@ -586,16 +596,14 @@ def lSdSamplerates(iDev:int) -> list:
supported_samplerates.append(fs) supported_samplerates.append(fs)
return supported_samplerates return supported_samplerates
def _get_nodes_path(oArgs:str): def _get_nodes_path(oArgs):
if oArgs and hasattr(oArgs, 'nodes_json') and \ if oArgs and hasattr(oArgs, 'nodes_json') and \
oArgs.nodes_json and os.path.isfile(oArgs.nodes_json): oArgs.nodes_json and os.path.isfile(oArgs.nodes_json):
default = oArgs.nodes_json default = oArgs.nodes_json
elif get_user_config_path:
default = os.path.join(get_user_config_path(), 'toxygen_nodes.json')
else: else:
# Windwoes default = os.path.join(get_user_config_path(), 'toxygen_nodes.json')
default = os.path.join(os.getenv('HOME'), '.config', 'tox', 'toxygen_nodes.json') # default = os.path.join(os.getenv('HOME'), '.config', 'tox', 'toxygen_nodes.json')
LOG.debug("_get_nodes_path: " +default) LOG.debug(f"_get_nodes_path: {default}")
return default return default
DEFAULT_NODES_COUNT = 8 DEFAULT_NODES_COUNT = 8
@ -604,7 +612,7 @@ global aNODES
aNODES = {} aNODES = {}
# @functools.lru_cache(maxsize=12) TypeError: unhashable type: 'Namespace' # @functools.lru_cache(maxsize=12) TypeError: unhashable type: 'Namespace'
def generate_nodes(oArgs=None, def generate_nodes(oArgs,
nodes_count:int = DEFAULT_NODES_COUNT, nodes_count:int = DEFAULT_NODES_COUNT,
ipv:str = 'ipv4', ipv:str = 'ipv4',
udp_not_tcp=True) -> dict: udp_not_tcp=True) -> dict:
@ -614,7 +622,7 @@ def generate_nodes(oArgs=None,
if sKey in aNODES and aNODES[sKey]: if sKey in aNODES and aNODES[sKey]:
return aNODES[sKey] return aNODES[sKey]
sFile = _get_nodes_path(oArgs) sFile = _get_nodes_path(oArgs)
assert os.path.exists(sFile), sFile # assert os.path.isfile(sFile), sFile
lNodes = generate_nodes_from_file(sFile, lNodes = generate_nodes_from_file(sFile,
nodes_count=nodes_count, nodes_count=nodes_count,
ipv=ipv, ipv=ipv,
@ -639,9 +647,6 @@ I had a conversation with @irungentoo on IRC about whether we really need to cal
if key in aNODES_CACHE: if key in aNODES_CACHE:
sorted_nodes = aNODES_CACHE[key] sorted_nodes = aNODES_CACHE[key]
else: else:
if not os.path.exists(sFile):
LOG.error("generate_nodes_from_file file not found " +sFile)
return []
try: try:
with open(sFile, 'rt') as fl: with open(sFile, 'rt') as fl:
json_nodes = json.loads(fl.read())['nodes'] json_nodes = json.loads(fl.read())['nodes']
@ -824,9 +829,9 @@ def sDNSLookup(host:str) -> str:
aHOSTS[host] = ip aHOSTS[host] = ip
return ip return ip
def bootstrap_udp(lelts:list, lToxes:list, oArgs=None) -> None: def bootstrap_udp(lelts:list, lToxes:list[int], oArgs=None, fsocket_timeout:float = fSOCKET_TIMEOUT) -> None:
lelts = lDNSClean(lelts) lelts = lDNSClean(lelts)
socket.setdefaulttimeout(15.0) socket.setdefaulttimeout(fsocket_timeout)
for oTox in lToxes: for oTox in lToxes:
random.shuffle(lelts) random.shuffle(lelts)
if hasattr(oTox, 'oArgs'): if hasattr(oTox, 'oArgs'):
@ -868,7 +873,8 @@ def bootstrap_udp(lelts:list, lToxes:list, oArgs=None) -> None:
# LOG.debug(f'bootstrap_udp to {host} not connected') # LOG.debug(f'bootstrap_udp to {host} not connected')
pass pass
def bootstrap_tcp(lelts:list, lToxes:list, oArgs=None) -> None: def bootstrap_tcp(lelts:list, lToxes:list, oArgs=None, fsocket_timeout:float = fSOCKET_TIMEOUT) -> None:
socket.setdefaulttimeout(fsocket_timeout)
lelts = lDNSClean(lelts) lelts = lDNSClean(lelts)
for oTox in lToxes: for oTox in lToxes:
if hasattr(oTox, 'oArgs'): oArgs = oTox.oArgs if hasattr(oTox, 'oArgs'): oArgs = oTox.oArgs

View File

@ -112,7 +112,9 @@ else:
ADDR_SIZE = 38 * 2 ADDR_SIZE = 38 * 2
CLIENT_ID_SIZE = 32 * 2 CLIENT_ID_SIZE = 32 * 2
THRESHOLD = 60 # >25 THRESHOLD = 120 # >25
fSOCKET_TIMEOUT = 15.0
iN = 6 iN = 6
global oTOX_OPTIONS global oTOX_OPTIONS
@ -220,7 +222,7 @@ def prepare(self):
self.bob.mycon_time = time.time() self.bob.mycon_time = time.time()
try: try:
if status != TOX_CONNECTION['NONE']: if status != TOX_CONNECTION['NONE']:
LOG_DEBUG(f"bobs_on_self_connection_status TRUE {status}" \ LOG_INFO(f"bobs_on_self_connection_status TRUE {status}" \
+f" last={int(self.bob.mycon_time)}" ) +f" last={int(self.bob.mycon_time)}" )
self.bob.mycon_status = True self.bob.mycon_status = True
else: else:
@ -232,7 +234,6 @@ def prepare(self):
else: else:
if self.bob.self_get_connection_status() != status: if self.bob.self_get_connection_status() != status:
LOG_WARN(f"bobs_on_self_connection_status DISAGREE {status}") LOG_WARN(f"bobs_on_self_connection_status DISAGREE {status}")
self.bob.dht_connected = status
def alices_on_self_connection_status(iTox, connection_state: int, *args) -> None: def alices_on_self_connection_status(iTox, connection_state: int, *args) -> None:
#FixMe connection_num #FixMe connection_num
@ -241,16 +242,15 @@ def prepare(self):
self.alice.mycon_time = time.time() self.alice.mycon_time = time.time()
try: try:
if status != TOX_CONNECTION['NONE']: if status != TOX_CONNECTION['NONE']:
LOG_DEBUG(f"alices_on_self_connection_status TRUE {status}" \ LOG_INFO(f"alices_on_self_connection_status TRUE {status}" \
+f" last={int(self.alice.mycon_time)}" ) +f" last={int(self.alice.mycon_time)}" )
self.alice.mycon_status = True self.alice.mycon_status = True
else: else:
LOG_WARN(f"alices_on_self_connection_status FALSE {status}" \ LOG_DEBUG(f"alices_on_self_connection_status FALSE {status}" \
+f" last={int(self.alice.mycon_time)}" ) +f" last={int(self.alice.mycon_time)}" )
self.alice.mycon_status = False self.alice.mycon_status = False
except Exception as e: except Exception as e:
LOG_ERROR(f"alices_on_self_connection_status error={e}") LOG_ERROR(f"alices_on_self_connection_status error={e}")
self.alice.dht_connected = status
opts = oTestsToxOptions(oTOX_OARGS) opts = oTestsToxOptions(oTOX_OARGS)
global bUSE_NOREQUEST global bUSE_NOREQUEST
@ -268,7 +268,7 @@ def prepare(self):
LOG.info(f"toxcore trace_enabled") LOG.info(f"toxcore trace_enabled")
ts.vAddLoggerCallback(opts) ts.vAddLoggerCallback(opts)
else: else:
LOG.debug(f"toxcore trace_enabled") LOG.debug(f"toxcore trace_enabled=False")
bob = BobTox(opts, app=oAPP) bob = BobTox(opts, app=oAPP)
bob.oArgs = opts bob.oArgs = opts
@ -382,10 +382,10 @@ class ToxSuite(unittest.TestCase):
def run(self, result=None) -> None: def run(self, result=None) -> None:
""" Stop after first error """ """ Stop after first error """
if not result.errors: if result and not result.errors:
super(ToxSuite, self).run(result) super(ToxSuite, self).run(result)
def get_connection_status(self) -> None: def get_connection_status(self) -> bool:
if self.bob.mycon_time <= 1 or self.alice.mycon_time <= 1: if self.bob.mycon_time <= 1 or self.alice.mycon_time <= 1:
pass pass
# drop through # drop through
@ -412,7 +412,7 @@ class ToxSuite(unittest.TestCase):
self.bob.iterate() self.bob.iterate()
sleep(interval / 1000.0) sleep(interval / 1000.0)
def call_bootstrap(self, num: Union[int, None] = None, lToxes:list[int] =None, i:int =0) -> None: def call_bootstrap(self, num: Union[int, None] = None, lToxes:Union[list[int], None] =None, i:int =0, fsocket_timeout:float = fSOCKET_TIMEOUT) -> None:
if num == None: num=ts.iNODES if num == None: num=ts.iNODES
if lToxes is None: if lToxes is None:
lToxes = [self.alice, self.bob] lToxes = [self.alice, self.bob]
@ -428,13 +428,13 @@ class ToxSuite(unittest.TestCase):
else: else:
lElts = self.lUdp[:num+i] lElts = self.lUdp[:num+i]
LOG.debug(f"call_bootstrap ts.bootstrap_udp {len(lElts)}") LOG.debug(f"call_bootstrap ts.bootstrap_udp {len(lElts)}")
ts.bootstrap_udp(lElts, lToxes) ts.bootstrap_udp(lElts, lToxes, fsocket_timeout=fsocket_timeout)
random.shuffle(self.lTcp) random.shuffle(self.lTcp)
lElts = self.lTcp[:num+i] lElts = self.lTcp[:num+i]
LOG.debug(f"call_bootstrap ts.bootstrap_tcp {len(lElts)}") LOG.debug(f"call_bootstrap ts.bootstrap_tcp {len(lElts)}")
ts.bootstrap_tcp(lElts, lToxes) ts.bootstrap_tcp(lElts, lToxes, fsocket_timeout=fsocket_timeout)
def group_until_connected(self, otox, group_number:int, num: Union[int, None] = None, iMax:int = THRESHOLD) -> None: def group_until_connected(self, otox, group_number:int, num: Union[int, None] = None, iMax:int = THRESHOLD, fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool:
""" """
""" """
i = 0 i = 0
@ -446,7 +446,7 @@ class ToxSuite(unittest.TestCase):
break break
if i % 5 == 0: if i % 5 == 0:
j = i//5 j = i//5
self.call_bootstrap(num, lToxes=None, i=j) self.call_bootstrap(num, lToxes=None, i=j, fsocket_timeout=fsocket_timeout)
s = '' s = ''
if i == 0: s = '\n' if i == 0: s = '\n'
LOG.info(s+"group_until_connected " \ LOG.info(s+"group_until_connected " \
@ -472,7 +472,7 @@ class ToxSuite(unittest.TestCase):
+f" last={int(otox.mycon_time)}" ) +f" last={int(otox.mycon_time)}" )
return False return False
def loop_until_connected(self, num: Union[int, None] = None) -> None: def loop_until_connected(self, num: Union[int, None] = None, fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool:
""" """
t:on_self_connection_status t:on_self_connection_status
t:self_get_connection_status t:self_get_connection_status
@ -486,7 +486,7 @@ class ToxSuite(unittest.TestCase):
break break
if i % 5 == 0: if i % 5 == 0:
j = i//5 j = i//5
self.call_bootstrap(num, lToxes=None, i=j) self.call_bootstrap(num, lToxes=None, i=j, fsocket_timeout=fsocket_timeout)
s = '' s = ''
if i == 0: s = '\n' if i == 0: s = '\n'
LOG.info(s+"loop_until_connected " \ LOG.info(s+"loop_until_connected " \
@ -528,7 +528,7 @@ class ToxSuite(unittest.TestCase):
+f" last={int(self.bob.mycon_time)}" ) +f" last={int(self.bob.mycon_time)}" )
return False return False
def wait_objs_attr(self, objs: list, attr: str) -> bool: def wait_objs_attr(self, objs: list, attr: str, fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool:
global THRESHOLD global THRESHOLD
i = 0 i = 0
while i <= THRESHOLD: while i <= THRESHOLD:
@ -536,7 +536,7 @@ class ToxSuite(unittest.TestCase):
num = None num = None
j = 0 j = 0
j = i//5 j = i//5
self.call_bootstrap(num, objs, i=j) self.call_bootstrap(num, lToxes=objs, i=j, fsocket_timeout=fsocket_timeout)
LOG.debug(f"wait_objs_attr {objs} for {attr} {i}") LOG.debug(f"wait_objs_attr {objs} for {attr} {i}")
if all([getattr(obj, attr) for obj in objs]): if all([getattr(obj, attr) for obj in objs]):
return True return True
@ -548,7 +548,7 @@ class ToxSuite(unittest.TestCase):
return all([getattr(obj, attr) is not None for obj in objs]) return all([getattr(obj, attr) is not None for obj in objs])
def wait_otox_attrs(self, obj, attrs: list[str]) -> bool: def wait_otox_attrs(self, obj, attrs: list[str], fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool:
assert all(attrs), f"wait_otox_attrs {attrs}" assert all(attrs), f"wait_otox_attrs {attrs}"
i = 0 i = 0
while i <= THRESHOLD: while i <= THRESHOLD:
@ -559,7 +559,7 @@ class ToxSuite(unittest.TestCase):
num = 4 num = 4
j = i//5 j = i//5
if obj.self_get_connection_status() == TOX_CONNECTION['NONE']: if obj.self_get_connection_status() == TOX_CONNECTION['NONE']:
self.call_bootstrap(num, [obj], i=j) self.call_bootstrap(num, lToxes=[obj], i=j, fsocket_timeout=fsocket_timeout)
LOG.debug(f"wait_otox_attrs {obj.name} for {attrs} {i}" \ LOG.debug(f"wait_otox_attrs {obj.name} for {attrs} {i}" \
+f" last={int(obj.mycon_time)}") +f" last={int(obj.mycon_time)}")
if all([getattr(obj, attr) is not None for attr in attrs]): if all([getattr(obj, attr) is not None for attr in attrs]):
@ -571,13 +571,13 @@ class ToxSuite(unittest.TestCase):
return all([getattr(obj, attr) for attr in attrs]) return all([getattr(obj, attr) for attr in attrs])
def wait_ensure_exec(self, method, args:list) -> bool: def wait_ensure_exec(self, method, args:list, fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool:
i = 0 i = 0
oRet = None oRet = None
while i <= THRESHOLD: while i <= THRESHOLD:
if i % 5 == 0: if i % 5 == 0:
j = i//5 j = i//5
self.call_bootstrap(num=None, lToxes=None, i=j) self.call_bootstrap(num=None, lToxes=None, i=j, fsocket_timeout=fsocket_timeout)
LOG.debug("wait_ensure_exec " \ LOG.debug("wait_ensure_exec " \
+" " +str(method) +" " +str(method)
+" " +str(i)) +" " +str(i))
@ -605,7 +605,6 @@ class ToxSuite(unittest.TestCase):
def bob_add_alice_as_friend_norequest(self) -> bool: def bob_add_alice_as_friend_norequest(self) -> bool:
if not self.bBobNeedAlice(): return True if not self.bBobNeedAlice(): return True
MSG = 'Hi, this is Bob.'
iRet = self.bob.friend_add_norequest(self.alice._address) iRet = self.bob.friend_add_norequest(self.alice._address)
if iRet < 0: if iRet < 0:
return False return False
@ -674,7 +673,6 @@ class ToxSuite(unittest.TestCase):
message_data, message_data,
message_data_size, message_data_size,
*largs) -> None: *largs) -> None:
LOG_DEBUG(f"alices_on_friend_request: " +repr(message_data))
try: try:
assert str(message_data, 'UTF-8') == MSG assert str(message_data, 'UTF-8') == MSG
LOG_INFO(f"alices_on_friend_request: {sSlot} = True ") LOG_INFO(f"alices_on_friend_request: {sSlot} = True ")
@ -858,7 +856,7 @@ class ToxSuite(unittest.TestCase):
LOG.info(f"group pK={sPk} iGrp={iGrp} numg={otox.group_get_number_groups()}") LOG.info(f"group pK={sPk} iGrp={iGrp} numg={otox.group_get_number_groups()}")
return iGrp return iGrp
def otox_verify_group(self, otox, iGrp) -> int: def otox_verify_group(self, otox, iGrp) -> None:
""" """
group_self_get_name group_self_get_name
group_self_get_peer_id group_self_get_peer_id
@ -1065,14 +1063,14 @@ class ToxSuite(unittest.TestCase):
else: else:
LOG.warning(f"bootstrap_local_netstat NOT {port} iStatus={iStatus}") LOG.warning(f"bootstrap_local_netstat NOT {port} iStatus={iStatus}")
def test_bootstrap_local(self) -> None: # works def test_bootstrap_local(self, fsocket_timeout:float = fSOCKET_TIMEOUT) -> bool: # works
""" """
t:call_bootstrap t:call_bootstrap
t:add_tcp_relay t:add_tcp_relay
t:self_get_dht_id t:self_get_dht_id
""" """
# get port from /etc/tox-bootstrapd.conf 33445 # get port from /etc/tox-bootstrapd.conf 33445
self.call_bootstrap() self.call_bootstrap(fsocket_timeout=fsocket_timeout)
# ts.bootstrap_local(self, self.lUdp) # ts.bootstrap_local(self, self.lUdp)
i = 0 i = 0
iStatus = -1 iStatus = -1
@ -1118,7 +1116,7 @@ class ToxSuite(unittest.TestCase):
lRetval = [] lRetval = []
random.shuffle(lElts) random.shuffle(lElts)
# assert # assert
ts.bootstrap_iNmapInfo(lElts, oTOX_OARGS, bIS_LOCAL, iNODES=8) ts.bootstrap_iNmapInfo(lElts, oTOX_OARGS, "tcp4", bIS_LOCAL=bIS_LOCAL, iNODES=8)
def test_self_get_secret_key(self) -> None: # works def test_self_get_secret_key(self) -> None: # works
""" """
@ -1937,7 +1935,6 @@ class ToxSuite(unittest.TestCase):
else: else:
assert self.both_add_as_friend() assert self.both_add_as_friend()
FRIEND_NUMBER = self.baid
FILE_NUMBER = 1 FILE_NUMBER = 1
FILE = os.urandom(1024 * 1024) FILE = os.urandom(1024 * 1024)
FILE_NAME = b"/tmp/test.bin" FILE_NAME = b"/tmp/test.bin"
@ -2114,6 +2111,7 @@ class ToxSuite(unittest.TestCase):
""" """
# Fatal Python error: Aborted # Fatal Python error: Aborted
# "/var/local/src/toxygen_wrapper/wrapper/tox.py", line 180 in kill # "/var/local/src/toxygen_wrapper/wrapper/tox.py", line 180 in kill
global oTOX_OARGS
assert self.alice.get_savedata_size() > 0 assert self.alice.get_savedata_size() > 0
data = self.alice.get_savedata() data = self.alice.get_savedata()
@ -2190,7 +2188,7 @@ def oTestsToxOptions(oArgs):
tox_options.contents.proxy_type = int(oArgs.proxy_type) tox_options.contents.proxy_type = int(oArgs.proxy_type)
tox_options.contents.proxy_host = bytes(oArgs.proxy_host, 'UTF-8') tox_options.contents.proxy_host = bytes(oArgs.proxy_host, 'UTF-8')
tox_options.contents.proxy_port = int(oArgs.proxy_port) tox_options.contents.proxy_port = int(oArgs.proxy_port)
tox_options.contents.udp_enabled = False tox_options.contents.udp_enabled = oArgs.udp_enabled = False
else: else:
tox_options.contents.udp_enabled = oArgs.udp_enabled tox_options.contents.udp_enabled = oArgs.udp_enabled
if not os.path.exists('/proc/sys/net/ipv6'): if not os.path.exists('/proc/sys/net/ipv6'):
@ -2224,18 +2222,18 @@ def oTestsToxOptions(oArgs):
return tox_options return tox_options
def oArgparse(lArgv): def oArgparse(lArgv):
global THRESHOLD
parser = ts.oMainArgparser() parser = ts.oMainArgparser()
parser.add_argument('--norequest',type=str, default='False', parser.add_argument('--norequest',type=str, default='False',
choices=['True','False'], choices=['True','False'],
help='Use _norequest') help='Use _norequest during testing')
parser.add_argument('--test_timeout',type=int, default=THRESHOLD,
help='Test timeout during testing')
parser.add_argument('profile', type=str, nargs='?', default=None, parser.add_argument('profile', type=str, nargs='?', default=None,
help='Path to Tox profile') help='Path to Tox profile')
oArgs = parser.parse_args(lArgv) oArgs = parser.parse_args(lArgv)
ts.clean_booleans(oArgs)
for key in ts.lBOOLEANS: THRESHOLD = oArgs.test_timeout
if key not in oArgs: continue
val = getattr(oArgs, key)
setattr(oArgs, key, bool(val))
if hasattr(oArgs, 'sleep'): if hasattr(oArgs, 'sleep'):
if oArgs.sleep == 'qt': if oArgs.sleep == 'qt':
@ -2249,10 +2247,13 @@ def oArgparse(lArgv):
def main(lArgs=None) -> int: def main(lArgs=None) -> int:
global oTOX_OARGS global oTOX_OARGS
global bIS_LOCAL
global THRESHOLD
if lArgs is None: lArgs = sys.argv[1:] if lArgs is None: lArgs = sys.argv[1:]
oArgs = oArgparse(lArgs) oArgs = oArgparse(lArgs)
global bIS_LOCAL
bIS_LOCAL = oArgs.network in ['newlocal', 'localnew', 'local'] bIS_LOCAL = oArgs.network in ['newlocal', 'localnew', 'local']
THRESHOLD = oArgs.test_timeout
oTOX_OARGS = oArgs oTOX_OARGS = oArgs
setattr(oTOX_OARGS, 'bIS_LOCAL', bIS_LOCAL) setattr(oTOX_OARGS, 'bIS_LOCAL', bIS_LOCAL)
bIS_LOCAL = True bIS_LOCAL = True

View File

@ -1,8 +1,9 @@
#!/var/local/bin/python3.bash #!/var/local/bin/python3.bash
# -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*- # -*- mode: python; indent-tabs-mode: nil; py-indent-offset: 4; coding: utf-8 -*-
# A work in progress - chat works. # A work in progress - chat works, but I don't think AV does.
""" echo.py features
""" echo.py a basic Tox echo service. Features:
- accept friend request - accept friend request
- echo back friend message - echo back friend message
# - accept and answer friend call request # - accept and answer friend call request
@ -17,6 +18,7 @@ import threading
import random import random
from ctypes import * from ctypes import *
import time import time
from typing import Union, Callable
# LOG=util.log # LOG=util.log
global LOG global LOG
@ -38,7 +40,7 @@ from tox_wrapper.toxcore_enums_and_consts import TOX_CONNECTION, TOX_USER_STATUS
import tox_wrapper.tests.support_testing as ts import tox_wrapper.tests.support_testing as ts
from tox_wrapper.tests.support_testing import oMainArgparser from tox_wrapper.tests.support_testing import oMainArgparser
def sleep(fSec): def sleep(fSec) -> None:
if 'QtCore' in globals(): if 'QtCore' in globals():
if fSec > .000001: QtCore.QThread.msleep(fSec) if fSec > .000001: QtCore.QThread.msleep(fSec)
QtCore.QCoreApplication.processEvents() QtCore.QCoreApplication.processEvents()
@ -74,26 +76,30 @@ else:
super(AV, self).__init__(core) super(AV, self).__init__(core)
self.core = self.get_tox() self.core = self.get_tox()
def on_call(self, fid, audio_enabled, video_enabled) -> None: def on_call(self, fid:int, audio_enabled:bool, video_enabled:bool) -> None:
LOG.info("Incoming %s call from %d:%s ..." % ( LOG.info("Incoming %s call from %d:%s ..." % (
"video" if video_enabled else "audio", fid, "video" if video_enabled else "audio",
fid,
self.core.friend_get_name(fid))) self.core.friend_get_name(fid)))
bret = self.answer(fid, 48, 64) bret = self.answer(fid, 48, 64)
LOG.info(f"Answered, in call... {bret}") LOG.info(f"Answered, in call... {bret}")
def on_call_state(self, fid, state) -> None: def on_call_state(self, fid:int, state:int) -> None:
LOG.info('call state:fn=%d, state=%d' % (fid, state)) LOG.info('call state:fn=%d, state=%d' % (fid, state))
def on_audio_bit_rate(self, fid, audio_bit_rate) -> None: def on_audio_bit_rate(self, fid:int, audio_bit_rate:int) -> None:
LOG.info('audio bit rate status: fn=%d, abr=%d' % LOG.info('audio bit rate status: fn=%d, abr=%d' %
(fid, audio_bit_rate)) (fid, audio_bit_rate))
def on_video_bit_rate(self, fid, video_bit_rate) -> None: def on_video_bit_rate(self, fid:int, video_bit_rate:int) -> None:
LOG.info('video bit rate status: fn=%d, vbr=%d' % LOG.info('video bit rate status: fn=%d, vbr=%d' %
(fid, video_bit_rate)) (fid, video_bit_rate))
def on_audio_receive_frame(self, fid, pcm, sample_count, def on_audio_receive_frame(self, fid:int,
channels, sampling_rate) -> None: pcm:int,
sample_count:int,
channels:int,
sampling_rate:int) -> None:
# LOG.info('audio frame: %d, %d, %d, %d' % # LOG.info('audio frame: %d, %d, %d, %d' %
# (fid, sample_count, channels, sampling_rate)) # (fid, sample_count, channels, sampling_rate))
# LOG.info('pcm len:%d, %s' % (len(pcm), str(type(pcm)))) # LOG.info('pcm len:%d, %s' % (len(pcm), str(type(pcm))))
@ -104,7 +110,7 @@ else:
if bret is False: if bret is False:
LOG.error('on_audio_receive_frame error.') LOG.error('on_audio_receive_frame error.')
def on_video_receive_frame(self, fid, width, height, frame, u, v) -> None: def on_video_receive_frame(self, fid:int, width:int, height:int, frame, u, v) -> None:
LOG.info('video frame: %d, %d, %d, ' % (fid, width, height)) LOG.info('video frame: %d, %d, %d, ' % (fid, width, height))
sys.stdout.write('*') sys.stdout.write('*')
sys.stdout.flush() sys.stdout.flush()
@ -116,12 +122,12 @@ else:
self.iterate() self.iterate()
def save_to_file(tox, fname): def save_to_file(tox, fname) -> None:
data = tox.get_savedata() data = tox.get_savedata()
with open(fname, 'wb') as f: with open(fname, 'wb') as f:
f.write(data) f.write(data)
def load_from_file(fname): def load_from_file(fname:str):
assert os.path.exists(fname) assert os.path.exists(fname)
return open(fname, 'rb').read() return open(fname, 'rb').read()
@ -261,20 +267,20 @@ class EchoBot():
LOG.info('Ending loop.') LOG.info('Ending loop.')
def iterate(self, n=100) -> None: def iterate(self, n:int = 100) -> None:
interval = self._tox.iteration_interval() interval = self._tox.iteration_interval()
for i in range(n): for i in range(n):
self._tox.iterate() self._tox.iterate()
sleep(interval / 1000.0) sleep(interval / 1000.0)
self._tox.iterate() self._tox.iterate()
def on_friend_request(self, pk, message) -> None: def on_friend_request(self, pk: Union[bytes,str], message: Union[bytes,str]) -> None:
LOG.debug('Friend request from %s: %s' % (pk, message)) LOG.debug('Friend request from %s: %s' % (pk, message))
self._tox.friend_add_norequest(pk) self._tox.friend_add_norequest(pk)
LOG.info('on_friend_request Accepted.') LOG.info('on_friend_request Accepted.')
save_to_file(self._tox, sDATA_FILE) save_to_file(self._tox, sDATA_FILE)
def on_friend_message(self, friendId, message_type , message) -> None: def on_friend_message(self, friendId:int , message_type, message: Union[bytes,str]) -> None:
name = self._tox.friend_get_name(friendId) name = self._tox.friend_get_name(friendId)
LOG.debug(f"{name}, {message}, {message_type}") LOG.debug(f"{name}, {message}, {message_type}")
yMessage = bytes(message, 'UTF-8') yMessage = bytes(message, 'UTF-8')