def test_frame_endpoint_tcp_adapter_basic(tloop): """ Test basic tcp interaction using the TCPFrameEndpoint interface. """ # List of results: res = [] addr, port = 'localhost', 8767 @asyncio.coroutine def server_handler(reader, writer): """Echo server""" tfe = TCPFrameEndpoint(reader, writer) # Read a frame: frame = yield from tfe.recv() # Send the frame back to client: yield from tfe.send(frame) @asyncio.coroutine def client(): CLIENT_MESS = b'This is a mess' reader, writer = yield from \ asyncio.open_connection(host=addr,port=port) tfe = TCPFrameEndpoint(reader, writer) yield from tfe.send(CLIENT_MESS) frame = yield from tfe.recv() assert frame == CLIENT_MESS # Append True to list of results: res.append(True) # Close client: yield from tfe.close() # Start server: start_server = asyncio.start_server(server_handler, host=addr, port=port, reuse_address=True) server_task = run_timeout(start_server, tloop) # Start client: run_timeout(client(), tloop) # Close server: server_task.close() # Wait until server is closed: run_timeout(server_task.wait_closed(), loop=tloop) assert res == [True]
def test_recv_invalid_msg(): """ Test receival of invalid message. """ my_loop = asyncio.new_event_loop() asyncio.set_event_loop(None) ser = Serializer(MyProtoDef) class BadFrameEndpoint: @asyncio.coroutine def send(self,data_frame:bytes): """Send a frame""" return @asyncio.coroutine def recv(self) -> bytes: """Receive a frame""" return b'Invalid Message data' @asyncio.coroutine def close(self): """Close the connection""" return @asyncio.coroutine def my_cor(): frame_endpoint = BadFrameEndpoint() mff = MsgFromFrame(ser,frame_endpoint) # We expect to get None (Which means the connection is considered to be # close) if the message is invalid. assert (yield from mff.recv()) is None run_timeout(my_cor(),loop=my_loop)
def test_recv_invalid_msg(): """ Test receival of invalid message. """ my_loop = asyncio.new_event_loop() asyncio.set_event_loop(None) ser = Serializer(MyProtoDef) class BadFrameEndpoint: @asyncio.coroutine def send(self, data_frame: bytes): """Send a frame""" return @asyncio.coroutine def recv(self) -> bytes: """Receive a frame""" return b'Invalid Message data' @asyncio.coroutine def close(self): """Close the connection""" return @asyncio.coroutine def my_cor(): frame_endpoint = BadFrameEndpoint() mff = MsgFromFrame(ser, frame_endpoint) # We expect to get None (Which means the connection is considered to be # close) if the message is invalid. assert (yield from mff.recv()) is None run_timeout(my_cor(), loop=my_loop)
def test_msg_from_frame_passing(): """ Test passing messages using msg_from_frame over a frame_endpoint. """ my_loop = asyncio.new_event_loop() asyncio.set_event_loop(None) # Build a serializer: ser = Serializer(MyProtoDef) # Messages from player 1 to player 2 q12 = asyncio.Queue(loop=my_loop) # Messages from player 2 to player 1 q21 = asyncio.Queue(loop=my_loop) # mff1 = MsgFromFrame(msg_mapper,q21.get,q12.put) mff1 = MsgFromFrame(ser,MockFrameEndpoint(q21.get,q12.put)) # mff2 = MsgFromFrame(msg_mapper,q12.get,q21.put) mff2 = MsgFromFrame(ser,MockFrameEndpoint(q12.get,q21.put)) # A future that marks the end of transaction # between player1 and player2: transac_fin = asyncio.Future(loop=my_loop) @asyncio.coroutine def player1(): # Send mess1 to player 2: mess1 = mff1.serializer.get_msg('Mess1') mess1.set_field('a_int',1) mess1.set_field('b_str','hello') yield from mff1.send(mess1) # Expect to receive mess2 from player 2: mess2 = yield from mff1.recv() assert mess2.msg_name == 'Mess2' assert mess2.get_field('c_int') == 2 # Send mess3 to player 1: mess1 = mff1.serializer.get_msg('Mess1') mess1.set_field('a_int',8) mess1.set_field('b_str','The string') yield from mff1.send(mess1) @asyncio.coroutine def player2(): # Expect to receive mess1 from player 1: mess1 = yield from mff2.recv() assert mess1.msg_name == 'Mess1' assert mess1.get_field('a_int') == 1 assert mess1.get_field('b_str') == 'hello' # Send mess2 to player 1: mess2 = mff2.serializer.get_msg('Mess2') mess2.set_field('c_int',2) yield from mff2.send(mess2) # Expect to receive mess1 from player 1: mess1 = yield from mff2.recv() assert mess1.msg_name == 'Mess1' assert mess1.get_field('a_int') == 8 assert mess1.get_field('b_str') == 'The string' transac_fin.set_result(True) asyncio.async(player1(),loop=my_loop) asyncio.async(player2(),loop=my_loop) run_timeout(transac_fin,loop=my_loop)
def test_tcp_adapter_frame_struct(tloop): """ Test send/recv of length prefixed frames over TCP with the TCPFrameEndpoint. """ # List of results: res = [] addr, port = 'localhost', 8767 @asyncio.coroutine def server_handler(reader, writer): """Echo server""" tfe = TCPFrameEndpoint(reader, writer) # Read a frame: frame = yield from tfe.recv() assert frame == b'abc' # Read a frame: frame = yield from tfe.recv() assert frame == b'' # Read a frame: frame = yield from tfe.recv() assert frame == b'abcd' # Read a frame: frame = yield from tfe.recv() assert frame == b'abcd' res.append('sending_frame') # Write a frame: yield from tfe.send(b'1234') # Last frame was cut in the middle (The connection was closed), # therefore we expect to get a None here: frame = yield from tfe.recv() assert frame is None res.append('got_none') @asyncio.coroutine def client(): reader, writer = yield from \ asyncio.open_connection(host=addr,port=port) # Write b'abc': writer.write(b'\x03\x00\x00\x00abc') yield from writer.drain() # Write empty frame: writer.write(b'\x00\x00\x00\x00') yield from writer.drain() # Write b'abcd': writer.write(b'\x04\x00\x00\x00abcd') yield from writer.drain() # Write b'abcd' in two parts: writer.write(b'\x04\x00\x00') yield from writer.drain() writer.write(b'\x00abcd') yield from writer.drain() # Read a frame from the server: len_prefix = yield from reader.readexactly(4) msg_len = struct.unpack('I', len_prefix)[0] frame = yield from reader.readexactly(msg_len) assert frame == b'1234' # Send half a frame: writer.write(b'\x00\x00\x00') yield from writer.drain() # Append True to list of results: res.append('client_close') # Close client: writer.close() # Start server: start_server = asyncio.start_server(server_handler, host=addr, port=port, reuse_address=True) server_task = run_timeout(start_server, tloop) # Start client: run_timeout(client(), tloop) # Close server: server_task.close() # Wait until server is closed: run_timeout(server_task.wait_closed(), loop=tloop) assert res == ['sending_frame', 'client_close', 'got_none']
def test_tcp_adapter_max_frame_len(tloop): """ Test send/recv of length prefixed frames over TCP with the TCPFrameEndpoint. """ # List of results: res = [] addr, port = 'localhost', 8767 @asyncio.coroutine def server_handler(reader, writer): """Echo server""" tfe = TCPFrameEndpoint(reader, writer, max_frame_len=4) # Read a frame: frame = yield from tfe.recv() assert frame == b'abc' # Read a frame: frame = yield from tfe.recv() assert frame == b'' # Read a frame. The frame should be too large for the chosen # max_frame_len=4, so we expect to get None here: frame = yield from tfe.recv() assert frame == None res.append('got_none') @asyncio.coroutine def client(): reader, writer = yield from \ asyncio.open_connection(host=addr,port=port) # Write b'abc': writer.write(b'\x03\x00\x00\x00abc') yield from writer.drain() # Write empty frame: writer.write(b'\x00\x00\x00\x00') yield from writer.drain() res.append('send_large_frame') # Write b'abcdef', which is too large for our chosen max_frame_len=4: writer.write(b'\x06\x00\x00\x00abcdef') yield from writer.drain() # We expect the server to disconnect us: with pytest.raises(asyncio.IncompleteReadError): yield from reader.readexactly(4) res.append('got_disconnected') # Close client: writer.close() # Start server: start_server = asyncio.start_server(server_handler, host=addr, port=port, reuse_address=True) server_task = run_timeout(start_server, tloop) # Start client: run_timeout(client(), tloop) # Close server: server_task.close() # Wait until server is closed: run_timeout(server_task.wait_closed(), loop=tloop) assert res == ['send_large_frame', 'got_none', 'got_disconnected']
def test_msg_from_frame_passing(): """ Test passing messages using msg_from_frame over a frame_endpoint. """ my_loop = asyncio.new_event_loop() asyncio.set_event_loop(None) # Build a serializer: ser = Serializer(MyProtoDef) # Messages from player 1 to player 2 q12 = asyncio.Queue(loop=my_loop) # Messages from player 2 to player 1 q21 = asyncio.Queue(loop=my_loop) # mff1 = MsgFromFrame(msg_mapper,q21.get,q12.put) mff1 = MsgFromFrame(ser, MockFrameEndpoint(q21.get, q12.put)) # mff2 = MsgFromFrame(msg_mapper,q12.get,q21.put) mff2 = MsgFromFrame(ser, MockFrameEndpoint(q12.get, q21.put)) # A future that marks the end of transaction # between player1 and player2: transac_fin = asyncio.Future(loop=my_loop) @asyncio.coroutine def player1(): # Send mess1 to player 2: mess1 = mff1.serializer.get_msg('Mess1') mess1.set_field('a_int', 1) mess1.set_field('b_str', 'hello') yield from mff1.send(mess1) # Expect to receive mess2 from player 2: mess2 = yield from mff1.recv() assert mess2.msg_name == 'Mess2' assert mess2.get_field('c_int') == 2 # Send mess3 to player 1: mess1 = mff1.serializer.get_msg('Mess1') mess1.set_field('a_int', 8) mess1.set_field('b_str', 'The string') yield from mff1.send(mess1) @asyncio.coroutine def player2(): # Expect to receive mess1 from player 1: mess1 = yield from mff2.recv() assert mess1.msg_name == 'Mess1' assert mess1.get_field('a_int') == 1 assert mess1.get_field('b_str') == 'hello' # Send mess2 to player 1: mess2 = mff2.serializer.get_msg('Mess2') mess2.set_field('c_int', 2) yield from mff2.send(mess2) # Expect to receive mess1 from player 1: mess1 = yield from mff2.recv() assert mess1.msg_name == 'Mess1' assert mess1.get_field('a_int') == 8 assert mess1.get_field('b_str') == 'The string' transac_fin.set_result(True) asyncio. async (player1(), loop=my_loop) asyncio. async (player2(), loop=my_loop) run_timeout(transac_fin, loop=my_loop)
def test_basic_catalog1_logic(tmpdir): my_loop = asyncio.new_event_loop() asyncio.set_event_loop(None) # Messages from player 1 to player 2 q12 = asyncio.Queue(loop=my_loop) # Messages from player 2 to player 1 q21 = asyncio.Queue(loop=my_loop) mff1 = MsgFromFrame(cser_serializer, MockFrameEndpoint(q21.get, q12.put)) mff2 = MsgFromFrame(client_ser, MockFrameEndpoint(q12.get, q21.put)) # A future that marks the end of transaction # between player1 and player2: transac_fin = asyncio.Future(loop=my_loop) sl = FCatalogServerLogic(tmpdir, NUM_HASHES, mff1) server_task1 = asyncio. async (sl.client_handler(), loop=my_loop) @asyncio.coroutine def client_cor1(): msg_inst = client_ser.get_msg('ChooseDB') msg_inst.set_field('db_name', 'my_db') yield from mff2.send(msg_inst) msg_inst = client_ser.get_msg('RequestSimilars') msg_inst.set_field('func_data', b'function data example') msg_inst.set_field('num_similars', 0) yield from mff2.send(msg_inst) msg_inst = yield from mff2.recv() assert msg_inst.msg_name == 'ResponseSimilars' assert msg_inst.get_field('similars') == [] # Add three functions: msg_inst = client_ser.get_msg('AddFunction') msg_inst.set_field('func_name', 'name1') msg_inst.set_field('func_comment', 'comment1') msg_inst.set_field('func_data', b'This is the function1 data') yield from mff2.send(msg_inst) msg_inst = client_ser.get_msg('AddFunction') msg_inst.set_field('func_name', 'name2') msg_inst.set_field('func_comment', 'comment2') msg_inst.set_field('func_data', b'This is the function2 data') yield from mff2.send(msg_inst) msg_inst = client_ser.get_msg('AddFunction') msg_inst.set_field('func_name', 'name3') msg_inst.set_field('func_comment', 'comment3') msg_inst.set_field('func_data', b'02938459238459283458932452345') yield from mff2.send(msg_inst) # Request similars: msg_inst = client_ser.get_msg('RequestSimilars') msg_inst.set_field('func_data', b'This is the function2 data') msg_inst.set_field('num_similars', 3) yield from mff2.send(msg_inst) msg_inst = yield from mff2.recv() assert msg_inst.msg_name == 'ResponseSimilars' sims = msg_inst.get_field('similars') assert len(sims) == 2 assert sims[0].name == 'name2' assert sims[0].comment == 'comment2' assert sims[0].sim_grade == NUM_HASHES assert sims[1].name == 'name1' assert sims[1].comment == 'comment1' assert sims[1].sim_grade < NUM_HASHES # Close the connection with the server: yield from mff2.close() # Wait for the server coroutine to finish: yield from asyncio.wait_for(server_task1, timeout=None, loop=my_loop) # Mark as finished: transac_fin.set_result(True) asyncio. async (client_cor1(), loop=my_loop) run_timeout(transac_fin, loop=my_loop, timeout=3.0) # We check persistance by logging in with another user: # Messages from player 1 to player 2 q12 = asyncio.Queue(loop=my_loop) # Messages from player 2 to player 1 q21 = asyncio.Queue(loop=my_loop) mff1 = MsgFromFrame(cser_serializer, MockFrameEndpoint(q21.get, q12.put)) mff2 = MsgFromFrame(client_ser, MockFrameEndpoint(q12.get, q21.put)) # A future that marks the end of transaction # between player1 and player2: sl = FCatalogServerLogic(tmpdir, NUM_HASHES, mff1) transac_fin = asyncio.Future(loop=my_loop) server_task2 = asyncio. async (sl.client_handler(), loop=my_loop) @asyncio.coroutine def client_cor2(): # Choose a database: msg_inst = client_ser.get_msg('ChooseDB') msg_inst.set_field('db_name', 'my_db') yield from mff2.send(msg_inst) # Request similars: msg_inst = client_ser.get_msg('RequestSimilars') msg_inst.set_field('func_data', b'This is the function2 data') msg_inst.set_field('num_similars', 3) yield from mff2.send(msg_inst) msg_inst = yield from mff2.recv() assert msg_inst.msg_name == 'ResponseSimilars' sims = msg_inst.get_field('similars') assert len(sims) == 2 assert sims[0].name == 'name2' assert sims[0].comment == 'comment2' assert sims[0].sim_grade == NUM_HASHES assert sims[1].name == 'name1' assert sims[1].comment == 'comment1' assert sims[1].sim_grade < NUM_HASHES # Close the connection with the server: yield from mff2.close() # Wait for the server coroutine to finish: yield from asyncio.wait_for(server_task2, timeout=None, loop=my_loop) # Mark as finished: transac_fin.set_result(True) asyncio. async (client_cor2(), loop=my_loop) run_timeout(transac_fin, loop=my_loop, timeout=3.0)
def test_basic_catalog1_logic(tmpdir): my_loop = asyncio.new_event_loop() asyncio.set_event_loop(None) # Messages from player 1 to player 2 q12 = asyncio.Queue(loop=my_loop) # Messages from player 2 to player 1 q21 = asyncio.Queue(loop=my_loop) mff1 = MsgFromFrame(cser_serializer,MockFrameEndpoint(q21.get,q12.put)) mff2 = MsgFromFrame(client_ser,MockFrameEndpoint(q12.get,q21.put)) # A future that marks the end of transaction # between player1 and player2: transac_fin = asyncio.Future(loop=my_loop) sl = FCatalogServerLogic(tmpdir,NUM_HASHES,mff1) server_task1 = asyncio.async(sl.client_handler(),loop=my_loop) @asyncio.coroutine def client_cor1(): msg_inst = client_ser.get_msg('ChooseDB') msg_inst.set_field('db_name','my_db') yield from mff2.send(msg_inst) msg_inst = client_ser.get_msg('RequestSimilars') msg_inst.set_field('func_data',b'function data example') msg_inst.set_field('num_similars',0) yield from mff2.send(msg_inst) msg_inst = yield from mff2.recv() assert msg_inst.msg_name == 'ResponseSimilars' assert msg_inst.get_field('similars') == [] # Add three functions: msg_inst = client_ser.get_msg('AddFunction') msg_inst.set_field('func_name','name1') msg_inst.set_field('func_comment','comment1') msg_inst.set_field('func_data',b'This is the function1 data') yield from mff2.send(msg_inst) msg_inst = client_ser.get_msg('AddFunction') msg_inst.set_field('func_name','name2') msg_inst.set_field('func_comment','comment2') msg_inst.set_field('func_data',b'This is the function2 data') yield from mff2.send(msg_inst) msg_inst = client_ser.get_msg('AddFunction') msg_inst.set_field('func_name','name3') msg_inst.set_field('func_comment','comment3') msg_inst.set_field('func_data',b'02938459238459283458932452345') yield from mff2.send(msg_inst) # Request similars: msg_inst = client_ser.get_msg('RequestSimilars') msg_inst.set_field('func_data',b'This is the function2 data') msg_inst.set_field('num_similars',3) yield from mff2.send(msg_inst) msg_inst = yield from mff2.recv() assert msg_inst.msg_name == 'ResponseSimilars' sims = msg_inst.get_field('similars') assert len(sims) == 2 assert sims[0].name == 'name2' assert sims[0].comment == 'comment2' assert sims[0].sim_grade == NUM_HASHES assert sims[1].name == 'name1' assert sims[1].comment == 'comment1' assert sims[1].sim_grade < NUM_HASHES # Close the connection with the server: yield from mff2.close() # Wait for the server coroutine to finish: yield from asyncio.wait_for(server_task1,timeout=None,loop=my_loop) # Mark as finished: transac_fin.set_result(True) asyncio.async(client_cor1(),loop=my_loop) run_timeout(transac_fin,loop=my_loop,timeout=3.0) # We check persistance by logging in with another user: # Messages from player 1 to player 2 q12 = asyncio.Queue(loop=my_loop) # Messages from player 2 to player 1 q21 = asyncio.Queue(loop=my_loop) mff1 = MsgFromFrame(cser_serializer,MockFrameEndpoint(q21.get,q12.put)) mff2 = MsgFromFrame(client_ser,MockFrameEndpoint(q12.get,q21.put)) # A future that marks the end of transaction # between player1 and player2: sl = FCatalogServerLogic(tmpdir,NUM_HASHES,mff1) transac_fin = asyncio.Future(loop=my_loop) server_task2 = asyncio.async(sl.client_handler(),loop=my_loop) @asyncio.coroutine def client_cor2(): # Choose a database: msg_inst = client_ser.get_msg('ChooseDB') msg_inst.set_field('db_name','my_db') yield from mff2.send(msg_inst) # Request similars: msg_inst = client_ser.get_msg('RequestSimilars') msg_inst.set_field('func_data',b'This is the function2 data') msg_inst.set_field('num_similars',3) yield from mff2.send(msg_inst) msg_inst = yield from mff2.recv() assert msg_inst.msg_name == 'ResponseSimilars' sims = msg_inst.get_field('similars') assert len(sims) == 2 assert sims[0].name == 'name2' assert sims[0].comment == 'comment2' assert sims[0].sim_grade == NUM_HASHES assert sims[1].name == 'name1' assert sims[1].comment == 'comment1' assert sims[1].sim_grade < NUM_HASHES # Close the connection with the server: yield from mff2.close() # Wait for the server coroutine to finish: yield from asyncio.wait_for(server_task2,timeout=None,loop=my_loop) # Mark as finished: transac_fin.set_result(True) asyncio.async(client_cor2(),loop=my_loop) run_timeout(transac_fin,loop=my_loop,timeout=3.0)