From 1aa831cbd6c292f134d8b2aa2527a310085ad351 Mon Sep 17 00:00:00 2001 From: emdee Date: Fri, 14 Jul 2023 14:07:08 +0000 Subject: [PATCH] Refactored tests --- wrapper/tox.c-toxcore.missing | 80 -- wrapper/tox.py | 55 +- wrapper_tests/support_onions.py | 164 +++- wrapper_tests/support_testing.py | 165 ++-- wrapper_tests/tests_wrapper.py | 1197 +++++++++++++++++------------- 5 files changed, 992 insertions(+), 669 deletions(-) delete mode 100644 wrapper/tox.c-toxcore.missing diff --git a/wrapper/tox.c-toxcore.missing b/wrapper/tox.c-toxcore.missing deleted file mode 100644 index 82fd0e7..0000000 --- a/wrapper/tox.c-toxcore.missing +++ /dev/null @@ -1,80 +0,0 @@ -tox_version_major -tox_version_minor -tox_version_patch -tox_version_is_compatible -tox_public_key_size -tox_secret_key_size -tox_conference_uid_size -tox_conference_id_size -tox_nospam_size -tox_address_size -tox_max_name_length -tox_max_status_message_length -tox_max_friend_request_length -tox_max_message_length -tox_max_custom_packet_size -tox_hash_length -tox_file_id_length -tox_max_filename_length -tox_max_hostname_length -tox_options_get_ipv6_enabled -tox_options_get_udp_enabled -tox_options_get_local_discovery_enabled -tox_options_get_dht_announcements_enabled -tox_options_get_proxy_type -tox_options_get_proxy_port -tox_options_get_start_port -tox_options_get_end_port -tox_options_get_tcp_port -tox_options_get_hole_punching_enabled -tox_options_get_savedata_type -tox_options_get_savedata_length -tox_options_get_experimental_thread_safety -tox_file_seek -tox_callback_conference_connected -tox_callback_conference_message -tox_callback_conference_title -tox_callback_conference_peer_list_changed -tox_conference_new -tox_conference_delete -tox_conference_peer_count -tox_conference_peer_get_name_size -tox_conference_peer_get_name -tox_conference_peer_get_public_key -tox_conference_peer_number_is_ours -tox_conference_offline_peer_count -tox_conference_offline_peer_get_name_size -tox_conference_offline_peer_get_name -tox_conference_offline_peer_get_public_key -tox_conference_offline_peer_get_last_active -tox_conference_set_max_offline -tox_conference_invite -tox_conference_join -tox_conference_send_message -tox_conference_get_title_size -tox_conference_get_title -tox_conference_set_title -tox_conference_get_chatlist_size -tox_conference_get_chatlist -tox_conference_get_type -tox_conference_get_id -tox_conference_by_id -tox_conference_get_uid -tox_conference_by_uid -tox_group_max_topic_length -tox_group_max_part_length -tox_group_max_group_name_length -tox_group_max_password_size -tox_group_chat_id_size -tox_group_peer_public_key_size -tox_group_peer_get_connection_status -tox_group_get_voice_state -tox_callback_group_voice_state -tox_group_get_topic_lock -tox_callback_group_topic_lock -tox_group_send_custom_private_packet -tox_callback_group_custom_private_packet -tox_group_founder_set_topic_lock -tox_group_founder_set_voice_state -tox_group_set_ignore -tox_group_mod_kick_peer diff --git a/wrapper/tox.py b/wrapper/tox.py index 360d957..fec93c7 100644 --- a/wrapper/tox.py +++ b/wrapper/tox.py @@ -175,7 +175,7 @@ class Tox: def kill(self): if hasattr(self, 'AV'): del self.AV - LOG_DEBUG(f"tox_kill") + LOG_INFO(f"tox_kill") try: Tox.libtoxcore.tox_kill(self._tox_pointer) except Exception as e: @@ -305,7 +305,7 @@ class Tox: raise ArgumentError('One of the arguments to the function was NULL when it was not expected.') if tox_err_bootstrap == TOX_ERR_BOOTSTRAP['BAD_HOST']: raise ArgumentError('The address could not be resolved to an IP ' - 'address, or the IP address passed was invalid.') + 'address, or the address passed was invalid.') if tox_err_bootstrap == TOX_ERR_BOOTSTRAP['BAD_PORT']: raise ArgumentError('The port passed was invalid. The valid port range is (1, 65535).') # me - this seems wrong - should be False @@ -763,7 +763,8 @@ class Tox: """ Checks if a friend with the given friend number exists and returns true if it does. """ - return bool(Tox.libtoxcore.tox_friend_exists(self._tox_pointer, c_uint32(friend_number))) + # bool() -> TypeError: 'str' object cannot be interpreted as an integer + return Tox.libtoxcore.tox_friend_exists(self._tox_pointer, c_uint32(friend_number)) def self_get_friend_list_size(self): """ @@ -1154,24 +1155,28 @@ class Tox: raise ToxError('The function did not return OK for set typing.') def friend_send_message(self, friend_number, message_type, message): - """ - Send a text chat message to an online friend. + """Send a text chat message to an online friend. This function creates a chat message packet and pushes it into the send queue. - The message length may not exceed TOX_MAX_MESSAGE_LENGTH. Larger messages must be split by the client and sent - as separate messages. Other clients can then reassemble the fragments. Messages may not be empty. + The message length may not exceed + TOX_MAX_MESSAGE_LENGTH. Larger messages must be split by the + client and sent as separate messages. Other clients can then + reassemble the fragments. Messages may not be empty. - The return value of this function is the message ID. If a read receipt is received, the triggered - `friend_read_receipt` event will be passed this message ID. + The return value of this function is the message ID. If a read + receipt is received, the triggered `friend_read_receipt` event + will be passed this message ID. - Message IDs are unique per friend. The first message ID is 0. Message IDs are incremented by 1 each time a - message is sent. If UINT32_MAX messages were sent, the next message ID is 0. + Message IDs are unique per friend. The first message ID is 0. + Message IDs are incremented by 1 each time a message is sent. + If UINT32_MAX messages were sent, the next message ID is 0. :param friend_number: The friend number of the friend to send the message to. :param message_type: Message type (TOX_MESSAGE_TYPE). :param message: A non-None message text. :return: message ID + """ tox_err_friend_send_message = c_int() LOG_DEBUG(f"tox_friend_send_message") @@ -1938,8 +1943,8 @@ class Tox: byref(error)) if error.value: - LOG_ERROR(f"group_join {error.value}") - raise ToxError(f"group_join {error.value}") + LOG_ERROR(f"group_join {error.value} {TOX_ERR_GROUP_JOIN[error.value]}") + raise ToxError(f"group_join {error.value} {TOX_ERR_GROUP_JOIN[error.value]}") return result def group_reconnect(self, group_number): @@ -2438,12 +2443,12 @@ class Tox: def groups_get_list(self): raise NotImplementedError('tox_groups_get_list') - groups_list_size = self.group_get_number_groups() - groups_list = create_string_buffer(sizeof(c_uint32) * groups_list_size) - groups_list = POINTER(c_uint32)(groups_list) - LOG_DEBUG(f"tox_groups_get_list") - Tox.libtoxcore.tox_groups_get_list(self._tox_pointer, groups_list) - return groups_list[0:groups_list_size] +# groups_list_size = self.group_get_number_groups() +# groups_list = create_string_buffer(sizeof(c_uint32) * groups_list_size) +# groups_list = POINTER(c_uint32)(groups_list) +# LOG_DEBUG(f"tox_groups_get_list") +# Tox.libtoxcore.tox_groups_get_list(self._tox_pointer, groups_list) +# return groups_list[0:groups_list_size] def group_get_privacy_state(self, group_number): """ @@ -3105,6 +3110,9 @@ class Tox: LOG_DEBUG(f"tox_callback_group_moderation") def group_toggle_set_ignore(self, group_number, peer_id, ignore): + return group_set_ignore(self, group_number, peer_id, ignore) + + def group_set_ignore(self, group_number, peer_id, ignore): """ Ignore or unignore a peer. @@ -3116,10 +3124,9 @@ class Tox: """ error = c_int() - LOG_DEBUG(f"tox_group_toggle_set_ignore") - result = Tox.libtoxcore.tox_group_toggle_set_ignore(self._tox_pointer, group_number, peer_id, ignore, byref(error)) + LOG_DEBUG(f"tox_group_set_ignore") + result = Tox.libtoxcore.tox_group_set_ignore(self._tox_pointer, group_number, peer_id, ignore, byref(error)) if error.value: - LOG_ERROR(f"tox_group_toggle_set_ignore {error.value}") - raise ToxError("tox_group_toggle_set_ignore {error.value}") + LOG_ERROR(f"tox_group_set_ignore {error.value}") + raise ToxError("tox_group_set_ignore {error.value}") return result - diff --git a/wrapper_tests/support_onions.py b/wrapper_tests/support_onions.py index 6da6529..ba1d182 100644 --- a/wrapper_tests/support_onions.py +++ b/wrapper_tests/support_onions.py @@ -29,22 +29,177 @@ LOG = logging.getLogger() bHAVE_TORR = shutil.which('tor-resolve') +yKNOWN_ONIONS = """ + - facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd # facebook + - duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad # ddg + - zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad # hks +""" +# grep -B 1 '
  • 0: LOG.warn(f'bootstraping local No local DHT running') LOG.info(f'bootstraping local') - return bootstrap_udp(self, elts, lToxes) + return bootstrap_udp(elts, lToxes, oArgs) def lDNSClean(l): - # [elt for elt in l if elt not in lDEAD_BS] - return list(set(l).difference(lDEAD_BS)) + global lDEAD_BS + # list(set(l).difference(set(lDEAD_BS))) + return [elt for elt in l if elt not in lDEAD_BS] def lExitExcluder(oArgs, iPort=9051): """ @@ -625,29 +647,33 @@ def lExitExcluder(oArgs, iPort=9051): LOG.exception('ExcludeExitNodes ' +str(e)) return exit_excludelist +aHOSTS = {} +@functools.lru_cache(maxsize=20) def sDNSLookup(host): + global aHOSTS ipv = 0 if host in lDEAD_BS: - LOG.warn(f"address skipped because in lDEAD_BS {host}") +# LOG.warn(f"address skipped because in lDEAD_BS {host}") return '' -# return host + if host in aHOSTS: + return aHOSTS[host] + try: s = host.replace('.','') int(s) + ipv = 4 except: try: s = host.replace(':','') int(s) - except: pass - else: ipv = 6 - else: - ipv = 4 + except: pass if ipv > 0: -# LOG.debug(f"{ipv} IP address {host}") +# LOG.debug(f"v={ipv} IP address {host}") return host + LOG.debug(f"sDNSLookup {host}") ip = '' if host.endswith('.tox') or host.endswith('.onion'): if False and stem: @@ -677,7 +703,11 @@ def sDNSLookup(host): else: try: ip = socket.gethostbyname(host) - return ip + LOG.debug(f"host={host} gethostbyname IP address {ip}") + if ip: + aHOSTS[host] = ip + return ip + # drop through except: # drop through pass @@ -685,62 +715,77 @@ def sDNSLookup(host): if ip == '': try: sout = f"/tmp/TR{os.getpid()}.log" - i = os.system(f"dig {host}|grep ^{host}|sed -e 's/.* //'> {sout}") + i = os.system(f"dig {host} +timeout=15|grep ^{host}|sed -e 's/.* //'> {sout}") if not i: LOG.warn(f"address skipped because dig failed on {host}") return '' ip = open(sout, 'rt').read().strip() LOG.debug(f"address dig {ip} on {host}") + aHOSTS[host] = ip return ip except: ip = host LOG.debug(f'sDNSLookup {host} -> {ip}') + if ip and ip != host: + aHOSTS[host] = ip return ip -def bootstrap_good(lelts, lToxes): - return bootstrap_udp(lelts, lToxes) - -def bootstrap_udp(lelts, lToxes): +def bootstrap_udp(lelts, lToxes, oArgs=None): lelts = lDNSClean(lelts) - LOG.debug(f'DHT bootstraping {len(lelts)}') - for elt in lToxes: + socket.setdefaulttimeout(15.0) + for oTox in lToxes: random.shuffle(lelts) + if hasattr(oTox, 'oArgs'): + oArgs = oTox.oArgs + if hasattr(oArgs, 'contents') and oArgs.contents.proxy_type != 0: + lelts = lelts[:1] + +# LOG.debug(f'bootstrap_udp DHT bootstraping {oTox.name} {len(lelts)}') for largs in lelts: + assert len(largs) == 3 host, port, key = largs + assert host; assert port; assert key + if host in lDEAD_BS: continue ip = sDNSLookup(host) if not ip: - LOG.warn(f'bootstrap_udp to {host} did not resolve') + LOG.warn(f'bootstrap_udp to host={host} port={port} did not resolve ip={ip}') continue if type(port) == str: port = int(port) try: assert len(key) == 64, key - oRet = elt.bootstrap(ip, + # NOT ip + oRet = oTox.bootstrap(host, port, key) except Exception as e: - LOG.error(f'bootstrap to {host}:' +str(largs[1]) \ - +' ' +str(e)) + if oArgs is None or ( + hasattr(oArgs, 'contents') and oArgs.contents.proxy_type == 0): + pass + # LOG.error(f'bootstrap_udp failed to host={host} port={port} {e}') continue if not oRet: - LOG.warn(f'bootstrap failed to {host} : ' +str(oRet)) - elif elt.self_get_connection_status() != TOX_CONNECTION['NONE']: - LOG.info(f'bootstrap to {host} connected') + LOG.warn(f'bootstrap_udp failed to {host} : {oRet}') + elif oTox.self_get_connection_status() != TOX_CONNECTION['NONE']: + LOG.info(f'bootstrap_udp to {host} connected') break else: - LOG.debug(f'bootstrap to {host} not connected') +# LOG.debug(f'bootstrap_udp to {host} not connected') pass -def bootstrap_tcp(lelts, lToxes): +def bootstrap_tcp(lelts, lToxes, oArgs=None): lelts = lDNSClean(lelts) for oTox in lToxes: + if hasattr(oTox, 'oArgs'): oArgs = oTox.oArgs random.shuffle(lelts) - LOG.info(f'bootstrap_tcp bootstapping {[l[0] for l in lelts]}') +# LOG.debug(f'bootstrap_tcp bootstapping {oTox.name} {len(lelts)}') for (host, port, key,) in lelts: + assert host; assert port;assert key + if host in lDEAD_BS: continue ip = sDNSLookup(host) if not ip: - LOG.warn(f'bootstrap_tcp to {host} did not resolve {ip}') + LOG.warn(f'bootstrap_tcp to {host} did not resolve ip={ip}') # continue ip = host if host.endswith('.onion') and stem: @@ -759,12 +804,19 @@ def bootstrap_tcp(lelts, lToxes): LOG.error(f'bootstrap_tcp to {host} : ' +str(e)) continue if not oRet: - LOG.warn(f'bootstrap_tcp failed to {host} : ' +str(oRet)) + LOG.warn(f'bootstrap_tcp failed to {host} : {oRet}') + elif oTox.mycon_time == 1: + LOG.info(f'bootstrap_tcp to {host} not yet connected last=1') + elif oTox.mycon_status is False: + LOG.info(f'bootstrap_tcp to {host} not True' \ + +f" last={int(oTox.mycon_time)}" ) elif oTox.self_get_connection_status() != TOX_CONNECTION['NONE']: - LOG.info(f'bootstrap_tcp to {host} connected') + LOG.info(f'bootstrap_tcp to {host} connected' \ + +f" last={int(oTox.mycon_time)}" ) break else: - LOG.debug(f'bootstrap_tcp to {host} but not connected') + LOG.debug(f'bootstrap_tcp to {host} but not connected' \ + +f" last={int(oTox.mycon_time)}" ) pass def iNmapInfoNmap(sProt, sHost, sPort, key=None, environ=None, cmd=''): @@ -812,13 +864,16 @@ def bootstrap_iNmapInfo(lElts, oArgs, protocol="tcp4", bIS_LOCAL=False, iNODES=i if not bIS_LOCAL and not bAreWeConnected(): LOG.warn(f"bootstrap_iNmapInfo not local and NOT CONNECTED") return True + if os.environ['USER'] != 'root': + LOG.warn(f"bootstrap_iNmapInfo not ROOT") + return True lRetval = [] for elts in lElts[:iNODES]: host, port, key = elts ip = sDNSLookup(host) if not ip: - LOG.info('bootstrap_iNmapInfo to {host} did not resolve') + LOG.info('bootstrap_iNmapInfo to {host} did not resolve ip={ip}') continue if type(port) == str: port = int(port) diff --git a/wrapper_tests/tests_wrapper.py b/wrapper_tests/tests_wrapper.py index 6561500..640916d 100644 --- a/wrapper_tests/tests_wrapper.py +++ b/wrapper_tests/tests_wrapper.py @@ -58,12 +58,13 @@ try: import coloredlogs os.environ['COLOREDLOGS_LEVEL_STYLES'] = 'spam=22;debug=28;verbose=34;notice=220;warning=202;success=118,bold;error=124;critical=background=red' except ImportError as e: - # logging.log(logging.DEBUG, f"coloredlogs not available: {e}") + logging.log(logging.DEBUG, f"coloredlogs not available: {e}") coloredlogs = None try: import color_runner except ImportError as e: + logging.log(logging.DEBUG, f"color_runner not available: {e}") color_runner = None import wrapper @@ -81,7 +82,7 @@ except ImportError: import wrapper_tests.support_testing as ts try: - from toxygen_tests import test_sound_notification + from tests.toxygen_tests import test_sound_notification bIS_NOT_TOXYGEN = False except ImportError: bIS_NOT_TOXYGEN = True @@ -102,12 +103,12 @@ def LOG_TRACE(l): pass # print('TRAC+ '+l) ADDR_SIZE = 38 * 2 CLIENT_ID_SIZE = 32 * 2 -THRESHOLD = 15 +THRESHOLD = 25 global oTOX_OPTIONS oTOX_OPTIONS = {} -bIS_LOCAL = 'new' in sys.argv or 'newlocal' in sys.argv +bIS_LOCAL = 'new' in sys.argv or 'main' in sys.argv or 'newlocal' in sys.argv # Patch unittest for Python version <= 2.6 if not hasattr(unittest, 'skip'): @@ -119,6 +120,22 @@ if not hasattr(unittest, 'skip'): return _wrap1 unittest.skip = unittest_skip +if not hasattr(unittest, 'expectedFailureIf'): + def unittest_expectedFailureIf(condition, reason): + def _wrap1(test_item): + def _wrap2(self, *args, **kwargs): + if condition: + test_item.__unittest_expecting_failure__ = True + pass + return _wrap2 + return _wrap1 + + unittest.expectedFailureIf = unittest_expectedFailureIf + +def expectedFailure(test_item): + test_item.__unittest_expecting_failure__ = True + return test_item + class ToxOptions(): def __init__(self): self.ipv6_enabled = True @@ -181,7 +198,7 @@ class BaseThread(threading.Thread): if not self.is_alive(): break i = i + 1 else: - LOG.warn(f"{self.name} BLOCKED") + LOG.warning(f"{self.name} BLOCKED") class ToxIterateThread(BaseThread): @@ -194,41 +211,157 @@ class ToxIterateThread(BaseThread): self._tox.iterate() sleep(self._tox.iteration_interval() / 1000) +global bob, alice +bob = alice = None + +def prepare(self): + global bob, alice + def bobs_on_self_connection_status(iTox, connection_state, *args): + status = connection_state + self.bob.dht_connected = status + self.bob.mycon_time = time.time() + try: + if status != TOX_CONNECTION['NONE']: + LOG_DEBUG(f"bobs_on_self_connection_status TRUE {status}" \ + +f" last={int(self.bob.mycon_time)}" ) + self.bob.mycon_status = True + else: + LOG_DEBUG(f"bobs_on_self_connection_status FALSE {status}" \ + +f" last={int(self.bob.mycon_time)}" ) + self.bob.mycon_status = False + except Exception as e: + LOG_ERROR(f"bobs_on_self_connection_status {e}") + else: + if self.bob.self_get_connection_status() != status: + LOG_WARN(f"bobs_on_self_connection_status DISAGREE {status}") + + def alices_on_self_connection_status(iTox, connection_state, *args): + #FixMe connection_num + status = connection_state + self.alice.dht_connected = status + self.alice.mycon_time = time.time() + try: + if status != TOX_CONNECTION['NONE']: + LOG_DEBUG(f"alices_on_self_connection_status TRUE {status}" \ + +f" last={int(self.alice.mycon_time)}" ) + self.alice.mycon_status = True + else: + LOG_WARN(f"alices_on_self_connection_status FALSE {status}" \ + +f" last={int(self.alice.mycon_time)}" ) + self.alice.mycon_status = False + except Exception as e: + LOG_ERROR(f"alices_on_self_connection_status error={e}") + else: + if self.alice.self_get_connection_status() != status: + LOG_WARN(f"alices_on_self_connection_status != {status}") + self.alice.dht_connected = status + + opts = oToxygenToxOptions(oTOX_OARGS) + alice = AliceTox(opts, app=oAPP) + alice.oArgs = opts + alice.dht_connected = -1 + alice.mycon_status = False + alice.mycon_time = 1 + alice.callback_self_connection_status(alices_on_self_connection_status) + + bob = BobTox(opts, app=oAPP) + bob.oArgs = opts + bob.dht_connected = -1 + bob.mycon_status = False + bob.mycon_time = 1 + bob.callback_self_connection_status(bobs_on_self_connection_status) + if not bIS_LOCAL and not ts.bAreWeConnected(): + LOG.warning(f"doOnce not local and NOT CONNECTED") + return [bob, alice] + class ToxSuite(unittest.TestCase): - global oTOX_OARGS + failureException = RuntimeError + + @classmethod + def setUpClass(cls): + global oTOX_OARGS + assert oTOX_OPTIONS + assert oTOX_OARGS + + if not hasattr(cls, 'alice') and not hasattr(cls, 'bob'): + l = prepare(cls) + assert l + cls.bob, cls.alice = l + if not hasattr(cls.bob, '_main_loop'): + cls.bob._main_loop = ToxIterateThread(cls.bob) + cls.bob._main_loop.start() + LOG.debug(f"cls.bob._main_loop: ") # {threading.enumerate()} + if not hasattr(cls.alice, '_main_loop'): + cls.alice._main_loop = ToxIterateThread(cls.alice) + cls.alice._main_loop.start() + LOG.debug(f"cls.alice._main_loop: ") # {threading.enumerate()} + + cls.lUdp = ts.generate_nodes( + oArgs=oTOX_OARGS, + nodes_count=2*ts.iNODES, + ipv='ipv4', + udp_not_tcp=True) + + cls.lTcp = ts.generate_nodes( + oArgs=oTOX_OARGS, + nodes_count=2*ts.iNODES, + ipv='ipv4', + udp_not_tcp=False) + + @classmethod + def tearDownClass(cls): + cls.bob._main_loop.stop_thread() + cls.alice._main_loop.stop_thread() + if False: + cls.alice.kill() + cls.bob.kill() + del cls.bob + del cls.alice + + def setUp(self): + """ + """ + if hasattr(self, 'baid') and self.baid >= 0 and \ + self.baid in self.bob.self_get_friend_list(): + LOG.warn(f"setUp ALICE IS ALREADY IN BOBS FRIEND LIST") + elif self.bob.self_get_friend_list_size() >= 1: + LOG.warn(f"setUp BOB STILL HAS A FRIEND LIST") + + if hasattr(self, 'abid') and self.abid >= 0 and \ + self.abid in self.alice.self_get_friend_list(): + LOG.warn(f"setUp BOB IS ALREADY IN ALICES FRIEND LIST") + elif self.alice.self_get_friend_list_size() >= 1: + LOG.warn(f"setUp ALICE STILL HAS A FRIEND LIST") + + def tearDown(self): + """ + """ + if hasattr(self, 'baid') and self.baid >= 0 and \ + self.baid in self.bob.self_get_friend_list(): + LOG.warn(f"tearDown ALICE IS STILL IN BOBS FRIEND LIST") + elif self.bob.self_get_friend_list_size() >= 1: + LOG.warn(f"tearDown BOBS STILL HAS A FRIEND LIST") + + if hasattr(self, 'abid') and self.abid >= 0 and \ + self.abid in self.alice.self_get_friend_list(): + LOG.warn(f"tearDown BOB IS STILL IN ALICES FRIEND LIST") + elif self.bob.self_get_friend_list_size() >= 1: + LOG.warn(f"tearDown ALICE STILL HAS A FRIEND LIST") def run(self, result=None): """ Stop after first error """ if not result.errors: super(ToxSuite, self).run(result) - def prepare(self, *args, **kw): - assert oTOX_OPTIONS - assert oTOX_OARGS - opts = oToxygenToxOptions(oTOX_OARGS) - print(repr(opts)) - if not hasattr(self, 'alice'): - self.alice = AliceTox(opts, app=oAPP) - self.alice.oArgs = opts - if not hasattr(self, 'bob'): - self.bob = BobTox(opts, app=oAPP) - self.bob.oArgs = opts - if not bIS_LOCAL and not ts.bAreWeConnected(): - LOG.warn(f"prepare not local and NOT CONNECTED") - - self.lUdp = ts.generate_nodes( - oArgs=oTOX_OARGS, - nodes_count=8, - ipv='ipv4', - udp_not_tcp=True) - - self.lTcp = ts.generate_nodes( - oArgs=oTOX_OARGS, - nodes_count=8, - ipv='ipv4', - udp_not_tcp=False) - def get_connection_status(self): + if self.bob.mycon_time == -1 or self.alice.mycon_time == -1: + pass + # drop through + elif self.bob.dht_connected == TOX_CONNECTION['NONE']: + return False + elif self.alice.dht_connected == TOX_CONNECTION['NONE']: + return False + # if not self.connected if self.bob.self_get_connection_status() == TOX_CONNECTION['NONE']: return False @@ -236,30 +369,6 @@ class ToxSuite(unittest.TestCase): return False return True - def setUp(self): - """ - t:on_log - """ - - if not hasattr(self, 'alice') or not hasattr(self, 'bob'): - self.prepare() - if not hasattr(self.bob, '_main_loop'): - self.bob._main_loop = ToxIterateThread(self.bob) - self.bob._main_loop.start() - # LOG.debug(f"self.bob._main_loop: {threading.enumerate()!r}") - - - def tearDown(self): - """ - t:kill - """ - self.bob._main_loop.stop_thread() - if False: - self.alice.kill() - self.bob.kill() - del self.bob - del self.alice - def loop(self, n): """ t:iterate @@ -271,150 +380,91 @@ class ToxSuite(unittest.TestCase): self.bob.iterate() sleep(interval / 1000.0) - def assert_connection_status(self): - """ - t:self_get_connection_status - """ - assert self.alice.self_get_connection_status() != TOX_CONNECTION['NONE'], \ - 'ERROR: self.alice.self_get_connection_status() is ' + \ - repr(self.alice.self_get_connection_status()) - assert self.bob.self_get_connection_status() != TOX_CONNECTION['NONE'], \ - 'ERROR: self.bob.self_get_connection_status() is ' + \ - repr(self.bob.self_get_connection_status()) - - def call_bootstrap(self): - LOG.debug(f"call_bootstrap") + def call_bootstrap(self, num=None, lToxes=None, i=0): + if num == None: num=ts.iNODES +# LOG.debug(f"call_bootstrap network={oTOX_OARGS.network}") if oTOX_OARGS.network in ['new', 'newlocal', 'localnew']: ts.bootstrap_local(self.lUdp, [self.alice, self.bob]) - elif self.get_connection_status() is True: - LOG.debug(f"call_bootstrap {self.get_connection_status()}") elif not ts.bAreWeConnected(): - LOG.warn('we are NOT CONNECTED') - elif oTOX_OARGS.proxy_port > 0: - random.shuffle(self.lUdp) -# LOG.debug(f"call_bootstrap ts.bootstrap_udp {self.lUdp[:2]}") - ts.bootstrap_udp(self.lUdp[:ts.iNODES], [self.alice, self.bob]) - random.shuffle(self.lTcp) -# LOG.debug(f"call_bootstrap ts.bootstrap_tcp {self.lTcp[:8]}") - ts.bootstrap_tcp(self.lTcp[:ts.iNODES], [self.alice, self.bob]) + LOG.warning('we are NOT CONNECTED') else: random.shuffle(self.lUdp) -# LOG.debug(f"call_bootstrap ts.bootstrap_udp {self.lUdp[:8]}") - ts.bootstrap_udp(self.lUdp[:8], [self.alice, self.bob]) + if oTOX_OARGS.proxy_port > 0: + lElts = self.lUdp[:1] + else: + lElts = self.lUdp[:num+i] + LOG.debug(f"call_bootstrap ts.bootstrap_udp {len(lElts)}") + if lToxes is None: lToxes = [self.alice, self.bob] + ts.bootstrap_udp(lElts, lToxes) + random.shuffle(self.lTcp) + lElts = self.lTcp[:num+i] + LOG.debug(f"call_bootstrap ts.bootstrap_tcp {len(lElts)}") + ts.bootstrap_tcp(lElts, lToxes) - def loop_until_connected(self): + def loop_until_connected(self, num=None): """ t:on_self_connection_status t:self_get_connection_status """ i = 0 bRet = None - - self.bob.mycon_status = False - def bobs_on_self_connection_status(iTox, connection_state, *args): - status = connection_state - try: - if status != TOX_CONNECTION['NONE']: - LOG_INFO(f"BOBS_ON_self_connection_status TRUE {status}") - self.bob.mycon_status = True - else: - LOG_WARN(f"BOBS_ON_self_connection_status FALSE {status}") - self.bob.mycon_status = False - except Exception as e: - LOG_ERROR(f"BOBS_ON_self_connection_status {e}") - else: - if self.bob.self_get_connection_status() != status: - LOG_WARN(f"BOBS_ON_self_connection_status != {status}") - - self.alice.mycon_status = False - def alices_on_self_connection_status(iTox, connection_state, *args): - #FixMe connection_num - status = connection_state - try: - if status != TOX_CONNECTION['NONE']: - LOG_INFO(f"alices_on_self_connection_status TRUE {status}") - self.alice.mycon_status = True - else: - LOG_WARN(f"alices_on_self_connection_status FALSE {status}") - self.alice.mycon_status = False - except Exception as e: - LOG_ERROR(f"alices_on_self_connection_status error={e}") - else: - if self.alice.self_get_connection_status() != status: - LOG_WARN(f"alices_on_self_connection_status != {status}") - - try: - self.alice.callback_self_connection_status(alices_on_self_connection_status) - self.bob.callback_self_connection_status(bobs_on_self_connection_status) - - while i <= THRESHOLD : - if i % 3 == 0: - self.call_bootstrap() - s = '' - if i == 0: s = '\n' - LOG.info(s+"loop_until_connected " \ - +" #" + str(i) \ - +" BOB=" +repr(self.bob.self_get_connection_status()) \ - +" ALICE=" +repr(self.alice.self_get_connection_status()) - +" BOBS=" +repr(self.bob.mycon_status) \ - +" ALICES=" +repr(self.alice.mycon_status) \ - ) - if (self.alice.mycon_status and self.bob.mycon_status): - bRet = True - break - if (self.alice.self_get_connection_status() and - self.bob.self_get_connection_status()): - LOG_WARN(f"loop_until_connected disagree !=" \ - +f' self.bob.mycon_status={self.bob.mycon_status}' - +f' alice.mycon_status={self.alice.mycon_status}') - bRet = True - break - i += 1 - self.loop(100) - else: - bRet = False - finally: - self.alice.callback_self_connection_status(None) - self.bob.callback_self_connection_status(None) - del self.alice.mycon_status - del self.bob.mycon_status + while i <= THRESHOLD : + if (self.alice.mycon_status and self.bob.mycon_status): + bRet = True + break + if i % 5 == 0: + j = i//5 + self.call_bootstrap(num, lToxes=None, i=j) + s = '' + if i == 0: s = '\n' + LOG.info(s+"loop_until_connected " \ + +" #" + str(i) \ + +" BOB=" +repr(self.bob.self_get_connection_status()) \ + +" ALICE=" +repr(self.alice.self_get_connection_status()) + +f" BOBS={self.bob.mycon_status}" \ + +f" ALICES={self.alice.mycon_status}" \ + +f" last={int(self.bob.mycon_time)}" ) + if (self.alice.mycon_status and self.bob.mycon_status): + bRet = True + break + if (self.alice.self_get_connection_status() and + self.bob.self_get_connection_status()): + LOG_WARN(f"loop_until_connected disagree status() DISAGREE" \ + +f' self.bob.mycon_status={self.bob.mycon_status}' \ + +f' alice.mycon_status={self.alice.mycon_status}' \ + +f" last={int(self.bob.mycon_time)}" ) + bRet = True + break + i += 1 + self.loop(100) + 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("loop_until_connected " \ + LOG.info(f"loop_until_connected returning True {i}" \ +f" BOB={self.bob.self_get_connection_status()}" \ - +f" ALICE={self.alice.self_get_connection_status()}") + +f" ALICE={self.alice.self_get_connection_status()}" \ + +f" last={int(self.bob.mycon_time)}" ) return True else: - LOG.warn("loop_until_connected " \ + 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()}") - return bRet + +f" ALICE={self.alice.self_get_connection_status()}" \ + +f" last={int(self.bob.mycon_time)}" ) + return False def wait_obj_attr(self, obj, attr): - i = 0 - while i < THRESHOLD: - if i % 3 == 0: - self.call_bootstrap() - LOG.debug("wait_obj_attr " +obj.name \ - +" for " +attr \ - +" " +str(i) \ - +" " +repr(getattr(obj, attr))) - if getattr(obj, attr): - return True - self.loop(100) - i += 1 - else: - LOG.error("wait_obj_attr count >= " + str(THRESHOLD) - + " for " +attr) - return getattr(obj, attr) + return wait_otox_attrs(self, obj, [attr]) def wait_objs_attr(self, objs, attr): i = 0 while i <= THRESHOLD: - if i % 1 == 0: - self.call_bootstrap() + if i % 5 == 0: + num = None + j = i//5 + self.call_bootstrap(num, objs, i=j) LOG.debug("wait_objs_attr " +repr(objs) \ +" for " +repr(attr) \ +" " +str(i)) @@ -423,24 +473,28 @@ class ToxSuite(unittest.TestCase): self.loop(100) i += 1 else: - LOG.error(f"wait_obj_attr i >= {THRESHOLD!s}") + LOG.error(f"wait_obj_attr i >= {THRESHOLD}") return all([getattr(obj, attr) for obj in objs]) - def wait_obj_attrs(self, obj, attrs): + def wait_otox_attrs(self, obj, attrs): i = 0 while i <= THRESHOLD: - if i % 3 == 0: - self.call_bootstrap() - LOG.debug("wait_obj_attrs " +repr(obj) \ - +" for " +repr(attrs) \ - +" " +str(i)) - if all([getattr(obj, attr) for attr in attrs]): + if i % 5 == 0: + num = None + j = 0 + if obj.mycon_time == 1: + num = 4 + j = i//5 + self.call_bootstrap(num, [obj], i=j) + LOG.debug(f"wait_otox_attrs {obj.name} for {attrs} {i}" \ + +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 else: - LOG.warn(f"wait_obj_attrs i >= {THRESHOLD!s}") + LOG.warning(f"wait_otox_attrs i >= {THRESHOLD}") return all([getattr(obj, attr) for attr in attrs]) @@ -448,8 +502,9 @@ class ToxSuite(unittest.TestCase): i = 0 oRet = None while i <= THRESHOLD: - if i % 3 == 0: - self.call_bootstrap() + if i % 5 == 0: + j = i//5 + self.call_bootstrap(num=None, lToxes=None, i=j) LOG.debug("wait_ensure_exec " \ +" " +str(method) +" " +str(i)) @@ -461,20 +516,28 @@ class ToxSuite(unittest.TestCase): except ArgumentError as e: # ArgumentError('This client is currently NOT CONNECTED to the friend.') # dunno - LOG.warn(f"wait_ensure_exec ArgumentError {e}") + LOG.warning(f"wait_ensure_exec ArgumentError {e}") return False except Exception as e: - LOG.warn(f"wait_ensure_exec EXCEPTION {e}") + LOG.warning(f"wait_ensure_exec EXCEPTION {e}") return False sleep(3) i += 1 else: - LOG.error(f"wait_ensure_exec i >= {1*THRESHOLD!s}") + LOG.error(f"wait_ensure_exec i >= {1*THRESHOLD}") return False return oRet def bob_add_alice_as_friend_norequest(self): + if hasattr(self, 'baid') and self.baid >= 0 and \ + self.baid in self.bob.self_get_friend_list(): + LOG.warn('Alice is already in bobs friend list') + return True + if self.bob.self_get_friend_list_size() >= 1: + LOG.warn(f'Bob has a friend list {self.bob.self_get_friend_list()}') + return True + MSG = 'Hi, this is Bob.' iRet = self.bob.friend_add_norequest(self.alice._address) self.baid = self.bob.friend_by_public_key(self.alice._address) @@ -483,20 +546,41 @@ class ToxSuite(unittest.TestCase): assert not self.bob.friend_exists(self.baid + 1) assert self.baid in self.bob.self_get_friend_list() assert self.bob.self_get_friend_list_size() >= 1 - return iRet + return iRet >= 0 def alice_add_bob_as_friend_norequest(self): + if hasattr(self, 'abid') and self.abid >= 0 and \ + self.abid in self.alice.self_get_friend_list(): + LOG.warn('Alice is already in Bobs friend list') + return True + if self.alice.self_get_friend_list_size() >= 1: + LOG.warn(f'Alice has a friend list {self.alice.self_get_friend_list()}') + MSG = 'Hi Bob, this is Alice.' iRet = self.alice.friend_add_norequest(self.bob._address) self.abid = self.alice.friend_by_public_key(self.bob._address) assert self.abid >= 0, self.abid + assert self.abid in self.alice.self_get_friend_list() assert self.alice.friend_exists(self.abid), "alice.friend_exists" assert not self.alice.friend_exists(self.abid + 1) - assert self.abid in self.alice.self_get_friend_list() assert self.alice.self_get_friend_list_size() >= 1 - return iRet + return iRet >= 0 - def bob_just_add_alice_as_friend(self): + def both_add_as_friend_norequest(self): + assert self.bob_add_alice_as_friend_norequest() + if not hasattr(self, 'baid') or self.baid < 0: + raise AssertionError("both_add_as_friend_norequest bob, 'baid'") + + assert self.alice_add_bob_as_friend_norequest() + if not hasattr(self, 'abid') or self.abid < 0: + raise AssertionError("both_add_as_friend_norequest alice, 'abid'") + + #: Test last online + assert self.alice.friend_get_last_online(self.abid) is not None + assert self.bob.friend_get_last_online(self.baid) is not None + return True + + def bob_add_alice_as_friend(self): """ t:friend_add t:on_friend_request @@ -510,29 +594,29 @@ class ToxSuite(unittest.TestCase): message_data, message_data_size, *largs): - # oTox = Tox(tox_pointer=iTox) + LOG_DEBUG(f"alices_on_friend_request: " +repr(message_data)) try: - LOG_DEBUG(f"alices_on_friend_request: " +repr(message_data)) assert str(message_data, 'UTF-8') == MSG + LOG_INFO(f"alices_on_friend_request: friend_added = True ") except Exception as e: LOG_WARN(f"alices_on_friend_request: Exception {e}") # return - else: - self.alice.friend_added = True - LOG_DEBUG(f"alices_on_friend_request: self.alice.friend_added = True ") + setattr(self.bob, sSlot, True) + setattr(self.bob, sSlot, None) inum = -1 + self.alice.callback_friend_request(alices_on_friend_request) try: - self.alice.friend_added = False - self.alice.callback_friend_request(alices_on_friend_request) inum = self.bob.friend_add(self.alice._address, bytes(MSG, 'UTF-8')) if not inum >= 0: - LOG.warn('bob.friend_add !>= 0 ' +repr(inum)) - if not self.wait_obj_attr(self.alice, 'friend_added'): + LOG.warning('bob.friend_add !>= 0 ' +repr(inum)) + if not self.wait_otox_attrs(self.bob, [sSlot]): return False except Exception as e: LOG.error(f"bob.friend_add EXCEPTION {e}") return False + finally: + self.bob.callback_friend_message(None) self.baid = self.bob.friend_by_public_key(self.alice._address) assert self.baid >= 0, self.baid @@ -542,70 +626,80 @@ class ToxSuite(unittest.TestCase): assert self.bob.self_get_friend_list_size() >= 1 return True - def alice_just_add_bob_as_friend(self): + def alice_add_bob_as_friend(self): """ t:friend_add t:on_friend_request t:friend_by_public_key """ MSG = 'Bob, this is Alice.' + sSlot = 'friend_request' def bobs_on_friend_request(iTox, public_key, message_data, message_data_size, *largs): - # oTox = Tox(tox_pointer=iTox) + LOG_DEBUG(f"bobs_on_friend_request: " +repr(message_data)) try: - LOG_DEBUG(f"BOBS_ON_friend_request: " +repr(message_data)) assert str(message_data, 'UTF-8') == MSG - LOG_INFO(f"BOBS_ON_friend_request: friend_added = True ") - self.bob.friend_added = True + LOG_INFO(f"bobs_on_friend_request: friend_added = True ") except Exception as e: - LOG_WARN(f"BOBS_ON_friend_request: Exception {e}") + LOG_WARN(f"bobs_on_friend_request: Exception {e}") + # return + else: + setattr(self.alice, sSlot, True) + setattr(self.alice, sSlot, None) inum = -1 - sSlot = 'friend_request' + self.bob.callback_friend_request(bobs_on_friend_request) try: - self.bob.friend_added = False - self.bob.callback_friend_request(bobs_on_friend_request) inum = self.alice.friend_add(self.bob._address, bytes(MSG, 'UTF-8')) if not inum >= 0: - LOG.warn('alice.friend_add !>= 0 ' +repr(inum)) - if not self.wait_obj_attr(self.bob, 'friend_added'): + LOG.warning('alice.friend_add !>= 0 ' +repr(inum)) + if not self.wait_obj_attr(self.alice, sSlot): return False except Exception as e: - LOG.error(f"alice.friend_add {e}") + LOG.error(f"alice.friend_add EXCEPTION {e}") return False finally: - self.alice.callback_friend_message(None) + self.bob.callback_friend_message(None) self.abid = self.alice.friend_by_public_key(self.bob._address) + assert self.abid >= 0, self.abid assert self.alice.friend_exists(self.abid) - assert self.alice.self_get_friend_list_size() >= 1 + assert not self.alice.friend_exists(self.abid + 1) assert self.abid in self.alice.self_get_friend_list() + assert self.alice.self_get_friend_list_size() >= 1 return True + def both_add_as_friend(self): + assert self.bob_add_alice_as_friend() + assert self.alice_add_bob_as_friend() + + #: Test last online + assert self.alice.friend_get_last_online(self.abid) is not None + assert self.bob.friend_get_last_online(self.baid) is not None + def bob_add_alice_as_friend_and_status(self): - bRetval = self.bob_just_add_alice_as_friend() - if not bRetval: - LOG.error("bob_add_alice_as_friend_and_status FAILED") - return False - LOG.info("bob_add_alice_as_friend_and_status waiting for connections") + if oTOX_OARGS.bIS_LOCAL: + assert self.bob_add_alice_as_friend_norequest() + else: + assert self.bob_add_alice_as_friend() #: Wait until both are online self.bob.friend_conn_status = False def bobs_on_friend_connection_status(iTox, friend_id, iStatus, *largs): - LOG_INFO(f"BOBS_ON_friend_connection_status {friend_id} ?>=0" +repr(iStatus)) + LOG_INFO(f"bobs_on_friend_connection_status {friend_id} ?>=0" +repr(iStatus)) if iStatus > 0: self.bob.friend_conn_status = True - self.bob.friend_status = False + self.bob.friend_status = None def bobs_on_friend_status(iTox, friend_id, iStatus, *largs): - LOG_INFO(f"BOBS_ON_friend_status {friend_id} ?>=0" +repr(iStatus)) + LOG_INFO(f"bobs_on_friend_status {friend_id} ?>=0" +repr(iStatus)) if iStatus > 0: self.bob.friend_status = True - self.alice.friend_conn_status = False + self.alice.friend_conn_status = None def alices_on_friend_connection_status(iTox, friend_id, iStatus, *largs): LOG_INFO(f"alices_on_friend_connection_status {friend_id} ?>=0 " +repr(iStatus)) if iStatus > 0: @@ -617,11 +711,11 @@ class ToxSuite(unittest.TestCase): if iStatus > 0: self.alice.friend_status = True + self.alice.callback_friend_connection_status(alices_on_friend_connection_status) + self.alice.callback_friend_status(alices_on_friend_status) try: - self.alice.callback_friend_connection_status(alices_on_friend_connection_status) - self.alice.callback_friend_status(alices_on_friend_status) LOG.info("bob_add_alice_as_friend_and_status waiting for alice connections") - if not self.wait_obj_attrs(self.alice, + if not self.wait_otox_attrs(self.alice, ['friend_conn_status', 'friend_status']): return False @@ -630,7 +724,7 @@ class ToxSuite(unittest.TestCase): self.bob.callback_friend_status(bobs_on_friend_status) LOG.info("bob_add_alice_as_friend_and_status waiting for bob connections") - if not self.wait_obj_attrs(self.bob, + if not self.wait_otox_attrs(self.bob, ['friend_conn_status', 'friend_status']): return False @@ -654,14 +748,24 @@ class ToxSuite(unittest.TestCase): def warn_if_no_cb(self, alice, sSlot): if not hasattr(alice, sSlot+'_cb') or \ not getattr(alice, sSlot+'_cb'): - LOG.warn(f"self.bob.{sSlot}_cb NOT EXIST") + LOG.warning(f"self.bob.{sSlot}_cb NOT EXIST") def warn_if_cb(self, alice, sSlot): if hasattr(self.bob, sSlot+'_cb') and \ getattr(self.bob, sSlot+'_cb'): - LOG.warn("self.bob.{sSlot}_cb EXIST") + LOG.warning(f"self.bob.{sSlot}_cb EXIST") # tests are executed in order + def test_notice_log(self): # works + notice = '/var/lib/tor/.SelekTOR/3xx/cache/9050/notice.log' + if True or os.path.exists(notice): + iRet = os.system(f"sudo sed -e '1,/.notice. Bootstrapped 100%/d' {notice}" + \ + "| grep 'Tried for 120 seconds to get a connection to :0.'") + if iRet == 0: + raise SystemExit("seconds to get a connection to :0") + else: + LOG.debug(f"checked {notice}") + def test_tests_logging(self): # works with self.assertLogs('foo', level='INFO') as cm: logging.getLogger('foo').info('first message') @@ -692,7 +796,7 @@ class ToxSuite(unittest.TestCase): if iStatus == 0: LOG.info(f"bootstrap_local_netstat port {port} iStatus={iStatus}") else: - LOG.warn(f"bootstrap_local_netstat NOT {port} iStatus={iStatus}") + LOG.warning(f"bootstrap_local_netstat NOT {port} iStatus={iStatus}") @unittest.skipIf(not bIS_LOCAL, "local test") def test_bootstrap_local(self): # works @@ -718,8 +822,7 @@ class ToxSuite(unittest.TestCase): o2 = self.bob.self_get_dht_id() assert len(o2) == 64 - if o1 != o2: - LOG.warn(f"bootstrap_local DHT NOT same {o1} {o2} iStatus={iStatus}") +# if o1 != o2: LOG.warning(f"bootstrap_local DHT NOT same {o1} {o2} iStatus={iStatus}") iStatus = self.bob.self_get_connection_status() if iStatus != TOX_CONNECTION['NONE']: @@ -729,10 +832,12 @@ class ToxSuite(unittest.TestCase): if iStatus != TOX_CONNECTION['NONE']: LOG.info(f"bootstrap_local connected iStatus={iStatus}") return True - LOG.warn(f"bootstrap_local NOT CONNECTED iStatus={iStatus}") + LOG.warning(f"bootstrap_local NOT CONNECTED iStatus={iStatus}") return False def test_bootstrap_iNmapInfo(self): # works + if os.environ['USER'] != 'root': + return if oTOX_OARGS.network in ['new', 'newlocal', 'localnew']: lElts = self.lUdp elif oTOX_OARGS.proxy_port > 0: @@ -781,6 +886,9 @@ class ToxSuite(unittest.TestCase): self.alice.self_set_name('Alice') assert self.alice.self_get_name() == 'Alice' assert self.alice.self_get_name_size() == len('Alice') + self.bob.self_set_name('Bob') + assert self.bob.self_get_name() == 'Bob' + assert self.bob.self_get_name_size() == len('Bob') @unittest.skip('loud') @unittest.skipIf(bIS_NOT_TOXYGEN or oTOX_OARGS.mode == 0, 'not testing in toxygen') @@ -789,30 +897,9 @@ class ToxSuite(unittest.TestCase): Plays sound notification :param type of notification """ - from toxygen_tests import test_sound_notification + from tests.toxygen_tests import test_sound_notification test_sound_notification(self) - def test_loop_until_connected(self): # works - assert self.loop_until_connected() - - def test_self_get_udp_port(self): # works - """ - t:self_get_udp_port - """ - if hasattr(oTOX_OPTIONS, 'udp_port') and oTOX_OPTIONS.udp_port: - o = self.alice.self_get_udp_port() - LOG.info('self_get_udp_port ' +repr(o)) - assert o > 0 - - def test_self_get_tcp_port(self): # works - """ - t:self_get_tcp_port - """ - if hasattr(oTOX_OPTIONS, 'tcp_port') and oTOX_OPTIONS.tcp_port: - # errors if tcp_port <= 0 - o = self.alice.self_get_tcp_port() - LOG.info('self_get_tcp_port ' +repr(o)) - def test_address(self): # works """ t:self_get_address @@ -831,6 +918,40 @@ class ToxSuite(unittest.TestCase): pk, sk = self.alice.self_get_keys() assert pk == self.alice.self_get_address()[:CLIENT_ID_SIZE] + def test_status_message(self): # works + MSG = 'Happy' + self.alice.self_set_status_message(MSG) + self.loop(100) + assert self.alice.self_get_status_message() == MSG, \ + self.alice.self_get_status_message() +' is not ' +MSG + assert self.alice.self_get_status_message_size() == len(MSG) + + def test_loop_until_connected(self): # works + assert self.loop_until_connected() + + def test_self_get_udp_port(self): # works + """ + t:self_get_udp_port + """ + 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)) + assert o > 0 + o = self.bob.self_get_udp_port() + LOG.info('self_get_udp_port bob ' +repr(o)) + assert o > 0 + + def test_self_get_tcp_port(self): # works + """ + t:self_get_tcp_port + """ + if hasattr(oTOX_OPTIONS, 'tcp_port') and oTOX_OPTIONS.tcp_port: + # errors if tcp_port <= 0 + o = self.alice.self_get_tcp_port() + LOG.info('self_get_tcp_port ' +repr(o)) + o = self.bob.self_get_tcp_port() + LOG.info('self_get_tcp_port ' +repr(o)) + def test_get_dht_id(self): # works """ t:self_get_dht_id @@ -850,72 +971,104 @@ class ToxSuite(unittest.TestCase): RuntimeError("ERROR: NOT CONNECTED " \ +repr(self.alice.self_get_connection_status())) - def test_status_message(self): # works - MSG = 'Happy' + def test_bob_assert_mycon_status(self): # works + if self.bob.mycon_status == False: + RuntimeError("ERROR: NOT CONNECTED " \ + +repr(self.bob.mycon_status)) - self.alice.self_set_status_message(MSG) - self.loop(50) - assert self.alice.self_get_status_message() == MSG, \ - self.alice.self_get_status_message() +' is not ' +MSG - assert self.alice.self_get_status_message_size() == len(MSG) + def test_alice_assert_mycon_status(self): # works + if self.alice.mycon_status == False: + RuntimeError("ERROR: NOT CONNECTED " \ + +repr(self.alice.mycon_status)) def test_bob_add_alice_as_friend_norequest(self): # works - iRet = self.bob_add_alice_as_friend_norequest() - if iRet < 0: - raise RuntimeError(f"bob_add_alice_as_friend_norequest {iRet}") + assert len(self.bob.self_get_friend_list()) == 0 + assert self.bob_add_alice_as_friend_norequest() #: Test last online assert self.bob.friend_get_last_online(self.baid) is not None self.bob.friend_delete(self.baid) - def test_alice_just_add_bob_as_friend_norequest(self): # works - iRet = self.alice_add_bob_as_friend_norequest() - if iRet < 0: - raise RuntimeError(f"bob_add_alice_as_friend_norequest {iRet}") + def test_alice_add_bob_as_friend_norequest(self): # works + assert len(self.alice.self_get_friend_list()) == 0 + assert self.alice_add_bob_as_friend_norequest() + assert len(self.alice.self_get_friend_list()) != 0 #: Test last online assert self.alice.friend_get_last_online(self.abid) is not None self.alice.friend_delete(self.abid) - @unittest.skipIf(bIS_LOCAL, "local test") - def test_bob_just_add_alice_as_friend(self): # works - assert self.bob_just_add_alice_as_friend() - #: Test last online - assert self.bob.friend_get_last_online(self.baid) is not None - self.bob.friend_delete(self.baid) - - @unittest.skipIf(bIS_LOCAL, "local test") - def test_alice_just_add_bob_as_friend(self): # works - assert self.alice_just_add_bob_as_friend() - #: Test last online - assert self.alice.friend_get_last_online(self.abid) is not None - self.alice.friend_delete(self.abid) - - def test_both_just_add_as_friend(self): # works - LOG_DEBUG(f"bIS_LOCAL={bIS_LOCAL} oTOX_OARGS.bIS_LOCAL={oTOX_OARGS.bIS_LOCAL}") - if oTOX_OARGS.bIS_LOCAL: - iRet = self.bob_add_alice_as_friend_norequest() - if iRet < 0: - raise RuntimeError(f"bob_add_alice_as_friend_norequest {iRet}") - iRet = self.alice_add_bob_as_friend_norequest() - if iRet < 0: - raise RuntimeError(f"alice_add_bob_as_friend_norequest {iRet}") - else: - assert self.bob_just_add_alice_as_friend() - assert self.alice_just_add_bob_as_friend() - - #: Test last online - assert self.alice.friend_get_last_online(self.abid) is not None - assert self.bob.friend_get_last_online(self.baid) is not None + def test_both_add_as_friend_norequest(self): # works + assert len(self.bob.self_get_friend_list()) == 0 + assert len(self.alice.self_get_friend_list()) == 0 + self.both_add_as_friend_norequest() self.bob.friend_delete(self.baid) self.alice.friend_delete(self.abid) + assert len(self.bob.self_get_friend_list()) == 0 + assert len(self.alice.self_get_friend_list()) == 0 + + def test_bob_add_alice_as_friend_and_status(self): + self.bob_add_alice_as_friend_and_status() + self.bob.friend_delete(self.baid) + + @unittest.skip('malloc_consolidate(): invalid chunk size') +# @unittest.skipIf(bIS_LOCAL, "local test") +# @expectedFailure # (bIS_LOCAL, "local test") + def test_bob_add_alice_as_friend(self): # fails + assert len(self.bob.self_get_friend_list()) == 0 + try: + assert self.bob_add_alice_as_friend() + #: Test last online + assert self.bob.friend_get_last_online(self.baid) is not None + except AssertionError as e: + #WTF? + self.bob.friend_delete(self.baid) + raise RuntimeError(f"Failed test {e}") + finally: + self.bob.friend_delete(self.baid) + assert len(self.bob.self_get_friend_list()) == 0 + + @unittest.skip('malloc_consolidate(): invalid chunk size') +# @unittest.skipIf(bIS_LOCAL, "local test") +# @expectedFailure + def test_alice_add_bob_as_friend(self): # fails + assert len(self.bob.self_get_friend_list()) == 0 + try: + assert self.alice_add_bob_as_friend() + #: Test last online + assert self.alice.friend_get_last_online(self.abid) is not None + except AssertionError as e: + raise RuntimeError(f"Failed test {e}") + except Exception as e: + LOG.error(f"test_alice_add_bob_as_friend EXCEPTION {e}") + raise + finally: + self.alice.friend_delete(self.abid) + assert len(self.alice.self_get_friend_list()) == 0 + +# @unittest.skipIf(bIS_LOCAL, "local test") + @expectedFailure + def test_both_add_as_friend(self): # works + try: + self.both_add_as_friend() + except AssertionError as e: + raise RuntimeError(f"Failed test {e}") + except Exception as e: + LOG.error(f"test_both_add_as_friend EXCEPTION {e}") + raise + finally: + self.bob.friend_delete(self.baid) + self.alice.friend_delete(self.abid) + assert len(self.bob.self_get_friend_list()) == 0 + assert len(self.alice.self_get_friend_list()) == 0 @unittest.skip('unfinished') def test_bob_add_alice_as_friend_and_status(self): assert self.bob_add_alice_as_friend_and_status() self.bob.friend_delete(self.baid) - @unittest.skip('fails') - def test_on_friend_status_message(self): +#? @unittest.skip('fails') + @expectedFailure + def test_on_friend_status_message(self): # fails """ t:self_set_status_message t:self_get_status_message @@ -928,46 +1081,43 @@ class ToxSuite(unittest.TestCase): MSG = 'Happy' sSlot = 'friend_status_message' - if oTOX_OARGS.bIS_LOCAL: - iRet = self.bob_add_alice_as_friend_norequest() - if iRet < 0: - raise RuntimeError(f"bob_add_alice_as_friend_norequest {iRet}") - else: - assert self.bob_just_add_alice_as_friend() - - setattr(self.bob, sSlot, False) def bob_on_friend_status_message(iTox, friend_id, new_status_message, new_status_size, *largs): - setattr(self.bob, sSlot, True) try: assert str(new_status_message, 'UTF-8') == MSG assert friend_id == self.baid except Exception as e: - LOG_ERROR("BOB_ON_friend_status_message EXCEPTION " +str(e)) + LOG_ERROR(f"BOB_ON_friend_status_message EXCEPTION {e}") else: - LOG_INFO("BOB_ON_friend_status_message " +repr(friend_id) \ + LOG_INFO(f"BOB_ON_friend_status_message {friend_id}" \ +repr(new_status_message)) + setattr(self.bob, sSlot, True) + setattr(self.bob, sSlot, None) try: + if oTOX_OARGS.bIS_LOCAL: + assert self.bob_add_alice_as_friend_norequest() + else: + assert self.bob_add_alice_as_friend() + self.bob.callback_friend_status_message(bob_on_friend_status_message) self.warn_if_no_cb(self.bob, sSlot) self.alice.self_set_status_message(MSG) - assert self.wait_obj_attr(self.bob, sSlot) + assert self.wait_otox_attrs(self.bob, [sSlot]) assert self.bob.friend_get_status_message(self.baid) == MSG assert self.bob.friend_get_status_message_size(self.baid) == len(MSG) except AssertionError as e: - raise + raise RuntimeError(f"Failed test {e}") except Exception as e: LOG.error(f"test_on_friend_status_message EXCEPTION {e}") raise finally: self.alice.callback_friend_status(None) + self.bob.friend_delete(self.baid) - self.bob.friend_delete(self.baid) - - @unittest.skip('fails') - def test_friend(self): + @expectedFailure + def test_friend(self): # works """ t:friend_delete t:friend_exists @@ -978,32 +1128,37 @@ class ToxSuite(unittest.TestCase): t:friend_get_name t:friend_get_name_size t:on_friend_name - """ + """ + assert len(self.bob.self_get_friend_list()) == 0 + assert len(self.alice.self_get_friend_list()) == 0 #: Test friend request if oTOX_OARGS.bIS_LOCAL: - iRet = self.bob_add_alice_as_friend_norequest() - if iRet < 0: - raise RuntimeError(f"bob_add_alice_as_friend_norequest {iRet}") + assert self.bob_add_alice_as_friend_norequest() + assert self.alice_add_bob_as_friend_norequest() else: - assert self.bob_just_add_alice_as_friend() + # no not connected error + assert self.bob_add_alice_as_friend() + assert self.alice_add_bob_as_friend() + try: + assert self.bob.friend_get_public_key(self.baid) == \ + self.alice.self_get_address()[:CLIENT_ID_SIZE] - assert self.bob.friend_get_public_key(self.baid) == \ - self.alice.self_get_address()[:CLIENT_ID_SIZE] + #: Test friend_get_public_key + assert self.alice.friend_get_public_key(self.abid) == \ + self.bob.self_get_address()[:CLIENT_ID_SIZE] + except AssertionError as e: + raise RuntimeError(f"Failed test {e}") + except Exception as e: + LOG.error(f"test_friend EXCEPTION {e}") + raise + finally: + self.bob.friend_delete(self.baid) + self.alice.friend_delete(self.abid) - LOG.info("test_friend alice_just_add_bob_as_friend ") - #? assert self.alice_just_add_bob_as_friend() - assert self.alice_add_bob_as_friend_norequest() >= 0 - - #: Test friend_get_public_key - assert self.alice.friend_get_public_key(self.abid) == \ - self.bob.self_get_address()[:CLIENT_ID_SIZE] - - self.bob.friend_delete(self.baid) - self.alice.friend_delete(self.abid) - - @unittest.skip('fails') - @unittest.skipIf(not bIS_LOCAL and not ts.bAreWeConnected(), 'NOT CONNECTED') +# @unittest.skip('fails') +# @unittest.skipIf(not bIS_LOCAL and not ts.bAreWeConnected(), 'NOT CONNECTED') + @expectedFailure def test_user_status(self): """ t:self_get_status @@ -1014,71 +1169,71 @@ class ToxSuite(unittest.TestCase): """ sSlot = 'friend_status' if oTOX_OARGS.bIS_LOCAL: - iRet = self.bob_add_alice_as_friend_norequest() - if iRet < 0: - raise RuntimeError(f"bob_add_alice_as_friend_norequest {iRet}") + assert self.bob_add_alice_as_friend_norequest() else: - assert self.bob_just_add_alice_as_friend() + assert self.bob_add_alice_as_friend() - sSTATUS = TOX_USER_STATUS['AWAY'] - setattr(self.bob, sSlot, False) + sSTATUS = TOX_USER_STATUS['NONE'] + setattr(self.bob, sSlot, None) def bobs_on_friend_set_status(iTox, friend_id, new_status, *largs): - LOG_INFO(f"BOBS_ON_friend_set_status " \ - +repr(friend_id) +repr(new_status)) + LOG_INFO(f"bobs_on_friend_set_status {friend_id} {new_status}") try: assert friend_id == self.baid - assert new_status == sSTATUS + assert new_status in [TOX_USER_STATUS['BUSY'], TOX_USER_STATUS['AWAY']] except Exception as e: - LOG_WARN(f"BOBS_ON_friend_set_status EXCEPTION {e}") + LOG_WARN(f"bobs_on_friend_set_status EXCEPTION {e}") setattr(self.bob, sSlot, True) try: - assert self.loop_until_connected() if not self.get_connection_status(): - LOG.warn(f"test_user_status NOT CONNECTED") - raise RuntimeError("not connected") + LOG.warning(f"test_user_status NOT CONNECTED self.get_connection_status") + self.loop_until_connected() self.bob.callback_friend_status(bobs_on_friend_set_status) - self.alice.self_set_status(sSTATUS) self.warn_if_no_cb(self.bob, sSlot) - assert self.wait_obj_attr(self.bob, sSlot) + sSTATUS = TOX_USER_STATUS['BUSY'] + self.alice.self_set_status(sSTATUS) + sSTATUS = TOX_USER_STATUS['AWAY'] + self.alice.self_set_status(sSTATUS) + assert self.wait_otox_attrs(self.bob, [sSlot]) # wait_obj_attr count >= 15 for friend_status + self.alice.self_set_status(TOX_USER_STATUS['NONE']) + assert self.alice.self_get_status() == TOX_USER_STATUS['NONE'] + assert self.bob.friend_get_status(self.baid) == TOX_USER_STATUS['NONE'] + except AssertionError as e: - raise + raise RuntimeError(f"Failed test {e}") + except Exception as e: LOG.error(f"test_user_status EXCEPTION {e}") raise finally: self.bob.callback_friend_status(None) self.warn_if_cb(self.bob, sSlot) - - self.alice.self_set_status(TOX_USER_STATUS['NONE']) - assert self.alice.self_get_status() == TOX_USER_STATUS['NONE'] - assert self.bob.friend_get_status(self.baid) == TOX_USER_STATUS['NONE'] - - self.bob.friend_delete(self.baid) + self.bob.friend_delete(self.baid) @unittest.skip('crashes') def test_connection_status(self): """ - t:friend_assert_connection_status + t:friend_get_connection_status t:on_friend_connection_status """ LOG.info("test_connection_status ") if oTOX_OARGS.bIS_LOCAL: - assert self.bob_add_alice_as_friend_norequest() >= 0 + assert self.bob_add_alice_as_friend_norequest() else: - assert self.bob_just_add_alice_as_friend() + assert self.bob_add_alice_as_friend() sSlot = 'friend_connection_status' + setattr(self.bob, sSlot, None) def bobs_on_friend_connection_status(iTox, friend_id, iStatus, *largs): setattr(self.bob, sSlot, True) - LOG_INFO(f"BOBS_ON_friend_connection_status " +repr(iStatus)) + LOG_INFO(f"bobs_on_friend_connection_status " +repr(iStatus)) try: assert friend_id == self.baid except Exception as e: - LOG.error(f"BOBS_ON_friend_connection_status ERROR {e}") + LOG.error(f"bobs_on_friend_connection_status ERROR {e}") opts = oToxygenToxOptions(oTOX_OARGS) try: @@ -1091,20 +1246,20 @@ class ToxSuite(unittest.TestCase): self.alice = Tox(opts, app=oAPP) LOG.info("test_connection_status maked alice") - assert self.wait_obj_attr(self.bob, sSlot) + assert self.wait_otox_attrs(self.bob, [sSlot]) except AssertionError as e: raise except Exception as e: - LOG.error(f"BOBS_ON_friend_connection_status {e}") + LOG.error(f"bobs_on_friend_connection_status {e}") raise finally: self.bob.callback_friend_connection_status(None) - #? assert self.bob.friend_assert_connection_status(self.aid) is False - self.bob.friend_delete(self.baid) + #? assert self.bob.friend_get_connection_status(self.aid) is False + self.bob.friend_delete(self.baid) - @unittest.skip('fails') - def test_friend_name(self): +#? @unittest.skip('fails') + def test_friend_name(self): # fails """ t:self_set_name t:friend_get_name @@ -1115,48 +1270,55 @@ class ToxSuite(unittest.TestCase): sSlot= 'friend_name' #: Test friend request - assert self.bob_just_add_alice_as_friend() + LOG.info("test_friend_name") + if oTOX_OARGS.bIS_LOCAL: + assert self.bob_add_alice_as_friend_norequest() + else: + assert self.bob_add_alice_as_friend() + + if not self.get_connection_status(): + LOG.warning(f"test_friend_message NOT CONNECTED") + self.loop_until_connected() - AID = self.baid #: Test friend name NEWNAME = 'Jenny' - setattr(self.bob, sSlot, False) def bobs_on_friend_name(iTox, fid, newname, iNameSize, *largs): - LOG_INFO(sSlot +" " +repr(fid)) + LOG_INFO(f"bobs_on_friend_name {sSlot} {fid}") try: - assert fid == AID + assert fid == self.baid assert str(newname, 'UTF-8') == NEWNAME except Exception as e: - LOG.error(f"BOBS_ON_friend_name EXCEPTION {e}") + LOG.error(f"bobs_on_friend_name EXCEPTION {e}") setattr(self.bob, sSlot, True) + setattr(self.bob, sSlot, None) + self.bob.callback_friend_name(bobs_on_friend_name) + self.warn_if_no_cb(self.bob, sSlot) try: - assert self.loop_until_connected() - - self.bob.callback_friend_name(bobs_on_friend_name) self.alice.self_set_name(NEWNAME) - assert self.wait_obj_attr(self.bob, sSlot) - self.warn_if_no_cb(self.bob, sSlot) + assert self.wait_otox_attrs(self.bob, [sSlot]) assert self.bob.friend_get_name(self.baid) == NEWNAME assert self.bob.friend_get_name_size(self.baid) == len(NEWNAME) + except AssertionError as e: - raise + raise RuntimeError(f"test_friend Failed test {e}") + except Exception as e: - LOG.error(f"test_friend EXCEPTION {e}") - raise + LOG.error(f"test_friend EXCEPTION {e}") + raise + finally: self.bob.callback_friend_name(None) if hasattr(self.bob, sSlot + '_cb') and \ getattr(self.bob, sSlot + '_cb'): - LOG.warn(sSlot + ' EXISTS') + LOG.warning(sSlot + ' EXISTS') - self.bob.friend_delete(self.baid) + self.bob.friend_delete(self.baid) - @unittest.skip('fails') # wait_ensure_exec ArgumentError This client is currently not connected to the friend. - def test_friend_message(self): + def test_friend_message(self): # fails """ t:on_friend_action t:on_friend_message @@ -1166,68 +1328,73 @@ class ToxSuite(unittest.TestCase): #: Test message MSG = 'Hi, Bob!' sSlot = 'friend_message' - if oTOX_OARGS.bIS_LOCAL: - assert self.bob_add_alice_as_friend_norequest() >= 0 + assert self.both_add_as_friend_norequest() else: - assert self.bob_just_add_alice_as_friend() - if oTOX_OARGS.bIS_LOCAL: - assert self.alice_add_bob_as_friend_norequest() >= 0 - else: - # times out - assert self.alice_just_add_bob_as_friend() + assert self.both_add_as_friend() - BID = self.baid + if not self.get_connection_status(): + LOG.warning(f"test_friend_message NOT CONNECTED") + self.loop_until_connected() - setattr(self.bob, sSlot, False) - def alices_on_friend_message(self, fid, msg_type, message, iSize, *largs): + iRet = self.bob.friend_get_connection_status(self.baid) + if iRet == TOX_CONNECTION['NONE']: + LOG.error("bob.friend_get_connection_status") + raise RuntimeError("bob.friend_get_connection_status") + iRet = self.alice.friend_get_connection_status(self.abid) + if iRet == TOX_CONNECTION['NONE']: + LOG.error("alice.friend_get_connection_status") + raise RuntimeError("alice.friend_get_connection_status") + + def alices_on_friend_message(iTox, fid, msg_type, message, iSize, *largs): + LOG_DEBUG(f"alices_on_friend_message {fid} {message}") try: - assert fid == BID + 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 " +repr(message)) - setattr(self.bob, sSlot, True) + LOG_INFO(f"alices_on_friend_message {message}") + setattr(self.alice, sSlot, True) + setattr(self.alice, sSlot, None) try: - assert self.loop_until_connected() - if not self.get_connection_status(): - LOG.warn(f"test_friend_message NOT CONNECTED") - raise RuntimeError("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. if True: - # dunno - assert self.bob.friend_send_message( + iMesId = self.bob.friend_send_message( self.baid, TOX_MESSAGE_TYPE['NORMAL'], bytes(MSG, 'UTF-8')) + # ArgumentError('This client is currently NOT CONNECTED to the friend.') else: - assert self.wait_ensure_exec(self.bob.friend_send_message, - [self.baid, - TOX_MESSAGE_TYPE['NORMAL'], - bytes(MSG, 'UTF-8')]) - assert self.wait_obj_attr(self.alice, sSlot) + iMesId = self.wait_ensure_exec(self.bob.friend_send_message, + [self.baid, + TOX_MESSAGE_TYPE['NORMAL'], + bytes(MSG, 'UTF-8')]) + assert iMesId >= 0 + assert self.wait_otox_attrs(self.alice, [sSlot]) except ArgumentError as e: # ArgumentError('This client is currently NOT CONNECTED to the friend.') # dunno LOG.error(f"test_friend_message {e}") - except AssertionError as e: - LOG.warn(f"test_friend_message {e}") raise + except AssertionError as e: + LOG.warning(f"test_friend_message {e}") + raise RuntimeError(f"Failed test test_friend_message {e}") except Exception as e: LOG.error(f"test_friend_message {e}") raise finally: self.alice.callback_friend_message(None) self.warn_if_cb(self.alice, sSlot) - self.bob.friend_delete(self.baid) - self.alice.friend_delete(self.abid) + self.bob.friend_delete(self.baid) + self.alice.friend_delete(self.abid) - @unittest.skip('fails') +#? @unittest.skip('fails') def test_friend_action(self): """ t:on_friend_action @@ -1236,69 +1403,85 @@ class ToxSuite(unittest.TestCase): """ if oTOX_OARGS.bIS_LOCAL: - iRet = self.bob_add_alice_as_friend_norequest() - if iRet < 0: - raise RuntimeError(f"bob_add_alice_as_friend_norequest {iRet}") + assert self.both_add_as_friend_norequest() else: - assert self.bob_just_add_alice_as_friend() - if True: - # times out - assert self.alice_just_add_bob_as_friend() - else: - assert self.alice_add_bob_as_friend_norequest() >= 0 + assert self.both_add_as_friend() + + if not self.get_connection_status(): + LOG.warning(f"test_friend_message NOT CONNECTED") + self.loop_until_connected() + + iRet = self.bob.friend_get_connection_status(self.baid) + if iRet == TOX_CONNECTION['NONE']: + LOG.error("bob.friend_get_connection_status") + raise RuntimeError("bob.friend_get_connection_status") + iRet = self.alice.friend_get_connection_status(self.abid) + if iRet == TOX_CONNECTION['NONE']: + LOG.error("alice.friend_get_connection_status") + raise RuntimeError("alice.friend_get_connection_status") BID = self.baid #: Test action ACTION = 'Kick' + sSlot = 'friend_read_action' + setattr(self.bob, sSlot, None) + sSlot = 'friend_read_receipt' + setattr(self.bob, sSlot, None) def alices_on_friend_action(iTox, fid, msg_type, action, *largs): - LOG_DEBUG(f"alices_on_friend_action") - assert fid == BID - assert msg_type == TOX_MESSAGE_TYPE['ACTION'] - assert action == ACTION sSlot = 'friend_read_action' + LOG_DEBUG(f"alices_on_friend_action") + try: + assert fid == self.bob.baid + assert msg_type == TOX_MESSAGE_TYPE['ACTION'] + assert action == ACTION + except Exception as e: + LOG_ERROR(f"alices_on_friend_action EXCEPTION {e}") + else: + LOG_INFO(f"alices_on_friend_action {message}") setattr(self.bob, sSlot, True) + sSlot = 'friend_read_action' + setattr(self.alice, sSlot, None) + sSlot = 'friend_read_receipt' + setattr(self.alice, sSlot, None) def alices_on_read_reciept(iTox, fid, msg_id, *largs): LOG_DEBUG(f"alices_on_read_reciept") sSlot = 'friend_read_receipt' - setattr(self.alice, sSlot, True) try: assert fid == BID except Exception as e: LOG_ERROR(f"alices_on_read_reciept {e}") + else: + LOG_INFO(f"alices_on_read_reciept {fid}") + setattr(self.alice, sSlot, True) + sSlot = 'friend_read_receipt' try: - assert self.loop_until_connected() - if not self.get_connection_status(): - LOG.warn(f"test_friend_message NOT CONNECTED") - raise RuntimeError("not connected") - sSlot = 'friend_read_action' setattr(self.bob, sSlot, False) sSlot = 'friend_read_receipt' setattr(self.alice, sSlot, False) self.alice.callback_friend_read_receipt(alices_on_read_reciept) #was alices_on_friend_action + self.warn_if_no_cb(self.alice, sSlot) assert self.wait_ensure_exec(self.bob.friend_send_message, - (self.baid, - TOX_MESSAGE_TYPE['ACTION'], - bytes(ACTION, 'UTF-8'))) - sSlot = 'friend_read_receipt' - assert self.wait_obj_attr(self.alice, sSlot) + [self.baid, + TOX_MESSAGE_TYPE['ACTION'], + bytes(ACTION, 'UTF-8')]) + assert self.wait_otox_attrs(self.alice, [sSlot]) except AssertionError as e: - raise + raise RuntimeError(f"Failed test {e}") except ArgumentError as e: # ArgumentError('This client is currently NOT CONNECTED to the friend.') # dunno - LOG.warn(f"test_friend_action {e}") + LOG.warning(f"test_friend_action {e}") except Exception as e: LOG.error(f"test_friend_action {e}") raise finally: self.alice.callback_friend_read_receipt(None) - - self.bob.friend_delete(self.baid) - self.alice.friend_delete(self.abid) + self.bob.friend_delete(self.baid) + self.alice.friend_delete(self.abid) @unittest.skip('fails') def test_alice_typing_status(self): @@ -1310,59 +1493,50 @@ class ToxSuite(unittest.TestCase): t:friend_get_last_online """ + sSlot = 'friend_typing' # works LOG.info("test_typing_status bob adding alice") - assert self.bob_just_add_alice_as_friend() - self.baid = self.bob.friend_by_public_key(self.alice._address) - assert self.bob.friend_exists(self.baid) - AID = self.baid - - sSlot = 'friend_typing' - LOG.info("test_typing_status alice adding bob") - if False: - # times out - assert self.alice_just_add_bob_as_friend() + if oTOX_OARGS.bIS_LOCAL: + assert self.both_add_as_friend_norequest() else: - assert self.alice_add_bob_as_friend_norequest() >= 0 - self.abid = self.alice.friend_by_public_key(self.bob._address) - assert self.alice.friend_exists(self.abid) + assert self.both_add_as_friend() + + BID = self.baid #: Test typing status def bob_on_friend_typing(iTox, fid, is_typing, *largs): - setattr(self.bob, sSlot, True) try: - assert fid == AID + assert fid == BID assert is_typing is True assert self.bob.friend_get_typing(fid) is True except Exception as e: - LOG.error(f"BOB_ON_friend_typing {e!s}") + LOG.error(f"BOB_ON_friend_typing {e}") raise else: LOG_INFO(f"BOB_ON_friend_typing" + str(fid)) + setattr(self.bob, sSlot, True) + setattr(self.bob, sSlot, None) try: - assert self.loop_until_connected() if not self.get_connection_status(): - LOG.warn(f"test_friend_message NOT CONNECTED") - if oTOX_OARGS.bIS_LOCAL: return - raise RuntimeError("not connected") + LOG.warning(f"test_friend_message NOT CONNECTED") + self.loop_until_connected() - setattr(self.bob, sSlot, False) self.bob.callback_friend_typing(bob_on_friend_typing) self.alice.self_set_typing(self.abid, True) - assert self.wait_obj_attr(self.bob, sSlot) + assert self.wait_otox_attrs(self.bob, [sSlot]) if not hasattr(self.bob, sSlot+'_cb') or \ not getattr(self.bob, sSlot+'_cb'): - LOG.warn(f"self.bob.{sSlot}_cb NOT EXIST") + LOG.warning(f"self.bob.{sSlot}_cb NOT EXIST") except AssertionError as e: - raise + raise RuntimeError(f"Failed test {e}") except Exception as e: LOG.error(f"test_alice_typing_status error={e}") raise finally: self.bob.callback_friend_typing(None) - self.bob.friend_delete(self.baid) - self.alice.friend_delete(self.abid) + self.bob.friend_delete(self.baid) + self.alice.friend_delete(self.abid) @unittest.skip('unfinished') def test_file_transfer(self): # unfinished @@ -1378,8 +1552,11 @@ class ToxSuite(unittest.TestCase): t:on_file_chunk_request """ - self.bob_add_alice_as_friend_norequest() - self.baid = self.bob.friend_by_public_key(self.alice._address) + if oTOX_OARGS.bIS_LOCAL: + assert self.bob_add_alice_as_friend_norequest() + else: + assert self.bob_add_alice_as_friend() + BID = self.baid FRIEND_NUMBER = self.baid @@ -1401,14 +1578,13 @@ class ToxSuite(unittest.TestCase): def alice_on_file_recv(iTox, fid, file_number, kind, size, filename): LOG_DEBUG(f"ALICE_ON_file_recv fid={fid} {file_number}") try: - assert fid == BID assert size == FILE_SIZE assert filename == FILE_NAME retv = self.alice.file_seek(fid, file_number, OFFSET) assert retv is True self.alice.file_control(fid, file_number, TOX_FILE_CONTROL['RESUME']) except Exception as e: - LOG_ERROR(f"ALICE_ON_file_recv {e!s}") + LOG_ERROR(f"ALICE_ON_file_recv {e}") else: LOG_INFO(f"ALICE_ON_file_recv " + str(fid)) @@ -1416,17 +1592,16 @@ class ToxSuite(unittest.TestCase): # TOX_FILE_CONTROL = { 'RESUME': 0, 'PAUSE': 1, 'CANCEL': 2,} LOG_DEBUG(f"ALICE_ON_file_recv_control fid={fid} {file_number} {control}") try: - assert fid == BID assert FILE_NUMBER == file_number # FixMe _FINISHED? if False and control == TOX_FILE_CONTROL['RESUME']: - # assert CONTEXT['RECEIVED'] == FILE_SIZE - # m = hashlib.md5() - # m.update(CONTEXT['FILE']) - # assert m.hexdigest() == FILE_DIGEST + # assert CONTEXT['RECEIVED'] == FILE_SIZE + # m = hashlib.md5() + # m.update(CONTEXT['FILE']) + # assert m.hexdigest() == FILE_DIGEST self.alice.completed = True except Exception as e: - LOG_ERROR(f"ALICE_ON_file_recv {e!s}") + LOG_ERROR(f"ALICE_ON_file_recv {e}") else: LOG_INFO(f"ALICE_ON_file_recv " + str(fid)) @@ -1436,7 +1611,6 @@ class ToxSuite(unittest.TestCase): # FixMe - use file_number and iNumBytes to get data? data = '' try: - assert fid == BID if data is None: assert CONTEXT['RECEIVED'] == (FILE_SIZE - OFFSET) m = hashlib.md5() @@ -1452,7 +1626,7 @@ class ToxSuite(unittest.TestCase): # assert self.file_data_remaining( # fid, file_number, 1) == FILE_SIZE - CONTEXT['RECEIVED'] except Exception as e: - LOG_ERROR(f"ALICE_ON_file_recv_chunk {e!s}") + LOG_ERROR(f"ALICE_ON_file_recv_chunk {e}") else: LOG_INFO(f"ALICE_ON_file_recv_chunk {fid}") @@ -1490,10 +1664,9 @@ class ToxSuite(unittest.TestCase): FILE_ID = 32*'1' # FILE_NAME = b'test.in' - assert self.loop_until_connected() if not self.get_connection_status(): - LOG.warn(f"test_file_transfer NOT CONNECTED") - raise RuntimeError("not connected") + LOG.warning(f"test_file_transfer NOT CONNECTED") + self.loop_until_connected() i = 0 iKind = 0 @@ -1519,9 +1692,13 @@ class ToxSuite(unittest.TestCase): hexFID = "".join([hex(ord(c))[2:].zfill(2) for c in FILE_NAME]) assert FID.startswith(hexFID.upper()) - if not self.wait_objs_attr([self.alice, self.bob], 'completed'): - LOG.warn(f"test_file_transfer not callbacks") + if not self.wait_obj_attrs(self.bob, ['completed']): + LOG.warning(f"test_file_transfer Bob not completed") return False + if not self.wait_obj_attrs(self.alice, ['completed']): + LOG.warning(f"test_file_transfer Alice not completed") + return False + return True except (ArgumentError, ValueError,) as e: # ValueError: non-hexadecimal number found in fromhex() arg at position 0 @@ -1534,6 +1711,7 @@ class ToxSuite(unittest.TestCase): raise finally: + self.bob.friend_delete(self.baid) self.alice.callback_file_recv(None) self.alice.callback_file_recv_control(None) self.alice.callback_file_recv_chunk(None) @@ -1542,12 +1720,16 @@ class ToxSuite(unittest.TestCase): LOG_INFO(f"test_file_transfer:: self.wait_objs_attr completed") + @unittest.skip('crashes') def test_tox_savedata(self): # works sorta # but "{addr} != {self.alice.self_get_address()}" """ t:get_savedata_size t:get_savedata """ + # Fatal Python error: Aborted + # "/var/local/src/toxygen_wrapper/wrapper/tox.py", line 180 in kill + return assert self.alice.get_savedata_size() > 0 data = self.alice.get_savedata() @@ -1556,8 +1738,11 @@ class ToxSuite(unittest.TestCase): # self._address try: + LOG.info("test_tox_savedata alice.kill") + # crashes self.alice.kill() - except: pass + except: + pass oArgs = oTOX_OARGS opts = oToxygenToxOptions(oArgs) @@ -1566,14 +1751,14 @@ class ToxSuite(unittest.TestCase): self.alice = Tox(tox_options=opts) if addr != self.alice.self_get_address(): - LOG.warn("test_tox_savedata " + + LOG.warning("test_tox_savedata " + f"{addr} != {self.alice.self_get_address()}") else: LOG.info("passed test_tox_savedata") def vOargsToxPreamble(oArgs, Tox, ToxTest): - ts.vSetupLogging() + ts.vSetupLogging(oArgs) methods = set([x for x in dir(Tox) if not x[0].isupper() and not x[0] == '_']) @@ -1592,13 +1777,13 @@ def vOargsToxPreamble(oArgs, Tox, ToxTest): def iMain(oArgs): failfast=True - ts.vOargsToxPreamble(oArgs, Tox, ToxSuite) + vOargsToxPreamble(oArgs, Tox, ToxSuite) # https://stackoverflow.com/questions/35930811/how-to-sort-unittest-testcases-properly/35930812#35930812 cases = ts.suiteFactory(*ts.caseFactory([ToxSuite])) if color_runner: - runner = color_runner.runner.TextTestRunner(verbosity=2,failfast=failfast) + runner = color_runner.runner.TextTestRunner(verbosity=2, failfast=failfast) else: - runner = unittest.TextTestRunner(verbosity=2,failfast=failfast) + runner = unittest.TextTestRunner(verbosity=2, failfast=failfast, warnings='ignore') runner.run(cases) def oToxygenToxOptions(oArgs): @@ -1613,17 +1798,19 @@ def oToxygenToxOptions(oArgs): tox_options.contents.udp_enabled = oArgs.udp_enabled if not os.path.exists('/proc/sys/net/ipv6'): oArgs.ipv6_enabled = False + else: + tox_options.contents.ipv6_enabled = oArgs.ipv6_enabled tox_options.contents.tcp_port = int(oArgs.tcp_port) + tox_options.contents.dht_announcements_enabled = oArgs.dht_announcements_enabled + tox_options.contents.hole_punching_enabled = oArgs.hole_punching_enabled # overrides tox_options.contents.local_discovery_enabled = False - tox_options.contents.dht_announcements_enabled = True - tox_options.contents.hole_punching_enabled = False tox_options.contents.experimental_thread_safety = False # REQUIRED!! if oArgs.ipv6_enabled and not os.path.exists('/proc/sys/net/ipv6'): - LOG.warn('Disabling IPV6 because /proc/sys/net/ipv6 does not exist' + repr(oArgs.ipv6_enabled)) + LOG.warning('Disabling IPV6 because /proc/sys/net/ipv6 does not exist' + repr(oArgs.ipv6_enabled)) tox_options.contents.ipv6_enabled = False else: tox_options.contents.ipv6_enabled = bool(oArgs.ipv6_enabled) @@ -1642,7 +1829,7 @@ def oToxygenToxOptions(oArgs): # LOG.debug("Adding logging to tox_options._options_pointer ") ts.vAddLoggerCallback(tox_options, ts.on_log) else: - LOG.warn("No tox_options._options_pointer " +repr(tox_options._options_pointer)) + LOG.warning("No tox_options._options_pointer " +repr(tox_options._options_pointer)) return tox_options @@ -1670,13 +1857,11 @@ def oArgparse(lArgv): def main(lArgs=None): global oTOX_OARGS if lArgs is None: lArgs = [] - print(lArgs) oArgs = oArgparse(lArgs) global bIS_LOCAL bIS_LOCAL = oArgs.network in ['newlocal', 'localnew', 'local'] oTOX_OARGS = oArgs setattr(oTOX_OARGS, 'bIS_LOCAL', bIS_LOCAL) - print(oArgs) bIS_LOCAL = True setattr(oTOX_OARGS, 'bIS_LOCAL', bIS_LOCAL) # oTOX_OPTIONS = ToxOptions() @@ -1697,4 +1882,4 @@ def main(lArgs=None): if __name__ == '__main__': sys.exit(main(sys.argv[1:])) -# Ran 34 tests in 86.589s OK (skipped=12) +# Ran 33 tests in 51.733s