def __init__(self, surface, start_page, tox_opts): MenuUi.__init__(self, surface, start_page) if tox_opts is not None: Tox.__init__(self, tox_opts) self.self_set_name("Toxphone") print('ID: %s' % self.self_get_address()) self.av = ToxPhoneAV(self) self.ring_enabled = False self.ringtone = wave.open('res/audio/ringtone.wav', 'rb') self.ring_stream = None self.ring_thread = None self.aostream = None self.aistream = None self.av.on_call = self.on_call self.av.on_call_state = self.on_call_state self.av.on_bit_rate_status = self.on_bit_rate_status self.av.on_audio_receive_frame = self.on_audio_receive_frame self.iterate_lock = Lock() ''' self.core_iterate_thread_stop = False self.core_iterate_thread = Thread(target=self.core_iterate) self.core_iterate_thread.daemon = True self.core_iterate_thread.start() self.av_iterate_thread_stop = False self.av_iterate_thread = Thread(target=self.av_iterate) self.av_iterate_thread.daemon = True self.av_iterate_thread.start() ''' self.call_status = {'status': False, 'friend_number': None} self.device_index = 0 self.audio_buffer = b'' print('========== AUDIO DEVICES ==========') for i in range(audio.get_device_count()): if audio.get_device_info_by_index(i)['name'] == 'pulse': self.device_index = i print(audio.is_format_supported(RATE, input_device=self.device_index, input_channels=CHANNELS, input_format=pyaudio.paInt16)) print(audio.get_device_info_by_index(i)) self.connect()
def test_tox(self): """ t:size t:save t:load """ assert self.alice.size() > 0 data = self.alice.save() assert data is not None addr = self.alice.get_address() self.alice.kill() self.alice = Tox() self.alice.load(data) assert addr == self.alice.get_address()
def test_tox(self): """ t:get_savedata_size t:get_savedata """ assert self.alice.get_savedata_size() > 0 data = self.alice.get_savedata() assert data is not None addr = self.alice.self_get_address() self.alice.kill() opt = ToxOptions() opt.savedata_data = data opt.savedata_length = len(data) self.alice = Tox(opt) assert addr == self.alice.self_get_address()
def test_tox_from_file(self): """ t:save_to_file t:load_from_file """ self.alice.save_to_file('data') addr = self.alice.get_address() self.alice.kill() self.alice = Tox() #: Test invalid file try: self.alice.load_from_file('not_exists') except OperationFailedError: pass else: assert False self.alice.load_from_file('data') assert addr == self.alice.get_address()
def test_connection_status(self): """ t:get_friend_connection_status t:on_connection_status """ self.bob_add_alice_as_friend() AID = self.aid def on_connection_status(self, friend_id, status): assert friend_id == AID assert status is False self.cs = True BobTox.on_connection_status = on_connection_status self.bob.cs = False self.alice.kill() self.alice = Tox() assert self.wait_callback(self.bob, 'cs') BobTox.on_connection_status = Tox.on_connection_status assert self.bob.get_friend_connection_status(self.aid) is False
def test_connection_status(self): """ t:friend_get_connection_status t:on_friend_connection_status """ self.bob_add_alice_as_friend() AID = self.aid def on_friend_connection_status(self, friend_id, status): assert friend_id == AID assert status is False self.friend_conn_status = True opt = ToxOptions() BobTox.on_friend_connection_status = on_friend_connection_status self.bob.friend_conn_status = False self.alice.kill() self.alice = Tox(opt) assert self.wait_callback(self.bob, 'friend_conn_status') BobTox.on_friend_connection_status = Tox.on_friend_connection_status assert self.bob.friend_get_connection_status(self.aid) is False
def setUp(self): """ t:bootstrap t:self_get_dht_id t:self_get_udp_port """ opt = ToxOptions() self.alice = AliceTox(opt) self.bob = BobTox(opt) self.bob.bootstrap("localhost", self.alice.self_get_udp_port(), self.alice.self_get_dht_id()) self.loop_until_connected()
class ToxTest(unittest.TestCase): def setUp(self): opt = ToxOptions() self.alice = AliceTox(opt) self.bob = BobTox(opt) self.loop_until_connected() def tearDown(self): """ t:kill """ self.alice.kill() self.bob.kill() def loop(self, n): """ t:iterate t:iteration_interval """ interval = self.bob.iteration_interval() for i in range(n): self.alice.iterate() self.bob.iterate() sleep(interval / 2000.0) def loop_until_connected(self): """ t:on_self_connection_status t:self_get_connection_status """ def on_self_connection_status(self, status): if status != Tox.CONNECTION_NONE: self.mycon_status = True else: self.mycon_status = False assert self.self_get_connection_status() == status self.alice.mycon_status = False self.bob.mycon_status = False AliceTox.on_self_connection_status = on_self_connection_status BobTox.on_self_connection_status = on_self_connection_status while not self.alice.mycon_status or not self.bob.mycon_status: self.loop(50) AliceTox.on_self_connection_status = Tox.on_self_connection_status BobTox.on_self_connection_status = Tox.on_self_connection_status def wait_callback(self, obj, attr): count = 0 THRESHOLD = 200 while not getattr(obj, attr): self.loop(50) if count >= THRESHOLD: return False count += 1 return True def wait_callbacks(self, obj, attrs): count = 0 THRESHOLD = 400 while not all([getattr(obj, attr) for attr in attrs]): self.loop(50) if count >= THRESHOLD: return False count += 1 return True def ensure_exec(self, method, args): count = 0 THRESHOLD = 200 while True: try: ret = method(*args) break except Exception as ex: self.loop(50) assert count < THRESHOLD count += 1 return ret def bob_add_alice_as_friend(self): """ t:friend_add t:friend_add_norequest t:on_friend_request t:friend_by_public_key """ MSG = 'Hi, this is Bob.' bob_addr = self.bob.self_get_address() def on_friend_request(self, pk, message): assert pk == bob_addr[:CLIENT_ID_SIZE] assert message == MSG self.friend_add_norequest(pk) self.friend_added = True AliceTox.on_friend_request = on_friend_request alice_addr = self.alice.self_get_address() self.alice.friend_added = False self.bob.friend_add(alice_addr, MSG) assert self.wait_callback(self.alice, 'friend_added') AliceTox.on_friend_request = Tox.on_friend_request self.bid = self.alice.friend_by_public_key(bob_addr) self.aid = self.bob.friend_by_public_key(alice_addr) #: Wait until both are online def on_friend_connection_status(self, friend_id, status): assert status is True self.friend_conn_status = True def on_friend_status(self, friend_id, new_status): self.friend_status = True AliceTox.on_friend_connection_status = on_friend_connection_status BobTox.on_friend_connection_status = on_friend_connection_status AliceTox.on_friend_status = on_friend_status BobTox.on_friend_status = on_friend_status self.alice.friend_conn_status = False self.bob.friend_conn_status = False self.alice.friend_status = False self.bob.friend_status = False assert self.wait_callbacks(self.alice, ['friend_conn_status', 'friend_status']) assert self.wait_callbacks(self.bob, ['friend_conn_status', 'friend_status']) AliceTox.on_friend_connection_status = Tox.on_friend_connection_status BobTox.on_friend_connection_status = Tox.on_friend_connection_status AliceTox.on_friend_status = Tox.on_friend_status BobTox.on_friend_status = Tox.on_friend_status def test_bootstrap(self): """ t:bootstrap """ assert self.alice.self_get_connection_status() != Tox.CONNECTION_NONE assert self.bob.self_get_connection_status() != Tox.CONNECTION_NONE def test_address(self): """ t:self_get_address t:self_get_nospam t:self_set_nospam t:self_get_keys """ assert len(self.alice.self_get_address()) == ADDR_SIZE assert len(self.bob.self_get_address()) == ADDR_SIZE self.alice.self_set_nospam(0x12345678) assert self.alice.self_get_nospam() == 0x12345678 pk, sk = self.alice.self_get_keys() assert pk == self.alice.self_get_address()[:CLIENT_ID_SIZE] def test_self_name(self): """ t:self_set_name t:self_get_name t:self_get_name_size """ self.alice.self_set_name('Alice') self.loop(10) assert self.alice.self_get_name() == 'Alice' assert self.alice.self_get_name_size() == len('Alice') def test_status_message(self): """ t:self_set_status_message t:self_get_status_message t:self_get_status_message_size t:friend_set_status_message t:friend_get_status_message t:friend_get_status_message_size t:on_friend_status_message """ self.bob_add_alice_as_friend() MSG = 'Happy' AID = self.aid def on_friend_status_message(self, friend_id, new_message): assert friend_id == AID assert new_message == MSG self.sm = True BobTox.on_friend_status_message = on_friend_status_message self.bob.sm = False self.alice.self_set_status_message(MSG) assert self.wait_callback(self.bob, 'sm') BobTox.on_friend_status_message = Tox.on_friend_status_message assert self.alice.self_get_status_message() == MSG assert self.alice.self_get_status_message_size() == len(MSG) assert self.bob.friend_get_status_message(self.aid) == MSG assert self.bob.friend_get_status_message_size(self.aid) == len(MSG) def test_user_status(self): """ t:self_get_status t:self_set_status t:friend_get_status t:friend_get_status t:on_friend_status """ self.bob_add_alice_as_friend() AID = self.aid def on_friend_status(self, friend_id, new_status): assert friend_id == AID assert new_status == Tox.USER_STATUS_BUSY self.friend_status = True self.alice.self_set_status(Tox.USER_STATUS_BUSY) BobTox.on_friend_status = on_friend_status self.bob.friend_status = False assert self.wait_callback(self.bob, 'friend_status') BobTox.on_friend_status = Tox.on_friend_status assert self.alice.self_get_status() == Tox.USER_STATUS_BUSY assert self.bob.friend_get_status(self.aid) == Tox.USER_STATUS_BUSY def test_connection_status(self): """ t:friend_get_connection_status t:on_friend_connection_status """ self.bob_add_alice_as_friend() AID = self.aid def on_friend_connection_status(self, friend_id, status): assert friend_id == AID assert status is False self.friend_conn_status = True opt = ToxOptions() BobTox.on_friend_connection_status = on_friend_connection_status self.bob.friend_conn_status = False self.alice.kill() self.alice = Tox(opt) assert self.wait_callback(self.bob, 'friend_conn_status') BobTox.on_friend_connection_status = Tox.on_friend_connection_status assert self.bob.friend_get_connection_status(self.aid) is False def test_tox(self): """ t:get_savedata_size t:get_savedata """ assert self.alice.get_savedata_size() > 0 data = self.alice.get_savedata() assert data is not None addr = self.alice.self_get_address() self.alice.kill() opt = ToxOptions() opt.savedata_data = data opt.savedata_length = len(data) self.alice = Tox(opt) assert addr == self.alice.self_get_address() def test_friend(self): """ t:friend_delete t:friend_exists t:friend_get_public_key t:self_get_friend_list t:self_get_friend_list_size t:self_set_name t:friend_get_name t:friend_get_name_size t:on_friend_name """ #: Test friend request self.bob_add_alice_as_friend() assert self.alice.friend_exists(self.bid) assert self.bob.friend_exists(self.aid) #: Test friend exists assert not self.alice.friend_exists(self.bid + 1) assert not self.bob.friend_exists(self.aid + 1) #: Test friend_get_public_key assert self.alice.friend_get_public_key(self.bid) == \ self.bob.self_get_address()[:CLIENT_ID_SIZE] assert self.bob.friend_get_public_key(self.aid) == \ self.alice.self_get_address()[:CLIENT_ID_SIZE] #: Test self_get_friend_list assert self.alice.self_get_friend_list() == [self.bid] assert self.bob.self_get_friend_list() == [self.aid] assert self.alice.self_get_friend_list_size() == 1 assert self.bob.self_get_friend_list_size() == 1 #: Test friend name NEWNAME = 'Jenny' AID = self.aid def on_friend_name(self, fid, newname): assert fid == AID assert newname == NEWNAME self.nc = True BobTox.on_friend_name = on_friend_name self.bob.nc = False self.alice.self_set_name(NEWNAME) assert self.wait_callback(self.bob, 'nc') assert self.bob.friend_get_name(self.aid) == NEWNAME assert self.bob.friend_get_name_size(self.aid) == len(NEWNAME) BobTox.on_friend_name = Tox.on_friend_name def test_friend_message_and_action(self): """ t:on_friend_action t:on_friend_message t:friend_send_message """ self.bob_add_alice_as_friend() #: Test message MSG = 'Hi, Bob!' BID = self.bid def on_friend_message(self, fid, msg_type, message): assert fid == BID assert message == MSG self.fm = True AliceTox.on_friend_message = on_friend_message self.ensure_exec(self.bob.friend_send_message, (self.aid, Tox.MESSAGE_TYPE_NORMAL, MSG)) self.alice.fm = False assert self.wait_callback(self.alice, 'fm') AliceTox.on_friend_message = Tox.on_friend_message #: Test action ACTION = 'Kick' BID = self.bid def on_friend_action(self, fid, msg_type, action): assert fid == BID assert action == ACTION self.fa = True AliceTox.on_friend_message = on_friend_action self.ensure_exec(self.bob.friend_send_message, (self.aid, Tox.MESSAGE_TYPE_ACTION, ACTION)) self.alice.fa = False assert self.wait_callback(self.alice, 'fa') AliceTox.on_friend_message = Tox.on_friend_message #: Test delete friend self.alice.friend_delete(self.bid) self.loop(10) assert not self.alice.friend_exists(self.bid) def test_meta_status(self): """ t:on_friend_read_receipt t:on_friend_typing t:self_set_typing t:friend_get_typing t:friend_get_last_online """ self.bob_add_alice_as_friend() AID = self.aid #: Test typing status def on_friend_typing(self, fid, is_typing): assert fid == AID assert is_typing is True assert self.friend_get_typing(fid) is True self.friend_typing = True BobTox.on_friend_typing = on_friend_typing self.bob.friend_typing = False self.alice.self_set_typing(self.bid, True) assert self.wait_callback(self.bob, 'friend_typing') BobTox.on_friend_typing = Tox.on_friend_typing #: Test last online assert self.alice.friend_get_last_online(self.bid) is not None assert self.bob.friend_get_last_online(self.aid) is not None def test_group(self): """ t:add_groupchat t:count_chatlist t:del_groupchat t:get_chatlist t:group_action_send t:group_get_names t:group_get_title t:group_get_type t:group_message_send t:group_number_peers t:group_peername t:group_set_title t:invite_friend t:join_groupchat t:on_group_action t:on_group_invite t:on_group_message t:on_group_namelist_change """ self.bob_add_alice_as_friend() #: Test group add group_id = self.bob.add_groupchat() assert group_id >= 0 self.loop(50) BID = self.bid def on_group_invite(self, fid, type_, data): assert fid == BID assert type_ == 0 gn = self.join_groupchat(fid, data) assert type_ == self.group_get_type(gn) self.gi = True AliceTox.on_group_invite = on_group_invite def on_group_namelist_change(self, gid, peer_number, change): assert gid == group_id assert change == Tox.CHAT_CHANGE_PEER_ADD self.gn = True AliceTox.on_group_namelist_change = on_group_namelist_change self.alice.gi = False self.alice.gn = False self.ensure_exec(self.bob.invite_friend, (self.aid, group_id)) assert self.wait_callbacks(self.alice, ['gi', 'gn']) AliceTox.on_group_invite = Tox.on_group_invite AliceTox.on_group_namelist_change = Tox.on_group_namelist_change #: Test group number of peers self.loop(50) assert self.bob.group_number_peers(group_id) == 2 #: Test group peername self.alice.self_set_name('Alice') self.bob.self_set_name('Bob') def on_group_namelist_change(self, gid, peer_number, change): if change == Tox.CHAT_CHANGE_PEER_NAME: self.gn = True AliceTox.on_group_namelist_change = on_group_namelist_change self.alice.gn = False assert self.wait_callback(self.alice, 'gn') AliceTox.on_group_namelist_change = Tox.on_group_namelist_change peernames = [self.bob.group_peername(group_id, i) for i in range(self.bob.group_number_peers(group_id))] assert 'Alice' in peernames assert 'Bob' in peernames assert sorted(self.bob.group_get_names(group_id)) == ['Alice', 'Bob'] #: Test title change self.bob.group_set_title(group_id, 'My special title') assert self.bob.group_get_title(group_id) == 'My special title' #: Test group message AID = self.aid BID = self.bid MSG = 'Group message test' def on_group_message(self, gid, fgid, message): if fgid == AID: assert gid == group_id assert message == MSG self.gm = True AliceTox.on_group_message = on_group_message self.alice.gm = False self.ensure_exec(self.bob.group_message_send, (group_id, MSG)) assert self.wait_callback(self.alice, 'gm') AliceTox.on_group_message = Tox.on_group_message #: Test group action AID = self.aid BID = self.bid MSG = 'Group action test' def on_group_action(self, gid, fgid, action): if fgid == AID: assert gid == group_id assert action == MSG self.ga = True AliceTox.on_group_action = on_group_action self.alice.ga = False self.ensure_exec(self.bob.group_action_send, (group_id, MSG)) assert self.wait_callback(self.alice, 'ga') AliceTox.on_group_action = Tox.on_group_action #: Test chatlist assert len(self.bob.get_chatlist()) == self.bob.count_chatlist() assert len(self.alice.get_chatlist()) == self.bob.count_chatlist() assert self.bob.count_chatlist() == 1 self.bob.del_groupchat(group_id) assert self.bob.count_chatlist() == 0 def test_file_transfer(self): """ t:file_send t:file_send_chunk t:file_control t:file_seek t:file_get_file_id t:on_file_recv t:on_file_recv_control t:on_file_recv_chunk t:on_file_chunk_request """ self.bob_add_alice_as_friend() FILE = os.urandom(1024 * 1024) FILE_NAME = "test.bin" FILE_SIZE = len(FILE) OFFSET = 567 m = hashlib.md5() m.update(FILE[OFFSET:]) FILE_DIGEST = m.hexdigest() BID = self.bid CONTEXT = {'FILE': bytes(), 'RECEIVED': 0, 'START': False, 'SENT': 0} self.alice.completed = False self.bob.completed = False def on_file_recv(self, fid, filenumber, kind, size, filename): assert fid == BID assert size == FILE_SIZE assert filename == FILE_NAME retv = self.file_seek(fid, filenumber, OFFSET) assert retv is True self.file_control(fid, filenumber, Tox.FILE_CONTROL_RESUME) def on_file_recv_control(self, fid, file_number, control): assert fid == BID # if receive_send == 0 and ct == Tox.FILE_CONTROL_FINISHED: # assert CONTEXT['RECEIVED'] == FILE_SIZE # m = hashlib.md5() # m.update(CONTEXT['FILE']) # assert m.hexdigest() == FILE_DIGEST # self.completed = True def on_file_recv_chunk(self, fid, file_number, position, data): assert fid == BID if data is None: assert CONTEXT['RECEIVED'] == (FILE_SIZE - OFFSET) m = hashlib.md5() m.update(CONTEXT['FILE']) assert m.hexdigest() == FILE_DIGEST self.completed = True self.file_control(fid, file_number, Tox.FILE_CONTROL_CANCEL) return CONTEXT['FILE'] += data CONTEXT['RECEIVED'] += len(data) # if CONTEXT['RECEIVED'] < FILE_SIZE: # assert self.file_data_remaining( # fid, file_number, 1) == FILE_SIZE - CONTEXT['RECEIVED'] # AliceTox.on_file_send_request = on_file_send_request # AliceTox.on_file_control = on_file_control # AliceTox.on_file_data = on_file_data AliceTox.on_file_recv = on_file_recv AliceTox.on_file_recv_control = on_file_recv_control AliceTox.on_file_recv_chunk = on_file_recv_chunk def on_file_recv_control2(self, fid, file_number, control): if control == Tox.FILE_CONTROL_RESUME: CONTEXT['START'] = True elif control == Tox.FILE_CONTROL_CANCEL: self.completed = True pass def on_file_chunk_request(self, fid, file_number, position, length): if length == 0: return data = FILE[position:(position + length)] self.file_send_chunk(fid, file_number, position, data) BobTox.on_file_recv_control = on_file_recv_control2 BobTox.on_file_chunk_request = on_file_chunk_request FN = self.bob.file_send(self.aid, 0, FILE_SIZE, FILE_NAME, FILE_NAME) FID = self.bob.file_get_file_id(self.aid, FN) hexFID = "".join([hex(ord(c))[2:].zfill(2) for c in FILE_NAME]) assert FID.startswith(hexFID.upper()) while not self.alice.completed and not self.bob.completed: self.alice.iterate() self.bob.iterate() sleep(0.02) AliceTox.on_file_recv = Tox.on_file_recv AliceTox.on_file_recv_control = Tox.on_file_recv_control AliceTox.on_file_recv_chunk = Tox.on_file_recv_chunk BobTox.on_file_recv_control = Tox.on_file_recv_control BobTox.on_file_chunk_request = Tox.on_file_chunk_request
def setUp(self): self.alice = AliceTox() self.bob = BobTox() self.loop_until_connected()
class ToxTest(unittest.TestCase): def setUp(self): self.alice = AliceTox() self.bob = BobTox() self.loop_until_connected() def tearDown(self): """ t:kill """ self.alice.kill() self.bob.kill() def loop(self, n): """ t:do t:do_interval """ interval = self.bob.do_interval() for i in range(n): self.alice.do() self.bob.do() sleep(interval / 2000.0) def loop_until_connected(self): """ t:isconnected """ while not self.alice.isconnected() or not self.bob.isconnected(): self.loop(50) def wait_callback(self, obj, attr): count = 0 THRESHOLD = 200 while not getattr(obj, attr): self.loop(50) if count >= THRESHOLD: return False count += 1 return True def wait_callbacks(self, obj, attrs): count = 0 THRESHOLD = 400 while not all([getattr(obj, attr) for attr in attrs]): self.loop(50) if count >= THRESHOLD: return False count += 1 return True def ensure_exec(self, method, args): count = 0 THRESHOLD = 200 while True: try: ret = method(*args) break except: self.loop(50) assert count < THRESHOLD count += 1 return ret def bob_add_alice_as_friend(self): """ t:add_friend t:add_friend_norequest t:on_friend_request t:get_friend_id """ MSG = 'Hi, this is Bob.' bob_addr = self.bob.get_address() def on_friend_request(self, pk, message): assert pk == bob_addr[:CLIENT_ID_SIZE] assert message == MSG self.add_friend_norequest(pk) self.fr = True AliceTox.on_friend_request = on_friend_request alice_addr = self.alice.get_address() self.alice.fr = False self.bob.add_friend(alice_addr, MSG) assert self.wait_callback(self.alice, 'fr') AliceTox.on_friend_request = Tox.on_friend_request self.bid = self.alice.get_friend_id(bob_addr) self.aid = self.bob.get_friend_id(alice_addr) #: Wait until both are online def on_connection_status(self, friend_id, status): assert status is True self.cs = True def on_user_status(self, friend_id, new_status): self.us = True AliceTox.on_connection_status = on_connection_status BobTox.on_connection_status = on_connection_status AliceTox.on_user_status = on_user_status BobTox.on_user_status = on_user_status self.alice.cs = False self.bob.cs = False self.alice.us = False self.bob.us = False assert self.wait_callbacks(self.alice, ['cs', 'us']) assert self.wait_callbacks(self.bob, ['cs', 'us']) AliceTox.on_connection_status = Tox.on_connection_status BobTox.on_connection_status = Tox.on_connection_status AliceTox.on_user_status = Tox.on_user_status BobTox.on_user_status = Tox.on_user_status def test_boostrap(self): """ t:bootstrap_from_address """ assert self.alice.isconnected() assert self.bob.isconnected() def test_address(self): """ t:get_address t:get_nospam t:set_nospam t:get_keys """ assert len(self.alice.get_address()) == ADDR_SIZE assert len(self.bob.get_address()) == ADDR_SIZE self.alice.set_nospam(0x12345678) assert self.alice.get_nospam() == 0x12345678 pk, sk = self.alice.get_keys() assert pk == self.alice.get_address()[:CLIENT_ID_SIZE] def test_self_name(self): """ t:set_name t:get_self_name t:get_self_name_size """ self.alice.set_name('Alice') self.loop(10) assert self.alice.get_self_name() == 'Alice' assert self.alice.get_self_name_size() == len('Alice') def test_status_message(self): """ t:get_self_status_message t:get_self_status_message_size t:get_status_message t:get_status_message_size t:on_status_message t:set_status_message """ self.bob_add_alice_as_friend() MSG = 'Happy' AID = self.aid def on_status_message(self, friend_id, new_message): assert friend_id == AID assert new_message == MSG self.sm = True BobTox.on_status_message = on_status_message self.bob.sm = False self.alice.set_status_message(MSG) assert self.wait_callback(self.bob, 'sm') BobTox.on_status_message = Tox.on_status_message assert self.alice.get_self_status_message() == MSG assert self.alice.get_self_status_message_size() == len(MSG) assert self.bob.get_status_message(self.aid) == MSG assert self.bob.get_status_message_size(self.aid) == len(MSG) def test_user_status(self): """ t:get_self_user_status t:get_user_status t:on_user_status t:set_user_status """ self.bob_add_alice_as_friend() AID = self.aid def on_user_status(self, friend_id, new_status): assert friend_id == AID assert new_status == Tox.USERSTATUS_BUSY self.us = True self.alice.set_user_status(Tox.USERSTATUS_BUSY) BobTox.on_user_status = on_user_status self.bob.us = False assert self.wait_callback(self.bob, 'us') BobTox.on_user_status = Tox.on_user_status assert self.alice.get_self_user_status() == Tox.USERSTATUS_BUSY assert self.bob.get_user_status(self.aid) == Tox.USERSTATUS_BUSY def test_connection_status(self): """ t:get_friend_connection_status t:on_connection_status """ self.bob_add_alice_as_friend() AID = self.aid def on_connection_status(self, friend_id, status): assert friend_id == AID assert status is False self.cs = True BobTox.on_connection_status = on_connection_status self.bob.cs = False self.alice.kill() self.alice = Tox() assert self.wait_callback(self.bob, 'cs') BobTox.on_connection_status = Tox.on_connection_status assert self.bob.get_friend_connection_status(self.aid) is False def test_tox(self): """ t:size t:save t:load """ assert self.alice.size() > 0 data = self.alice.save() assert data is not None addr = self.alice.get_address() self.alice.kill() self.alice = Tox() self.alice.load(data) assert addr == self.alice.get_address() def test_tox_from_file(self): """ t:save_to_file t:load_from_file """ self.alice.save_to_file('data') addr = self.alice.get_address() self.alice.kill() self.alice = Tox() #: Test invalid file try: self.alice.load_from_file('not_exists') except OperationFailedError: pass else: assert False self.alice.load_from_file('data') assert addr == self.alice.get_address() def test_friend(self): """ t:count_friendlist t:del_friend t:friend_exists t:get_client_id t:get_friendlist t:get_name t:get_name_size t:get_num_online_friends t:on_name_change """ #: Test friend request self.bob_add_alice_as_friend() assert self.alice.friend_exists(self.bid) assert self.bob.friend_exists(self.aid) #: Test friend exists assert not self.alice.friend_exists(self.bid + 1) assert not self.bob.friend_exists(self.aid + 1) #: Test get_cliend_id assert self.alice.get_client_id(self.bid) == \ self.bob.get_address()[:CLIENT_ID_SIZE] assert self.bob.get_client_id(self.aid) == \ self.alice.get_address()[:CLIENT_ID_SIZE] #: Test friendlist assert self.alice.get_friendlist() == [self.bid] assert self.bob.get_friendlist() == [self.aid] assert self.alice.count_friendlist() == 1 assert self.bob.count_friendlist() == 1 assert self.alice.get_num_online_friends() == 1 assert self.bob.get_num_online_friends() == 1 #: Test friend name NEWNAME = 'Jenny' AID = self.aid def on_name_change(self, fid, newname): assert fid == AID assert newname == NEWNAME self.nc = True BobTox.on_name_change = on_name_change self.bob.nc = False self.alice.set_name(NEWNAME) assert self.wait_callback(self.bob, 'nc') assert self.bob.get_name(self.aid) == NEWNAME assert self.bob.get_name_size(self.aid) == len(NEWNAME) BobTox.on_name_change = Tox.on_name_change def test_friend_message_and_action(self): """ t:on_friend_action t:on_friend_message t:send_action t:send_message """ self.bob_add_alice_as_friend() #: Test message MSG = 'Hi, Bob!' BID = self.bid def on_friend_message(self, fid, message): assert fid == BID assert message == MSG self.fm = True AliceTox.on_friend_message = on_friend_message self.ensure_exec(self.bob.send_message, (self.aid, MSG)) self.alice.fm = False assert self.wait_callback(self.alice, 'fm') AliceTox.on_friend_message = Tox.on_friend_message #: Test action ACTION = 'Kick' BID = self.bid def on_friend_action(self, fid, action): assert fid == BID assert action == ACTION self.fa = True AliceTox.on_friend_action = on_friend_action self.ensure_exec(self.bob.send_action, (self.aid, ACTION)) self.alice.fa = False assert self.wait_callback(self.alice, 'fa') AliceTox.on_friend_action = Tox.on_friend_action #: Test delete friend self.alice.del_friend(self.bid) self.loop(10) assert not self.alice.friend_exists(self.bid) def test_meta_status(self): """ t:on_read_receipt t:on_typing_change t:set_user_is_typing t:get_is_typing t:get_last_online """ self.bob_add_alice_as_friend() AID = self.aid #: Test typing status def on_typing_change(self, fid, is_typing): assert fid == AID assert is_typing is True assert self.get_is_typing(fid) is True self.ut = True BobTox.on_typing_change = on_typing_change self.bob.ut = False self.alice.set_user_is_typing(self.bid, True) assert self.wait_callback(self.bob, 'ut') BobTox.on_typing_change = Tox.on_typing_change #: Test last online assert self.alice.get_last_online(self.bid) is not None assert self.bob.get_last_online(self.aid) is not None @unittest.skip("groupchat is under major refactor in toxcore") def test_group(self): """ t:add_groupchat t:count_chatlist t:del_groupchat t:get_chatlist t:group_action_send t:group_get_names t:group_message_send t:group_number_peers t:group_peername t:invite_friend t:join_groupchat t:on_group_action t:on_group_invite t:on_group_message t:on_group_namelist_change """ self.bob_add_alice_as_friend() #: Test group add group_id = self.bob.add_groupchat() assert group_id >= 0 self.loop(50) BID = self.bid def on_group_invite(self, fid, data): assert fid == BID self.join_groupchat(fid, data) self.gi = True AliceTox.on_group_invite = on_group_invite def on_group_namelist_change(self, gid, peer_number, change): assert gid == group_id assert change == Tox.CHAT_CHANGE_PEER_ADD self.gn = True AliceTox.on_group_namelist_change = on_group_namelist_change self.alice.gi = False self.alice.gn = False self.ensure_exec(self.bob.invite_friend, (self.aid, group_id)) assert self.wait_callbacks(self.alice, ['gi', 'gn']) AliceTox.on_group_invite = Tox.on_group_invite AliceTox.on_group_namelist_change = Tox.on_group_namelist_change #: Test group number of peers self.loop(50) assert self.bob.group_number_peers(group_id) == 2 #: Test group peername self.alice.set_name('Alice') self.bob.set_name('Bob') def on_group_namelist_change(self, gid, peer_number, change): if change == Tox.CHAT_CHANGE_PEER_NAME: self.gn = True AliceTox.on_group_namelist_change = on_group_namelist_change self.alice.gn = False assert self.wait_callback(self.alice, 'gn') AliceTox.on_group_namelist_change = Tox.on_group_namelist_change peernames = [ self.bob.group_peername(group_id, i) for i in range(self.bob.group_number_peers(group_id)) ] assert 'Alice' in peernames assert 'Bob' in peernames assert sorted(self.bob.group_get_names(group_id)) == ['Alice', 'Bob'] #: Test group message AID = self.aid BID = self.bid MSG = 'Group message test' def on_group_message(self, gid, fgid, message): if fgid == AID: assert gid == group_id assert message == MSG self.gm = True AliceTox.on_group_message = on_group_message self.alice.gm = False self.ensure_exec(self.bob.group_message_send, (group_id, MSG)) assert self.wait_callback(self.alice, 'gm') AliceTox.on_group_message = Tox.on_group_message #: Test group action AID = self.aid BID = self.bid MSG = 'Group action test' def on_group_action(self, gid, fgid, action): if fgid == AID: assert gid == group_id assert action == MSG self.ga = True AliceTox.on_group_action = on_group_action self.alice.ga = False self.ensure_exec(self.bob.group_action_send, (group_id, MSG)) assert self.wait_callback(self.alice, 'ga') AliceTox.on_group_action = Tox.on_group_action #: Test chatlist assert len(self.bob.get_chatlist()) == self.bob.count_chatlist() assert len(self.alice.get_chatlist()) == self.bob.count_chatlist() assert self.bob.count_chatlist() == 1 self.bob.del_groupchat(group_id) assert self.bob.count_chatlist() == 0 def test_file_transfer(self): """ t:file_data_remaining t:file_data_size t:file_send_control t:file_send_data t:new_file_sender t:on_file_control t:on_file_data t:on_file_send_request """ self.bob_add_alice_as_friend() FILE = os.urandom(1024 * 1024) FILE_NAME = "test.bin" FILE_SIZE = len(FILE) m = hashlib.md5() m.update(FILE) FILE_DIGEST = m.hexdigest() BID = self.bid CONTEXT = {'FILE': bytes(), 'RECEIVED': 0, 'START': False, 'SENT': 0} def on_file_send_request(self, fid, filenumber, size, filename): assert fid == BID assert size == FILE_SIZE assert filename == FILE_NAME self.file_send_control(fid, 1, filenumber, Tox.FILECONTROL_ACCEPT) def on_file_control(self, fid, receive_send, file_number, ct, data): assert fid == BID if receive_send == 0 and ct == Tox.FILECONTROL_FINISHED: assert CONTEXT['RECEIVED'] == FILE_SIZE m = hashlib.md5() m.update(CONTEXT['FILE']) assert m.hexdigest() == FILE_DIGEST self.completed = True def on_file_data(self, fid, file_number, data): assert fid == BID CONTEXT['FILE'] += data CONTEXT['RECEIVED'] += len(data) if CONTEXT['RECEIVED'] < FILE_SIZE: assert self.file_data_remaining( fid, file_number, 1) == FILE_SIZE - CONTEXT['RECEIVED'] AliceTox.on_file_send_request = on_file_send_request AliceTox.on_file_control = on_file_control AliceTox.on_file_data = on_file_data def on_file_control2(self, fid, receive_send, file_number, ct, data): if receive_send == 1 and ct == Tox.FILECONTROL_ACCEPT: CONTEXT['START'] = True BobTox.on_file_control = on_file_control2 self.alice.completed = False BLK = self.bob.file_data_size(self.aid) FN = self.bob.new_file_sender(self.aid, FILE_SIZE, FILE_NAME) while not self.alice.completed: if CONTEXT['START']: try: while True: if CONTEXT['SENT'] == FILE_SIZE: self.bob.file_send_control( self.aid, 0, FN, Tox.FILECONTROL_FINISHED) CONTEXT['START'] = False break else: ed = CONTEXT['SENT'] + BLK if ed > FILE_SIZE: ed = FILE_SIZE self.bob.file_send_data(self.aid, FN, FILE[CONTEXT['SENT']:ed]) CONTEXT['SENT'] = ed except: pass self.alice.do() self.bob.do() sleep(0.02) AliceTox.on_file_send_request = Tox.on_file_send_request AliceTox.on_file_control = Tox.on_file_control AliceTox.on_file_data = Tox.on_file_data BobTox.on_file_control = Tox.on_file_control
class ToxTest(unittest.TestCase): def setUp(self): self.alice = AliceTox() self.bob = BobTox() self.loop_until_connected() def tearDown(self): """ t:kill """ self.alice.kill() self.bob.kill() def loop(self, n): """ t:do t:do_interval """ interval = self.bob.do_interval() for i in range(n): self.alice.do() self.bob.do() sleep(interval / 2000.0) def loop_until_connected(self): """ t:isconnected """ while not self.alice.isconnected() or not self.bob.isconnected(): self.loop(50) def wait_callback(self, obj, attr): count = 0 THRESHOLD = 200 while not getattr(obj, attr): self.loop(50) if count >= THRESHOLD: return False count += 1 return True def wait_callbacks(self, obj, attrs): count = 0 THRESHOLD = 400 while not all([getattr(obj, attr) for attr in attrs]): self.loop(50) if count >= THRESHOLD: return False count += 1 return True def ensure_exec(self, method, args): count = 0 THRESHOLD = 200 while True: try: ret = method(*args) break except: self.loop(50) assert count < THRESHOLD count += 1 return ret def bob_add_alice_as_friend(self): """ t:add_friend t:add_friend_norequest t:on_friend_request t:get_friend_id """ MSG = 'Hi, this is Bob.' bob_addr = self.bob.get_address() def on_friend_request(self, pk, message): assert pk == bob_addr[:CLIENT_ID_SIZE] assert message == MSG self.add_friend_norequest(pk) self.fr = True AliceTox.on_friend_request = on_friend_request alice_addr = self.alice.get_address() self.alice.fr = False self.bob.add_friend(alice_addr, MSG) assert self.wait_callback(self.alice, 'fr') AliceTox.on_friend_request = Tox.on_friend_request self.bid = self.alice.get_friend_id(bob_addr) self.aid = self.bob.get_friend_id(alice_addr) #: Wait until both are online def on_connection_status(self, friend_id, status): assert status is True self.cs = True def on_user_status(self, friend_id, new_status): self.us = True AliceTox.on_connection_status = on_connection_status BobTox.on_connection_status = on_connection_status AliceTox.on_user_status = on_user_status BobTox.on_user_status = on_user_status self.alice.cs = False self.bob.cs = False self.alice.us = False self.bob.us = False assert self.wait_callbacks(self.alice, ['cs', 'us']) assert self.wait_callbacks(self.bob, ['cs', 'us']) AliceTox.on_connection_status = Tox.on_connection_status BobTox.on_connection_status = Tox.on_connection_status AliceTox.on_user_status = Tox.on_user_status BobTox.on_user_status = Tox.on_user_status def test_boostrap(self): """ t:bootstrap_from_address """ assert self.alice.isconnected() assert self.bob.isconnected() def test_address(self): """ t:get_address t:get_nospam t:set_nospam t:get_keys """ assert len(self.alice.get_address()) == ADDR_SIZE assert len(self.bob.get_address()) == ADDR_SIZE self.alice.set_nospam(0x12345678) assert self.alice.get_nospam() == 0x12345678 pk, sk = self.alice.get_keys() assert pk == self.alice.get_address()[:CLIENT_ID_SIZE] def test_self_name(self): """ t:set_name t:get_self_name t:get_self_name_size """ self.alice.set_name('Alice') self.loop(10) assert self.alice.get_self_name() == 'Alice' assert self.alice.get_self_name_size() == len('Alice') def test_status_message(self): """ t:get_self_status_message t:get_self_status_message_size t:get_status_message t:get_status_message_size t:on_status_message t:set_status_message """ self.bob_add_alice_as_friend() MSG = 'Happy' AID = self.aid def on_status_message(self, friend_id, new_message): assert friend_id == AID assert new_message == MSG self.sm = True BobTox.on_status_message = on_status_message self.bob.sm = False self.alice.set_status_message(MSG) assert self.wait_callback(self.bob, 'sm') BobTox.on_status_message = Tox.on_status_message assert self.alice.get_self_status_message() == MSG assert self.alice.get_self_status_message_size() == len(MSG) assert self.bob.get_status_message(self.aid) == MSG assert self.bob.get_status_message_size(self.aid) == len(MSG) def test_user_status(self): """ t:get_self_user_status t:get_user_status t:on_user_status t:set_user_status """ self.bob_add_alice_as_friend() AID = self.aid def on_user_status(self, friend_id, new_status): assert friend_id == AID assert new_status == Tox.USERSTATUS_BUSY self.us = True self.alice.set_user_status(Tox.USERSTATUS_BUSY) BobTox.on_user_status = on_user_status self.bob.us = False assert self.wait_callback(self.bob, 'us') BobTox.on_user_status = Tox.on_user_status assert self.alice.get_self_user_status() == Tox.USERSTATUS_BUSY assert self.bob.get_user_status(self.aid) == Tox.USERSTATUS_BUSY def test_connection_status(self): """ t:get_friend_connection_status t:on_connection_status """ self.bob_add_alice_as_friend() AID = self.aid def on_connection_status(self, friend_id, status): assert friend_id == AID assert status is False self.cs = True BobTox.on_connection_status = on_connection_status self.bob.cs = False self.alice.kill() self.alice = Tox() assert self.wait_callback(self.bob, 'cs') BobTox.on_connection_status = Tox.on_connection_status assert self.bob.get_friend_connection_status(self.aid) is False def test_tox(self): """ t:size t:save t:load """ assert self.alice.size() > 0 data = self.alice.save() assert data is not None addr = self.alice.get_address() self.alice.kill() self.alice = Tox() self.alice.load(data) assert addr == self.alice.get_address() def test_tox_from_file(self): """ t:save_to_file t:load_from_file """ self.alice.save_to_file('data') addr = self.alice.get_address() self.alice.kill() self.alice = Tox() #: Test invalid file try: self.alice.load_from_file('not_exists') except OperationFailedError: pass else: assert False self.alice.load_from_file('data') assert addr == self.alice.get_address() def test_friend(self): """ t:count_friendlist t:del_friend t:friend_exists t:get_client_id t:get_friendlist t:get_name t:get_name_size t:get_num_online_friends t:on_name_change """ #: Test friend request self.bob_add_alice_as_friend() assert self.alice.friend_exists(self.bid) assert self.bob.friend_exists(self.aid) #: Test friend exists assert not self.alice.friend_exists(self.bid + 1) assert not self.bob.friend_exists(self.aid + 1) #: Test get_cliend_id assert self.alice.get_client_id(self.bid) == \ self.bob.get_address()[:CLIENT_ID_SIZE] assert self.bob.get_client_id(self.aid) == \ self.alice.get_address()[:CLIENT_ID_SIZE] #: Test friendlist assert self.alice.get_friendlist() == [self.bid] assert self.bob.get_friendlist() == [self.aid] assert self.alice.count_friendlist() == 1 assert self.bob.count_friendlist() == 1 assert self.alice.get_num_online_friends() == 1 assert self.bob.get_num_online_friends() == 1 #: Test friend name NEWNAME = 'Jenny' AID = self.aid def on_name_change(self, fid, newname): assert fid == AID assert newname == NEWNAME self.nc = True BobTox.on_name_change = on_name_change self.bob.nc = False self.alice.set_name(NEWNAME) assert self.wait_callback(self.bob, 'nc') assert self.bob.get_name(self.aid) == NEWNAME assert self.bob.get_name_size(self.aid) == len(NEWNAME) BobTox.on_name_change = Tox.on_name_change def test_friend_message_and_action(self): """ t:on_friend_action t:on_friend_message t:send_action t:send_message """ self.bob_add_alice_as_friend() #: Test message MSG = 'Hi, Bob!' BID = self.bid def on_friend_message(self, fid, message): assert fid == BID assert message == MSG self.fm = True AliceTox.on_friend_message = on_friend_message self.ensure_exec(self.bob.send_message, (self.aid, MSG)) self.alice.fm = False assert self.wait_callback(self.alice, 'fm') AliceTox.on_friend_message = Tox.on_friend_message #: Test action ACTION = 'Kick' BID = self.bid def on_friend_action(self, fid, action): assert fid == BID assert action == ACTION self.fa = True AliceTox.on_friend_action = on_friend_action self.ensure_exec(self.bob.send_action, (self.aid, ACTION)) self.alice.fa = False assert self.wait_callback(self.alice, 'fa') AliceTox.on_friend_action = Tox.on_friend_action #: Test delete friend self.alice.del_friend(self.bid) self.loop(10) assert not self.alice.friend_exists(self.bid) def test_meta_status(self): """ t:on_read_receipt t:on_typing_change t:set_user_is_typing t:get_is_typing t:get_last_online """ self.bob_add_alice_as_friend() AID = self.aid #: Test typing status def on_typing_change(self, fid, is_typing): assert fid == AID assert is_typing is True assert self.get_is_typing(fid) is True self.ut = True BobTox.on_typing_change = on_typing_change self.bob.ut = False self.alice.set_user_is_typing(self.bid, True) assert self.wait_callback(self.bob, 'ut') BobTox.on_typing_change = Tox.on_typing_change #: Test last online assert self.alice.get_last_online(self.bid) is not None assert self.bob.get_last_online(self.aid) is not None @unittest.skip("groupchat is under major refactor in toxcore") def test_group(self): """ t:add_groupchat t:count_chatlist t:del_groupchat t:get_chatlist t:group_action_send t:group_get_names t:group_message_send t:group_number_peers t:group_peername t:invite_friend t:join_groupchat t:on_group_action t:on_group_invite t:on_group_message t:on_group_namelist_change """ self.bob_add_alice_as_friend() #: Test group add group_id = self.bob.add_groupchat() assert group_id >= 0 self.loop(50) BID = self.bid def on_group_invite(self, fid, data): assert fid == BID self.join_groupchat(fid, data) self.gi = True AliceTox.on_group_invite = on_group_invite def on_group_namelist_change(self, gid, peer_number, change): assert gid == group_id assert change == Tox.CHAT_CHANGE_PEER_ADD self.gn = True AliceTox.on_group_namelist_change = on_group_namelist_change self.alice.gi = False self.alice.gn = False self.ensure_exec(self.bob.invite_friend, (self.aid, group_id)) assert self.wait_callbacks(self.alice, ['gi', 'gn']) AliceTox.on_group_invite = Tox.on_group_invite AliceTox.on_group_namelist_change = Tox.on_group_namelist_change #: Test group number of peers self.loop(50) assert self.bob.group_number_peers(group_id) == 2 #: Test group peername self.alice.set_name('Alice') self.bob.set_name('Bob') def on_group_namelist_change(self, gid, peer_number, change): if change == Tox.CHAT_CHANGE_PEER_NAME: self.gn = True AliceTox.on_group_namelist_change = on_group_namelist_change self.alice.gn = False assert self.wait_callback(self.alice, 'gn') AliceTox.on_group_namelist_change = Tox.on_group_namelist_change peernames = [self.bob.group_peername(group_id, i) for i in range(self.bob.group_number_peers(group_id))] assert 'Alice' in peernames assert 'Bob' in peernames assert sorted(self.bob.group_get_names(group_id)) == ['Alice', 'Bob'] #: Test group message AID = self.aid BID = self.bid MSG = 'Group message test' def on_group_message(self, gid, fgid, message): if fgid == AID: assert gid == group_id assert message == MSG self.gm = True AliceTox.on_group_message = on_group_message self.alice.gm = False self.ensure_exec(self.bob.group_message_send, (group_id, MSG)) assert self.wait_callback(self.alice, 'gm') AliceTox.on_group_message = Tox.on_group_message #: Test group action AID = self.aid BID = self.bid MSG = 'Group action test' def on_group_action(self, gid, fgid, action): if fgid == AID: assert gid == group_id assert action == MSG self.ga = True AliceTox.on_group_action = on_group_action self.alice.ga = False self.ensure_exec(self.bob.group_action_send, (group_id, MSG)) assert self.wait_callback(self.alice, 'ga') AliceTox.on_group_action = Tox.on_group_action #: Test chatlist assert len(self.bob.get_chatlist()) == self.bob.count_chatlist() assert len(self.alice.get_chatlist()) == self.bob.count_chatlist() assert self.bob.count_chatlist() == 1 self.bob.del_groupchat(group_id) assert self.bob.count_chatlist() == 0 def test_file_transfer(self): """ t:file_data_remaining t:file_data_size t:file_send_control t:file_send_data t:new_file_sender t:on_file_control t:on_file_data t:on_file_send_request """ self.bob_add_alice_as_friend() FILE = os.urandom(1024 * 1024) FILE_NAME = "test.bin" FILE_SIZE = len(FILE) m = hashlib.md5() m.update(FILE) FILE_DIGEST = m.hexdigest() BID = self.bid CONTEXT = {'FILE': bytes(), 'RECEIVED': 0, 'START': False, 'SENT': 0} def on_file_send_request(self, fid, filenumber, size, filename): assert fid == BID assert size == FILE_SIZE assert filename == FILE_NAME self.file_send_control(fid, 1, filenumber, Tox.FILECONTROL_ACCEPT) def on_file_control(self, fid, receive_send, file_number, ct, data): assert fid == BID if receive_send == 0 and ct == Tox.FILECONTROL_FINISHED: assert CONTEXT['RECEIVED'] == FILE_SIZE m = hashlib.md5() m.update(CONTEXT['FILE']) assert m.hexdigest() == FILE_DIGEST self.completed = True def on_file_data(self, fid, file_number, data): assert fid == BID CONTEXT['FILE'] += data CONTEXT['RECEIVED'] += len(data) if CONTEXT['RECEIVED'] < FILE_SIZE: assert self.file_data_remaining( fid, file_number, 1) == FILE_SIZE - CONTEXT['RECEIVED'] AliceTox.on_file_send_request = on_file_send_request AliceTox.on_file_control = on_file_control AliceTox.on_file_data = on_file_data def on_file_control2(self, fid, receive_send, file_number, ct, data): if receive_send == 1 and ct == Tox.FILECONTROL_ACCEPT: CONTEXT['START'] = True BobTox.on_file_control = on_file_control2 self.alice.completed = False BLK = self.bob.file_data_size(self.aid) FN = self.bob.new_file_sender(self.aid, FILE_SIZE, FILE_NAME) while not self.alice.completed: if CONTEXT['START']: try: while True: if CONTEXT['SENT'] == FILE_SIZE: self.bob.file_send_control( self.aid, 0, FN, Tox.FILECONTROL_FINISHED ) CONTEXT['START'] = False break else: ed = CONTEXT['SENT'] + BLK if ed > FILE_SIZE: ed = FILE_SIZE self.bob.file_send_data( self.aid, FN, FILE[CONTEXT['SENT']:ed] ) CONTEXT['SENT'] = ed except: pass self.alice.do() self.bob.do() sleep(0.02) AliceTox.on_file_send_request = Tox.on_file_send_request AliceTox.on_file_control = Tox.on_file_control AliceTox.on_file_data = Tox.on_file_data BobTox.on_file_control = Tox.on_file_control
class ToxTest(unittest.TestCase): def setUp(self): opt = ToxOptions() self.alice = AliceTox(opt) self.bob = BobTox(opt) self.loop_until_connected() def tearDown(self): """ t:kill """ self.alice.kill() self.bob.kill() def loop(self, n): """ t:iterate t:iteration_interval """ interval = self.bob.iteration_interval() for i in range(n): self.alice.iterate() self.bob.iterate() sleep(interval / 2000.0) def loop_until_connected(self): """ t:on_self_connection_status t:self_get_connection_status """ def on_self_connection_status(self, status): if status != Tox.CONNECTION_NONE: self.mycon_status = True else: self.mycon_status = False assert self.self_get_connection_status() == status self.alice.mycon_status = False self.bob.mycon_status = False AliceTox.on_self_connection_status = on_self_connection_status BobTox.on_self_connection_status = on_self_connection_status while not self.alice.mycon_status or not self.bob.mycon_status: self.loop(50) AliceTox.on_self_connection_status = Tox.on_self_connection_status BobTox.on_self_connection_status = Tox.on_self_connection_status def wait_callback(self, obj, attr): count = 0 THRESHOLD = 200 while not getattr(obj, attr): self.loop(50) if count >= THRESHOLD: return False count += 1 return True def wait_callbacks(self, obj, attrs): count = 0 THRESHOLD = 400 while not all([getattr(obj, attr) for attr in attrs]): self.loop(50) if count >= THRESHOLD: return False count += 1 return True def ensure_exec(self, method, args): count = 0 THRESHOLD = 200 while True: try: ret = method(*args) break except Exception as ex: self.loop(50) assert count < THRESHOLD count += 1 return ret def bob_add_alice_as_friend(self): """ t:friend_add t:friend_add_norequest t:on_friend_request t:friend_by_public_key """ MSG = 'Hi, this is Bob.' bob_addr = self.bob.self_get_address() def on_friend_request(self, pk, message): assert pk == bob_addr[:CLIENT_ID_SIZE] assert message == MSG self.friend_add_norequest(pk) self.friend_added = True AliceTox.on_friend_request = on_friend_request alice_addr = self.alice.self_get_address() self.alice.friend_added = False self.bob.friend_add(alice_addr, MSG) assert self.wait_callback(self.alice, 'friend_added') AliceTox.on_friend_request = Tox.on_friend_request self.bid = self.alice.friend_by_public_key(bob_addr) self.aid = self.bob.friend_by_public_key(alice_addr) #: Wait until both are online def on_friend_connection_status(self, friend_id, status): assert status is True self.friend_conn_status = True def on_friend_status(self, friend_id, new_status): self.friend_status = True AliceTox.on_friend_connection_status = on_friend_connection_status BobTox.on_friend_connection_status = on_friend_connection_status AliceTox.on_friend_status = on_friend_status BobTox.on_friend_status = on_friend_status self.alice.friend_conn_status = False self.bob.friend_conn_status = False self.alice.friend_status = False self.bob.friend_status = False assert self.wait_callbacks(self.alice, ['friend_conn_status', 'friend_status']) assert self.wait_callbacks(self.bob, ['friend_conn_status', 'friend_status']) AliceTox.on_friend_connection_status = Tox.on_friend_connection_status BobTox.on_friend_connection_status = Tox.on_friend_connection_status AliceTox.on_friend_status = Tox.on_friend_status BobTox.on_friend_status = Tox.on_friend_status def test_bootstrap(self): """ t:bootstrap """ assert self.alice.self_get_connection_status() != Tox.CONNECTION_NONE assert self.bob.self_get_connection_status() != Tox.CONNECTION_NONE def test_address(self): """ t:self_get_address t:self_get_nospam t:self_set_nospam t:self_get_keys """ assert len(self.alice.self_get_address()) == ADDR_SIZE assert len(self.bob.self_get_address()) == ADDR_SIZE self.alice.self_set_nospam(0x12345678) assert self.alice.self_get_nospam() == 0x12345678 pk, sk = self.alice.self_get_keys() assert pk == self.alice.self_get_address()[:CLIENT_ID_SIZE] def test_self_name(self): """ t:self_set_name t:self_get_name t:self_get_name_size """ self.alice.self_set_name('Alice') self.loop(10) assert self.alice.self_get_name() == 'Alice' assert self.alice.self_get_name_size() == len('Alice') def test_status_message(self): """ t:self_set_status_message t:self_get_status_message t:self_get_status_message_size t:friend_set_status_message t:friend_get_status_message t:friend_get_status_message_size t:on_friend_status_message """ self.bob_add_alice_as_friend() MSG = 'Happy' AID = self.aid def on_friend_status_message(self, friend_id, new_message): assert friend_id == AID assert new_message == MSG self.sm = True BobTox.on_friend_status_message = on_friend_status_message self.bob.sm = False self.alice.self_set_status_message(MSG) assert self.wait_callback(self.bob, 'sm') BobTox.on_friend_status_message = Tox.on_friend_status_message assert self.alice.self_get_status_message() == MSG assert self.alice.self_get_status_message_size() == len(MSG) assert self.bob.friend_get_status_message(self.aid) == MSG assert self.bob.friend_get_status_message_size(self.aid) == len(MSG) def test_user_status(self): """ t:self_get_status t:self_set_status t:friend_get_status t:friend_get_status t:on_friend_status """ self.bob_add_alice_as_friend() AID = self.aid def on_friend_status(self, friend_id, new_status): assert friend_id == AID assert new_status == Tox.USER_STATUS_BUSY self.friend_status = True self.alice.self_set_status(Tox.USER_STATUS_BUSY) BobTox.on_friend_status = on_friend_status self.bob.friend_status = False assert self.wait_callback(self.bob, 'friend_status') BobTox.on_friend_status = Tox.on_friend_status assert self.alice.self_get_status() == Tox.USER_STATUS_BUSY assert self.bob.friend_get_status(self.aid) == Tox.USER_STATUS_BUSY def test_connection_status(self): """ t:friend_get_connection_status t:on_friend_connection_status """ self.bob_add_alice_as_friend() AID = self.aid def on_friend_connection_status(self, friend_id, status): assert friend_id == AID assert status is False self.friend_conn_status = True opt = ToxOptions() BobTox.on_friend_connection_status = on_friend_connection_status self.bob.friend_conn_status = False self.alice.kill() self.alice = Tox(opt) assert self.wait_callback(self.bob, 'friend_conn_status') BobTox.on_friend_connection_status = Tox.on_friend_connection_status assert self.bob.friend_get_connection_status(self.aid) is False def test_tox(self): """ t:get_savedata_size t:get_savedata """ assert self.alice.get_savedata_size() > 0 data = self.alice.get_savedata() assert data is not None addr = self.alice.self_get_address() self.alice.kill() opt = ToxOptions() opt.savedata_data = data opt.savedata_length = len(data) self.alice = Tox(opt) assert addr == self.alice.self_get_address() def test_friend(self): """ t:friend_delete t:friend_exists t:friend_get_public_key t:self_get_friend_list t:self_get_friend_list_size t:self_set_name t:friend_get_name t:friend_get_name_size t:on_friend_name """ #: Test friend request self.bob_add_alice_as_friend() assert self.alice.friend_exists(self.bid) assert self.bob.friend_exists(self.aid) #: Test friend exists assert not self.alice.friend_exists(self.bid + 1) assert not self.bob.friend_exists(self.aid + 1) #: Test friend_get_public_key assert self.alice.friend_get_public_key(self.bid) == \ self.bob.self_get_address()[:CLIENT_ID_SIZE] assert self.bob.friend_get_public_key(self.aid) == \ self.alice.self_get_address()[:CLIENT_ID_SIZE] #: Test self_get_friend_list assert self.alice.self_get_friend_list() == [self.bid] assert self.bob.self_get_friend_list() == [self.aid] assert self.alice.self_get_friend_list_size() == 1 assert self.bob.self_get_friend_list_size() == 1 #: Test friend name NEWNAME = 'Jenny' AID = self.aid def on_friend_name(self, fid, newname): assert fid == AID assert newname == NEWNAME self.nc = True BobTox.on_friend_name = on_friend_name self.bob.nc = False self.alice.self_set_name(NEWNAME) assert self.wait_callback(self.bob, 'nc') assert self.bob.friend_get_name(self.aid) == NEWNAME assert self.bob.friend_get_name_size(self.aid) == len(NEWNAME) BobTox.on_friend_name = Tox.on_friend_name def test_friend_message_and_action(self): """ t:on_friend_action t:on_friend_message t:friend_send_message """ self.bob_add_alice_as_friend() #: Test message MSG = 'Hi, Bob!' BID = self.bid def on_friend_message(self, fid, msg_type, message): assert fid == BID assert message == MSG self.fm = True AliceTox.on_friend_message = on_friend_message self.ensure_exec(self.bob.friend_send_message, (self.aid, Tox.MESSAGE_TYPE_NORMAL, MSG)) self.alice.fm = False assert self.wait_callback(self.alice, 'fm') AliceTox.on_friend_message = Tox.on_friend_message #: Test action ACTION = 'Kick' BID = self.bid def on_friend_action(self, fid, msg_type, action): assert fid == BID assert action == ACTION self.fa = True AliceTox.on_friend_message = on_friend_action self.ensure_exec(self.bob.friend_send_message, (self.aid, Tox.MESSAGE_TYPE_ACTION, ACTION)) self.alice.fa = False assert self.wait_callback(self.alice, 'fa') AliceTox.on_friend_message = Tox.on_friend_message #: Test delete friend self.alice.friend_delete(self.bid) self.loop(10) assert not self.alice.friend_exists(self.bid) def test_meta_status(self): """ t:on_friend_read_receipt t:on_friend_typing t:self_set_typing t:friend_get_typing t:friend_get_last_online """ self.bob_add_alice_as_friend() AID = self.aid #: Test typing status def on_friend_typing(self, fid, is_typing): assert fid == AID assert is_typing is True assert self.friend_get_typing(fid) is True self.friend_typing = True BobTox.on_friend_typing = on_friend_typing self.bob.friend_typing = False self.alice.self_set_typing(self.bid, True) assert self.wait_callback(self.bob, 'friend_typing') BobTox.on_friend_typing = Tox.on_friend_typing #: Test last online assert self.alice.friend_get_last_online(self.bid) is not None assert self.bob.friend_get_last_online(self.aid) is not None def test_group(self): """ t:add_groupchat t:count_chatlist t:del_groupchat t:get_chatlist t:group_action_send t:group_get_names t:group_get_title t:group_get_type t:group_message_send t:group_number_peers t:group_peername t:group_set_title t:invite_friend t:join_groupchat t:on_group_action t:on_group_invite t:on_group_message t:on_group_namelist_change """ self.bob_add_alice_as_friend() #: Test group add group_id = self.bob.add_groupchat() assert group_id >= 0 self.loop(50) BID = self.bid def on_group_invite(self, fid, type_, data): assert fid == BID assert type_ == 0 gn = self.join_groupchat(fid, data) assert type_ == self.group_get_type(gn) self.gi = True AliceTox.on_group_invite = on_group_invite def on_group_namelist_change(self, gid, peer_number, change): assert gid == group_id assert change == Tox.CHAT_CHANGE_PEER_ADD self.gn = True AliceTox.on_group_namelist_change = on_group_namelist_change self.alice.gi = False self.alice.gn = False self.ensure_exec(self.bob.invite_friend, (self.aid, group_id)) assert self.wait_callbacks(self.alice, ['gi', 'gn']) AliceTox.on_group_invite = Tox.on_group_invite AliceTox.on_group_namelist_change = Tox.on_group_namelist_change #: Test group number of peers self.loop(50) assert self.bob.group_number_peers(group_id) == 2 #: Test group peername self.alice.self_set_name('Alice') self.bob.self_set_name('Bob') def on_group_namelist_change(self, gid, peer_number, change): if change == Tox.CHAT_CHANGE_PEER_NAME: self.gn = True AliceTox.on_group_namelist_change = on_group_namelist_change self.alice.gn = False assert self.wait_callback(self.alice, 'gn') AliceTox.on_group_namelist_change = Tox.on_group_namelist_change peernames = [self.bob.group_peername(group_id, i) for i in range(self.bob.group_number_peers(group_id))] assert 'Alice' in peernames assert 'Bob' in peernames assert sorted(self.bob.group_get_names(group_id)) == ['Alice', 'Bob'] #: Test title change self.bob.group_set_title(group_id, 'My special title') assert self.bob.group_get_title(group_id) == 'My special title' #: Test group message AID = self.aid BID = self.bid MSG = 'Group message test' def on_group_message(self, gid, fgid, message): if fgid == AID: assert gid == group_id assert message == MSG self.gm = True AliceTox.on_group_message = on_group_message self.alice.gm = False self.ensure_exec(self.bob.group_message_send, (group_id, MSG)) assert self.wait_callback(self.alice, 'gm') AliceTox.on_group_message = Tox.on_group_message #: Test group action AID = self.aid BID = self.bid MSG = 'Group action test' def on_group_action(self, gid, fgid, action): if fgid == AID: assert gid == group_id assert action == MSG self.ga = True AliceTox.on_group_action = on_group_action self.alice.ga = False self.ensure_exec(self.bob.group_action_send, (group_id, MSG)) assert self.wait_callback(self.alice, 'ga') AliceTox.on_group_action = Tox.on_group_action #: Test chatlist assert len(self.bob.get_chatlist()) == self.bob.count_chatlist() assert len(self.alice.get_chatlist()) == self.bob.count_chatlist() assert self.bob.count_chatlist() == 1 self.bob.del_groupchat(group_id) assert self.bob.count_chatlist() == 0 def test_file_transfer(self): """ t:file_send t:file_send_chunk t:file_control t:file_seek t:on_file_recv t:on_file_recv_control t:on_file_recv_chunk t:on_file_chunk_request """ self.bob_add_alice_as_friend() FILE = os.urandom(1024 * 1024) FILE_NAME = "test.bin" FILE_SIZE = len(FILE) OFFSET = 567 m = hashlib.md5() m.update(FILE[OFFSET:]) FILE_DIGEST = m.hexdigest() BID = self.bid CONTEXT = {'FILE': bytes(), 'RECEIVED': 0, 'START': False, 'SENT': 0} self.alice.completed = False self.bob.completed = False def on_file_recv(self, fid, filenumber, kind, size, filename): assert fid == BID assert size == FILE_SIZE assert filename == FILE_NAME retv = self.file_seek(fid, filenumber, OFFSET) assert retv is True self.file_control(fid, filenumber, Tox.FILE_CONTROL_RESUME) def on_file_recv_control(self, fid, file_number, control): assert fid == BID # if receive_send == 0 and ct == Tox.FILE_CONTROL_FINISHED: # assert CONTEXT['RECEIVED'] == FILE_SIZE # m = hashlib.md5() # m.update(CONTEXT['FILE']) # assert m.hexdigest() == FILE_DIGEST # self.completed = True def on_file_recv_chunk(self, fid, file_number, position, data): assert fid == BID if data is None: assert CONTEXT['RECEIVED'] == (FILE_SIZE - OFFSET) m = hashlib.md5() m.update(CONTEXT['FILE']) assert m.hexdigest() == FILE_DIGEST self.completed = True self.file_control(fid, file_number, Tox.FILE_CONTROL_CANCEL) return CONTEXT['FILE'] += data CONTEXT['RECEIVED'] += len(data) # if CONTEXT['RECEIVED'] < FILE_SIZE: # assert self.file_data_remaining( # fid, file_number, 1) == FILE_SIZE - CONTEXT['RECEIVED'] # AliceTox.on_file_send_request = on_file_send_request # AliceTox.on_file_control = on_file_control # AliceTox.on_file_data = on_file_data AliceTox.on_file_recv = on_file_recv AliceTox.on_file_recv_control = on_file_recv_control AliceTox.on_file_recv_chunk = on_file_recv_chunk def on_file_recv_control2(self, fid, file_number, control): if control == Tox.FILE_CONTROL_RESUME: CONTEXT['START'] = True elif control == Tox.FILE_CONTROL_CANCEL: self.completed = True pass def on_file_chunk_request(self, fid, file_number, position, length): if length == 0: return data = FILE[position:(position + length)] self.file_send_chunk(fid, file_number, position, data) BobTox.on_file_recv_control = on_file_recv_control2 BobTox.on_file_chunk_request = on_file_chunk_request FN = self.bob.file_send(self.aid, 0, FILE_SIZE, FILE_NAME, FILE_NAME) while not self.alice.completed and not self.bob.completed: self.alice.iterate() self.bob.iterate() sleep(0.02) AliceTox.on_file_recv = Tox.on_file_recv AliceTox.on_file_recv_control = Tox.on_file_recv_control AliceTox.on_file_recv_chunk = Tox.on_file_recv_chunk BobTox.on_file_recv_control = Tox.on_file_recv_control BobTox.on_file_chunk_request = Tox.on_file_chunk_request
def setUp(self): opt = ToxOptions() self.alice = AliceTox(opt) self.bob = BobTox(opt) self.loop_until_connected()
def tox_kill(self): Tox.kill(self)
class ToxTest(unittest.TestCase): def setUp(self): """ t:bootstrap t:self_get_dht_id t:self_get_udp_port """ opt = ToxOptions() self.alice = AliceTox(opt) self.bob = BobTox(opt) self.bob.bootstrap("localhost", self.alice.self_get_udp_port(), self.alice.self_get_dht_id()) self.loop_until_connected() def tearDown(self): """ t:kill """ self.alice.kill() self.bob.kill() def loop(self, n): """ t:iterate t:iteration_interval """ interval = self.bob.iteration_interval() for _ in range(n): self.alice.iterate() self.bob.iterate() sleep(interval / 2000.0) def loop_until_connected(self): """ t:on_self_connection_status t:self_get_connection_status """ def on_self_connection_status(self, status): self.mycon_status = True if status != Tox.CONNECTION_NONE else False assert self.self_get_connection_status() == status self.alice.mycon_status = False self.bob.mycon_status = False AliceTox.on_self_connection_status = on_self_connection_status BobTox.on_self_connection_status = on_self_connection_status while not self.alice.mycon_status or not self.bob.mycon_status: self.loop(50) AliceTox.on_self_connection_status = Tox.on_self_connection_status BobTox.on_self_connection_status = Tox.on_self_connection_status def wait_callback(self, obj, attr): count = 0 THRESHOLD = 200 while not getattr(obj, attr): self.loop(50) if count >= THRESHOLD: return False count += 1 return True def wait_callbacks(self, obj, attrs): count = 0 THRESHOLD = 400 while not all(getattr(obj, attr) for attr in attrs): self.loop(50) if count >= THRESHOLD: return False count += 1 return True def ensure_exec(self, method, args): count = 0 THRESHOLD = 200 while True: try: ret = method(*args) break except Exception as ex: self.loop(50) assert count < THRESHOLD count += 1 return ret def bob_add_alice_as_friend(self): """ t:friend_add t:friend_add_norequest t:on_friend_request t:friend_by_public_key """ MSG = "Hi, this is Bob." bob_addr = self.bob.self_get_address() def on_friend_request(self, pk, message): assert pk == bob_addr[:CLIENT_ID_SIZE] assert message == MSG self.friend_add_norequest(pk) self.friend_added = True AliceTox.on_friend_request = on_friend_request alice_addr = self.alice.self_get_address() self.alice.friend_added = False self.bob.friend_add(alice_addr, MSG) assert self.wait_callback(self.alice, "friend_added") AliceTox.on_friend_request = Tox.on_friend_request self.bid = self.alice.friend_by_public_key(bob_addr) self.aid = self.bob.friend_by_public_key(alice_addr) #: Wait until both are online def on_friend_connection_status(self, friend_id, status): assert status is True self.friend_conn_status = True def on_friend_status(self, friend_id, new_status): self.friend_status = True AliceTox.on_friend_connection_status = on_friend_connection_status BobTox.on_friend_connection_status = on_friend_connection_status AliceTox.on_friend_status = on_friend_status BobTox.on_friend_status = on_friend_status self.alice.friend_conn_status = False self.bob.friend_conn_status = False self.alice.friend_status = False self.bob.friend_status = False assert self.wait_callbacks(self.alice, ["friend_conn_status", "friend_status"]) assert self.wait_callbacks(self.bob, ["friend_conn_status", "friend_status"]) AliceTox.on_friend_connection_status = Tox.on_friend_connection_status BobTox.on_friend_connection_status = Tox.on_friend_connection_status AliceTox.on_friend_status = Tox.on_friend_status BobTox.on_friend_status = Tox.on_friend_status def test_self_get_connection_status(self): """ t:self_get_connection_status """ assert self.alice.self_get_connection_status() != Tox.CONNECTION_NONE assert self.bob.self_get_connection_status() != Tox.CONNECTION_NONE def test_address(self): """ t:self_get_address t:self_get_nospam t:self_set_nospam t:self_get_keys """ assert len(self.alice.self_get_address()) == ADDR_SIZE assert len(self.bob.self_get_address()) == ADDR_SIZE self.alice.self_set_nospam(0x12345678) assert self.alice.self_get_nospam() == 0x12345678 pk, sk = self.alice.self_get_keys() assert pk == self.alice.self_get_address()[:CLIENT_ID_SIZE] def test_self_name(self): """ t:self_set_name t:self_get_name t:self_get_name_size """ self.alice.self_set_name("Alice") self.loop(10) assert self.alice.self_get_name() == "Alice" assert self.alice.self_get_name_size() == len("Alice") def test_status_message(self): """ t:self_set_status_message t:self_get_status_message t:self_get_status_message_size t:friend_set_status_message t:friend_get_status_message t:friend_get_status_message_size t:on_friend_status_message """ self.bob_add_alice_as_friend() MSG = "Happy" AID = self.aid def on_friend_status_message(self, friend_id, new_message): assert friend_id == AID assert new_message == MSG self.sm = True BobTox.on_friend_status_message = on_friend_status_message self.bob.sm = False self.alice.self_set_status_message(MSG) assert self.wait_callback(self.bob, "sm") BobTox.on_friend_status_message = Tox.on_friend_status_message assert self.alice.self_get_status_message() == MSG assert self.alice.self_get_status_message_size() == len(MSG) assert self.bob.friend_get_status_message(self.aid) == MSG assert self.bob.friend_get_status_message_size(self.aid) == len(MSG) def test_user_status(self): """ t:self_get_status t:self_set_status t:friend_get_status t:friend_get_status t:on_friend_status """ self.bob_add_alice_as_friend() AID = self.aid def on_friend_status(self, friend_id, new_status): assert friend_id == AID assert new_status == Tox.USER_STATUS_BUSY self.friend_status = True self.alice.self_set_status(Tox.USER_STATUS_BUSY) BobTox.on_friend_status = on_friend_status self.bob.friend_status = False assert self.wait_callback(self.bob, "friend_status") BobTox.on_friend_status = Tox.on_friend_status assert self.alice.self_get_status() == Tox.USER_STATUS_BUSY assert self.bob.friend_get_status(self.aid) == Tox.USER_STATUS_BUSY def test_connection_status(self): """ t:friend_get_connection_status t:on_friend_connection_status """ self.bob_add_alice_as_friend() AID = self.aid def on_friend_connection_status(self, friend_id, status): assert friend_id == AID assert status is False self.friend_conn_status = True opt = ToxOptions() BobTox.on_friend_connection_status = on_friend_connection_status self.bob.friend_conn_status = False self.alice.kill() self.alice = Tox(opt) assert self.wait_callback(self.bob, "friend_conn_status") BobTox.on_friend_connection_status = Tox.on_friend_connection_status assert self.bob.friend_get_connection_status(self.aid) is False def test_tox(self): """ t:get_savedata_size t:get_savedata """ assert self.alice.get_savedata_size() > 0 data = self.alice.get_savedata() assert data is not None addr = self.alice.self_get_address() self.alice.kill() opt = ToxOptions() opt.savedata_data = data opt.savedata_length = len(data) self.alice = Tox(opt) assert addr == self.alice.self_get_address() def test_friend(self): """ t:friend_delete t:friend_exists t:friend_get_public_key t:self_get_friend_list t:self_get_friend_list_size t:self_set_name t:friend_get_name t:friend_get_name_size t:on_friend_name """ #: Test friend request self.bob_add_alice_as_friend() assert self.alice.friend_exists(self.bid) assert self.bob.friend_exists(self.aid) #: Test friend exists assert not self.alice.friend_exists(self.bid + 1) assert not self.bob.friend_exists(self.aid + 1) #: Test friend_get_public_key assert (self.alice.friend_get_public_key( self.bid) == self.bob.self_get_address()[:CLIENT_ID_SIZE]) assert (self.bob.friend_get_public_key( self.aid) == self.alice.self_get_address()[:CLIENT_ID_SIZE]) #: Test self_get_friend_list assert self.alice.self_get_friend_list() == [self.bid] assert self.bob.self_get_friend_list() == [self.aid] assert self.alice.self_get_friend_list_size() == 1 assert self.bob.self_get_friend_list_size() == 1 #: Test friend name NEWNAME = "Jenny" AID = self.aid def on_friend_name(self, fid, newname): assert fid == AID assert newname == NEWNAME self.nc = True BobTox.on_friend_name = on_friend_name self.bob.nc = False self.alice.self_set_name(NEWNAME) assert self.wait_callback(self.bob, "nc") assert self.bob.friend_get_name(self.aid) == NEWNAME assert self.bob.friend_get_name_size(self.aid) == len(NEWNAME) BobTox.on_friend_name = Tox.on_friend_name def test_friend_message_and_action(self): """ t:on_friend_action t:on_friend_message t:friend_send_message """ self.bob_add_alice_as_friend() #: Test message MSG = "Hi, Bob!" BID = self.bid def on_friend_message(self, fid, msg_type, message): assert fid == BID assert msg_type == Tox.MESSAGE_TYPE_NORMAL assert message == MSG self.fm = True AliceTox.on_friend_message = on_friend_message self.ensure_exec(self.bob.friend_send_message, (self.aid, Tox.MESSAGE_TYPE_NORMAL, MSG)) self.alice.fm = False assert self.wait_callback(self.alice, "fm") AliceTox.on_friend_message = Tox.on_friend_message #: Test action ACTION = "Kick" BID = self.bid def on_friend_action(self, fid, msg_type, action): assert fid == BID assert msg_type == Tox.MESSAGE_TYPE_ACTION assert action == ACTION self.fa = True AliceTox.on_friend_message = on_friend_action self.ensure_exec(self.bob.friend_send_message, (self.aid, Tox.MESSAGE_TYPE_ACTION, ACTION)) self.alice.fa = False assert self.wait_callback(self.alice, "fa") AliceTox.on_friend_message = Tox.on_friend_message #: Test delete friend self.alice.friend_delete(self.bid) self.loop(10) assert not self.alice.friend_exists(self.bid) def test_meta_status(self): """ t:on_friend_read_receipt t:on_friend_typing t:self_set_typing t:friend_get_typing t:friend_get_last_online """ self.bob_add_alice_as_friend() AID = self.aid #: Test typing status def on_friend_typing(self, fid, is_typing): assert fid == AID assert is_typing is True assert self.friend_get_typing(fid) is True self.friend_typing = True BobTox.on_friend_typing = on_friend_typing self.bob.friend_typing = False self.alice.self_set_typing(self.bid, True) assert self.wait_callback(self.bob, "friend_typing") BobTox.on_friend_typing = Tox.on_friend_typing #: Test last online assert self.alice.friend_get_last_online(self.bid) is not None assert self.bob.friend_get_last_online(self.aid) is not None def test_conference(self): """ t:conference_new t:conference_delete t:conference_get_chatlist_size t:conference_get_chatlist t:conference_send_message t:conference_get_id t:conference_get_title t:conference_get_type t:conference_send_message t:conference_peer_count t:conference_peer_get_name t:conference_set_title t:conference_invite t:conference_join t:on_conference_invite t:on_conference_message t:on_conference_peer_name t:on_conference_peer_list_changed """ self.bob_add_alice_as_friend() #: Test group add group_id = self.bob.conference_new() assert group_id >= 0 self.loop(50) BID = self.bid def on_conference_invite(self, fid, type_, data): assert fid == BID assert type_ == 0 gn = self.conference_join(fid, data) assert type_ == self.conference_get_type(gn) self.gi = True AliceTox.on_conference_invite = on_conference_invite def on_conference_peer_list_changed(self, gid): assert gid == group_id self.gn = True AliceTox.on_conference_peer_list_changed = on_conference_peer_list_changed self.alice.gi = False self.alice.gn = False self.ensure_exec(self.bob.conference_invite, (self.aid, group_id)) assert self.wait_callbacks(self.alice, ["gi", "gn"]) AliceTox.on_conference_invite = Tox.on_conference_invite AliceTox.on_conference_peer_list_changed = Tox.on_conference_peer_list_changed #: Test group number of peers self.loop(50) assert self.bob.conference_peer_count(group_id) == 2 #: Test group peername self.alice.self_set_name("Alice") self.bob.self_set_name("Bob") def on_conference_peer_name(self, gid, peer_number, name): self.gn = True AliceTox.on_conference_peer_name = on_conference_peer_name self.alice.gn = False assert self.wait_callback(self.alice, "gn") AliceTox.on_conference_peer_name = Tox.on_conference_peer_name peernames = [ self.bob.conference_peer_get_name(group_id, i) for i in range(self.bob.conference_peer_count(group_id)) ] assert "Alice" in peernames assert "Bob" in peernames #: Test title change self.bob.conference_set_title(group_id, "My special title") assert self.bob.conference_get_title(group_id) == "My special title" #: Test conference ID getter (32 * 2 characters). assert len(self.bob.conference_get_id(group_id)) == 64 # Invalid conference id: has_error = False try: self.bob.conference_get_id(1234) except OperationFailedError: has_error = True assert has_error # Invalid type for conference id: has_error = False try: self.bob.conference_get_id("1234") except OperationFailedError: has_error = True assert has_error #: Test group message AID = self.aid BID = self.bid MSG = "Group message test" def on_conference_message(self, gid, fgid, msg_type, message): if fgid == AID: assert gid == group_id assert message == MSG self.gm = True AliceTox.on_conference_message = on_conference_message self.alice.gm = False self.ensure_exec(self.bob.conference_send_message, (group_id, Tox.MESSAGE_TYPE_NORMAL, MSG)) assert self.wait_callback(self.alice, "gm") AliceTox.on_conference_message = Tox.on_conference_message #: Test group action AID = self.aid BID = self.bid MSG = "Group action test" def on_conference_action(self, gid, fgid, msg_type, action): if fgid == AID: assert gid == group_id assert msg_type == Tox.MESSAGE_TYPE_ACTION assert action == MSG self.ga = True AliceTox.on_conference_message = on_conference_action self.alice.ga = False self.ensure_exec(self.bob.conference_send_message, (group_id, Tox.MESSAGE_TYPE_ACTION, MSG)) assert self.wait_callback(self.alice, "ga") AliceTox.on_conference_message = Tox.on_conference_message #: Test chatlist assert (len(self.bob.conference_get_chatlist()) == self.bob.conference_get_chatlist_size()) assert (len(self.alice.conference_get_chatlist()) == self.bob.conference_get_chatlist_size()) assert self.bob.conference_get_chatlist_size() == 1 self.bob.conference_delete(group_id) assert self.bob.conference_get_chatlist_size() == 0 def test_file_transfer(self): """ t:file_send t:file_send_chunk t:file_control t:file_seek t:file_get_file_id t:on_file_recv t:on_file_recv_control t:on_file_recv_chunk t:on_file_chunk_request """ self.bob_add_alice_as_friend() FILE = os.urandom(1024 * 1024) FILE_NAME = "test.bin" FILE_SIZE = len(FILE) OFFSET = 567 m = hashlib.md5() m.update(FILE[OFFSET:]) FILE_DIGEST = m.hexdigest() BID = self.bid CONTEXT = {"FILE": bytes(), "RECEIVED": 0, "START": False, "SENT": 0} self.alice.completed = False self.bob.completed = False def on_file_recv(self, fid, filenumber, kind, size, filename): assert fid == BID assert size == FILE_SIZE assert filename == FILE_NAME retv = self.file_seek(fid, filenumber, OFFSET) assert retv is True self.file_control(fid, filenumber, Tox.FILE_CONTROL_RESUME) def on_file_recv_control(self, fid, file_number, control): assert fid == BID # if receive_send == 0 and ct == Tox.FILE_CONTROL_FINISHED: # assert CONTEXT['RECEIVED'] == FILE_SIZE # m = hashlib.md5() # m.update(CONTEXT['FILE']) # assert m.hexdigest() == FILE_DIGEST # self.completed = True def on_file_recv_chunk(self, fid, file_number, position, data): assert fid == BID if data is None: assert CONTEXT["RECEIVED"] == (FILE_SIZE - OFFSET) m = hashlib.md5() m.update(CONTEXT["FILE"]) assert m.hexdigest() == FILE_DIGEST self.completed = True self.file_control(fid, file_number, Tox.FILE_CONTROL_CANCEL) return CONTEXT["FILE"] += data CONTEXT["RECEIVED"] += len(data) # if CONTEXT['RECEIVED'] < FILE_SIZE: # assert self.file_data_remaining( # fid, file_number, 1) == FILE_SIZE - CONTEXT['RECEIVED'] # AliceTox.on_file_send_request = on_file_send_request # AliceTox.on_file_control = on_file_control # AliceTox.on_file_data = on_file_data AliceTox.on_file_recv = on_file_recv AliceTox.on_file_recv_control = on_file_recv_control AliceTox.on_file_recv_chunk = on_file_recv_chunk def on_file_recv_control2(self, fid, file_number, control): if control == Tox.FILE_CONTROL_RESUME: CONTEXT["START"] = True elif control == Tox.FILE_CONTROL_CANCEL: self.completed = True def on_file_chunk_request(self, fid, file_number, position, length): if length == 0: return data = FILE[position:(position + length)] self.file_send_chunk(fid, file_number, position, data) BobTox.on_file_recv_control = on_file_recv_control2 BobTox.on_file_chunk_request = on_file_chunk_request FN = self.bob.file_send(self.aid, 0, FILE_SIZE, FILE_NAME, FILE_NAME) FID = self.bob.file_get_file_id(self.aid, FN) hexFID = "".join([hex(ord(c))[2:].zfill(2) for c in FILE_NAME]) assert FID.startswith(hexFID.upper()) while not self.alice.completed and not self.bob.completed: self.alice.iterate() self.bob.iterate() sleep(0.02) AliceTox.on_file_recv = Tox.on_file_recv AliceTox.on_file_recv_control = Tox.on_file_recv_control AliceTox.on_file_recv_chunk = Tox.on_file_recv_chunk BobTox.on_file_recv_control = Tox.on_file_recv_control BobTox.on_file_chunk_request = Tox.on_file_chunk_request