def test_sending_messages(self): """ SocketLayer receives a message from higher layer so it sends it """ self.socket_layer.start_server("127.0.0.1", 8080) sender = Peer(33, "33.22.11.22", 9992, False) sender2 = Peer(21, "23.45.67.86", 9393, False) receiver = Peer(11, '127.0.0.1', 8080, False) mess = putils.create_ping_message(sender, receiver) mess2 = putils.create_ping_message(sender2, receiver) address = putils.get_receiver_address(mess) address2 = putils.get_receiver_address(mess2) _run(self.higher[0].put((mess.SerializeToString(), address))) _run(self.higher[0].put((mess2.SerializeToString(), address2))) # Get the message msg = _run(self.higher[1].get()) msg2 = _run(self.higher[1].get()) log.warning("Stop the server") status = _run(self.socket_layer.stop_server()) self.assertIs(status, StatusMessage.SUCCESS) self.assertEqual(msg, mess.SerializeToString()) self.assertEqual(msg2, mess2.SerializeToString())
def setUpClass(cls): cls.socket_layer = SocketLayer() q1 = asyncio.Queue() q2 = asyncio.Queue() cls.higher = (q1, q2) _run(cls.socket_layer.add_layer_communication(higher=cls.higher)) cls.sender = Peer(123, '123.123.123.123', 8022, True) cls.receiver = Peer(11, '66.22.66.22', 9090, False)
def test_passing_message(self): """ P2P layer got some message from higher layer. It passes it on to the lower layer using queue. """ sender = Peer(123, '123.123.123.123', 8022, True) receiver = Peer(11, '66.22.66.22', 9090, False) mess = putils.create_ping_message(sender, receiver) _run(self.higher[0].put(mess)) # wait a while for message to propagate through the layer _run(asyncio.sleep(0.1)) self.assertEqual(_run(self.lower[1].get()), mess)
def setUpClass(cls): sl = SocketLayer() cls.ml = MessageLayer(sl) q1 = asyncio.Queue() q2 = asyncio.Queue() q3 = asyncio.Queue() q4 = asyncio.Queue() cls.higher = (q1, q2) cls.lower = (q3, q4) _run(cls.ml.add_layer_communication(higher=cls.higher, lower=cls.lower)) cls.sender = Peer(123, '123.123.123.123', 8022, True) cls.receiver = Peer(11, '66.22.66.22', 9090, False)
def test_that_server_receives_messages(self): """ We tell SocketLayer to start the server. It should start it in another thread and listen for incoming connections at given socket. We test that by sending some message to the server and if everything works it should handle it and put it into the queue. """ self.socket_layer.start_server("127.0.0.1", 8080) log.debug("Create socket") sock = socket.socket() sock2 = socket.socket() try: sock.connect(("127.0.0.1", 8080)) sock2.connect(("127.0.0.1", 8080)) except socket.error as msg: log.warning("Could not connect to the server") return mess = putils.create_ping_message(self.sender, self.receiver) sender2 = Peer(555, '1.123.1.123', 333, True) receiver2 = Peer(5434, '64.88.66.22', 444, True) mess2 = putils.create_ping_message(sender2, receiver2) serialized = putils.serialize_message(mess) framed = self.socket_layer._frame_message(serialized) serialized2 = putils.serialize_message(mess2) framed2 = self.socket_layer._frame_message(serialized2) try: log.debug("Try to send the messages") sock.send(framed) log.debug("Try to send next messages") sock2.send(framed2) except socket.error as msg: log.warning("Could not send the message: {}".format(msg)) sock.close() sock2.close() return sock.close() sock2.close() #Get the message msg = _run(self.higher[1].get()) msg2 = _run(self.higher[1].get()) log.warning("Stop the server") status = _run(self.socket_layer.stop_server()) self.assertIs(status, StatusMessage.SUCCESS) # And now we check if the message is correct self.assertIn(serialized, [msg, msg2]) self.assertIn(serialized2, [msg, msg2])
def test_sending_command(self): peer = Peer(5343, "127.33.21.21", 3233, False) _run(self.business_layer.lower_layer._routing_table.insert(peer)) status = _run( self.business_layer.command(target_id=5343, command="ls -l", should_respond=False)) self.assertIs(status, StatusMessage.SUCCESS) message = _run(self.lower[1].get()) self.assertIsInstance(message, Message) self.assertEqual(message.type, Message.COMMAND) find_node_message = putils.create_command_message( sender=self.business_layer.get_myself(), receiver=peer, command="ls -l", should_respond=False) find_node_message.uuid = message.uuid self.assertEqual(message, find_node_message) status = _run( self.business_layer.command(target_id=266, command="dir .", should_respond=False)) self.assertIs(status, StatusMessage.FAILURE)
async def join_network(self, bootstrap_node): """ Join network that the bootstrap_node belongs to :param bootstrap_node: Bootstrap node we will be asking for information about network :return: SUCCESS or FAILURE """ sever_status = await self.start_server() if sever_status is StatusMessage.FAILURE: print("Cancel network joining, could not start the server") return sever_status if bootstrap_node: log.debug("Joining network, bootstrap node: {}".format(bootstrap_node)) peer_to_ask = Peer(None, bootstrap_node[0], bootstrap_node[1], False) await self.lower_layer.add_peer(peer_to_ask) await self.ping(peer_to_ask.id) log.debug("Waiting for boot node to respond") await asyncio.sleep(4) peer_to_ask = await self.lower_layer.get_peer_by_id(peer_to_ask.id) if peer_to_ask is None: log.warning("Bootstrap node is not responding. Failed to bootstrap") await self.stop_server() return StatusMessage.FAILURE message = putils.create_find_node_message(sender=self.get_myself(), receiver=peer_to_ask, guid=self.get_myself().id) status = await self._put_message_on_lower(message) if status is StatusMessage.FAILURE: log.warning("Could not send find node message to bootstrap node") await self.stop_server() return status return StatusMessage.SUCCESS
def test_responding_to_file_request_message_for_huge_file(self): print(file_util.get_file_size('./huge_file.txt')) another_peer = Peer(22, "127.33.21.22", 3233, False) message = putils.create_file_request_message( self.business_layer.get_myself(), receiver=another_peer, path='./huge_file.txt') _run(self.lower[0].put(message)) chunk1 = _run(self.lower[1].get()) chunk2 = _run(self.lower[1].get()) file_size = file_util.get_file_size('./huge_file.txt') binary_data1 = file_util.get_file_binary_data('./huge_file.txt', 8192) binary_data2 = file_util.get_file_binary_data('./huge_file.txt')[8192:] self.assertEqual( chunk1.fileChunk.fileName, './huge_file.txt' + '.{}'.format(self.business_layer.get_myself().id)) self.assertEqual(chunk1.fileChunk.fileSize, file_size) self.assertEqual(chunk1.fileChunk.ordinal, 0) self.assertEqual(chunk1.fileChunk.data, binary_data1) self.assertEqual( chunk2.fileChunk.fileName, './huge_file.txt' + '.{}'.format(self.business_layer.get_myself().id)) self.assertEqual(chunk2.fileChunk.fileSize, file_size) self.assertEqual(chunk2.fileChunk.ordinal, 1) self.assertEqual(chunk2.fileChunk.data, binary_data2) self.assertEqual(chunk1.fileChunk.uuid, chunk2.fileChunk.uuid)
def test_remove_peer(self): peer = Peer(1234, "23.32.45.22", 9033, False) _run(self.p2pl.add_peer(peer)) self.assertIs(peer, _run(self.p2pl.get_peer_by_id(1234))) _run(self.p2pl.remove_peer(peer)) self.assertIs(None, _run(self.p2pl.get_peer_by_id(1234)))
async def ping_all(self): null_peer = Peer(-1, "127.0.0.1", 22, False) message = putils.create_ping_message(sender=self.get_myself(), receiver=null_peer) try: status = await self._propagate_message(message) return status except asyncio.CancelledError: return StatusMessage.FAILURE
def __init__(self, lower_layer, address, port, id=None): self.lower_layer = lower_layer self.log = logging.getLogger(__name__) self._this_peer = Peer(id, address, port) self._routing_table = BucketList(bucket_size=5, buckets_number=64, id=self._this_peer.id)
def test_removal_of_peer_after_not_responding(self): peer = Peer(2, "127.33.21.22", 3233, False) _run(self.business_layer.lower_layer._routing_table.insert(peer)) status = _run(self.business_layer.ping(2)) self.assertIs(status, StatusMessage.SUCCESS) _run(asyncio.sleep(10)) peer = _run(self.business_layer.lower_layer.get_peer_by_id(2)) self.assertIs(peer, None)
def test_get_peer(self): peer = Peer(1, "127.33.21.22", 3233, False) _run(self.p2pl._routing_table.insert(peer)) peer = _run(self.p2pl.get_peer_by_id(1)) self.assertEqual(peer.id, 1) self.assertEqual(peer.ip, "127.33.21.22") self.assertEqual(peer.port, 3233) self.assertEqual(peer.is_NAT, False)
def test_creation_of_found_nodes_message(self): p1 = Peer(1, "123.32.33.22", 90, False) p2 = Peer(2, "11.22.33.22", 99, False) p3 = Peer(3, "34.23.42.33", 80, False) p4 = Peer(4, "23.44.23.21", 77, False) peers = [p1, p2, p3, p4] mess = putils.create_found_nodes_message(self.sender, self.receiver, peers) self.assertEqual(mess.type, Message.FOUND_NODES) self.assertEqual(len(mess.foundNodes.nodes), 4) self.assertEqual( putils.create_peer_from_contact(mess.foundNodes.nodes[0]), p1) self.assertEqual( putils.create_peer_from_contact(mess.foundNodes.nodes[1]), p2) self.assertEqual( putils.create_peer_from_contact(mess.foundNodes.nodes[2]), p3) self.assertEqual( putils.create_peer_from_contact(mess.foundNodes.nodes[3]), p4)
async def leave(self): null_peer = Peer(-1, "127.0.0.1", 22, False) message = putils.create_leave_message(sender=self.get_myself(), receiver=null_peer) try: log.debug("Propagating LEAVE message") status = await self._propagate_message(message) log.debug("LEAVE message propagated") return status except asyncio.CancelledError: return StatusMessage.FAILURE
def test_connecting_to_wrong_server(self): self.socket_layer.start_server("127.0.0.1", 8080) sender = Peer(33, "33.22.11.22", 9992, False) sender2 = Peer(21, "23.45.67.86", 9393, False) receiver = Peer(11, '127.0.0.1', 88, False) mess = putils.create_ping_message(sender, receiver) mess2 = putils.create_ping_message(sender2, receiver) address = putils.get_receiver_address(mess) address2 = putils.get_receiver_address(mess2) _run(self.higher[0].put((mess.SerializeToString(), address))) _run(self.higher[0].put((mess2.SerializeToString(), address2))) self.assertEqual(self.higher[1].qsize(), 0) # Get the message log.warning("Stop the server") status = _run(self.socket_layer.stop_server()) self.assertIs(status, StatusMessage.SUCCESS)
def test_that_responsive_peer_is_not_removed(self): peer = Peer(666, "127.33.21.22", 3233, False) _run(self.business_layer.lower_layer._routing_table.insert(peer)) status = _run(self.business_layer.ping(666)) self.assertIs(status, StatusMessage.SUCCESS) ping_respond_message = putils.create_ping_response_message( sender=peer, receiver=self.business_layer.get_myself()) _run(self.lower[0].put(ping_respond_message)) _run(asyncio.sleep(3.2)) peer_from_routing_table = _run( self.business_layer.lower_layer.get_peer_by_id(666)) self.assertEqual(peer, peer_from_routing_table)
def test_handling_found_nodes(self): p1 = Peer(1, "123.32.33.22", 90, False) p2 = Peer(2, "11.22.33.22", 99, False) p3 = Peer(3, "34.23.42.33", 80, False) p4 = Peer(4, "23.44.23.21", 77, False) peers = [p1, p2, p3, p4] sender = Peer(6, "1.1.1.1", 666, False) this_peer = self.business_layer.get_myself() message = putils.create_found_nodes_message(sender=sender, receiver=this_peer, nearest_peers=peers) _run(self.lower[0].put(message)) ping_respond_message1 = putils.create_ping_response_message( sender=p1, receiver=self.business_layer.get_myself()) ping_respond_message2 = putils.create_ping_response_message( sender=p2, receiver=self.business_layer.get_myself()) ping_respond_message3 = putils.create_ping_response_message( sender=p3, receiver=self.business_layer.get_myself()) ping_respond_message4 = putils.create_ping_response_message( sender=p4, receiver=self.business_layer.get_myself()) _run(self.lower[0].put(ping_respond_message1)) _run(self.lower[0].put(ping_respond_message2)) _run(self.lower[0].put(ping_respond_message3)) _run(self.lower[0].put(ping_respond_message4)) _run(asyncio.sleep(4)) inputed_p1 = _run(self.business_layer.lower_layer.get_peer_by_id(1)) inputed_p2 = _run(self.business_layer.lower_layer.get_peer_by_id(2)) inputed_p3 = _run(self.business_layer.lower_layer.get_peer_by_id(3)) inputed_p4 = _run(self.business_layer.lower_layer.get_peer_by_id(4)) self.assertEqual(p1, inputed_p1) self.assertEqual(p2, inputed_p2) self.assertEqual(p3, inputed_p3) self.assertEqual(p4, inputed_p4)
def test_responding_to_command(self): another_peer = Peer(5, "127.33.21.22", 3233, False) this_peer = self.business_layer.get_myself() message = putils.create_command_message(sender=another_peer, receiver=this_peer, command="dir", should_respond=True) _run(self.lower[0].put(message)) response_message = _run(self.lower[1].get()) with open('./dir.txt', 'r', encoding='utf-8', errors='ignore') as file: value = file.read() self.assertEqual(response_message.response.value, value) self.assertEqual(response_message.response.status, 0) self.assertEqual(response_message.response.command, 'dir')
def test_responding_to_ping(self): another_peer = Peer(5, "127.33.21.22", 3233, False) this_peer = self.business_layer.get_myself() message = putils.create_ping_message(sender=another_peer, receiver=this_peer) message2 = putils.create_ping_message(sender=another_peer, receiver=this_peer) message3 = putils.create_ping_message(sender=another_peer, receiver=this_peer) # Put three messages in queue _run(self.lower[0].put(message)) _run(self.lower[0].put(message2)) _run(self.lower[0].put(message3)) # Three response messages should be created and passed to the lower layer respond_message1 = _run(self.lower[1].get()) respond_message2 = _run(self.lower[1].get()) respond_message3 = _run(self.lower[1].get()) # Their uuid should be different self.assertNotEqual(respond_message1.uuid, respond_message2.uuid) self.assertNotEqual(respond_message2.uuid, respond_message3.uuid) self.assertNotEqual(respond_message1.uuid, respond_message3.uuid) # But after chaanging it to be the same for all three messages they should be the same respond_message2.uuid = respond_message1.uuid respond_message3.uuid = respond_message2.uuid self.assertEqual(respond_message1, respond_message2) self.assertEqual(respond_message1, respond_message3) self.assertEqual(respond_message3, respond_message2) inputed_peer = _run(self.business_layer.lower_layer.get_peer_by_id(5)) self.assertEqual(respond_message1.type, Message.PING_RESPONSE) self.assertEqual(int(respond_message1.receiver.guid), 5) self.assertEqual(respond_message1.receiver.IP, "127.33.21.22") self.assertEqual(respond_message1.receiver.port, 3233) self.assertEqual(respond_message1.receiver.isNAT, False) self.assertEqual(int(respond_message1.sender.guid), this_peer.id) self.assertEqual(respond_message1.sender.IP, this_peer.ip) self.assertEqual(respond_message1.sender.port, this_peer.port) self.assertEqual(respond_message1.sender.isNAT, this_peer.is_NAT) self.assertEqual(inputed_peer, another_peer)
def test_responding_to_file_request_message(self): another_peer = Peer(22, "127.33.21.22", 3233, False) message = putils.create_file_request_message( self.business_layer.get_myself(), receiver=another_peer, path='./test_file.txt') _run(self.lower[0].put(message)) response_message = _run(self.lower[1].get()) file_size = file_util.get_file_size('./test_file.txt') binary_data = file_util.get_file_binary_data('./test_file.txt') self.assertEqual( response_message.fileChunk.fileName, './test_file.txt' + '.{}'.format(self.business_layer.get_myself().id)) self.assertEqual(response_message.fileChunk.fileSize, file_size) self.assertEqual(response_message.fileChunk.ordinal, 0) self.assertEqual(response_message.fileChunk.data, binary_data)
def test_ping(self): """ Business layer creates ping message using protobuf_utils and passes it on to the lower layer """ peer = Peer(2, "127.33.21.22", 3233, False) _run(self.business_layer.lower_layer._routing_table.insert(peer)) status = _run(self.business_layer.ping(2)) self.assertIs(status, StatusMessage.SUCCESS) message = _run(self.lower[1].get()) self.assertIsInstance(message, Message) self.assertEqual(message.type, Message.PING) ping_message = putils.create_ping_message( self.business_layer.get_myself(), peer) ping_message.uuid = message.uuid self.assertEqual(message, ping_message) status = _run(self.business_layer.ping(266)) self.assertIs(status, StatusMessage.FAILURE)
def test_handling_file_chunks_message(self): print(file_util.get_file_size('./huge_file.txt')) another_peer = Peer(22, "127.33.21.22", 3233, False) message = putils.create_file_request_message( self.business_layer.get_myself(), receiver=another_peer, path='./huge_file.txt') _run(self.lower[0].put(message)) chunk1 = _run(self.lower[1].get()) chunk2 = _run(self.lower[1].get()) _run(self.lower[0].put(chunk1)) _run(self.lower[0].put(chunk2)) _run(asyncio.sleep(4)) true_binary_data = file_util.get_file_binary_data('./huge_file.txt') binary_data = file_util.get_file_binary_data( path='./huge.file.txt.{}'.format( self.business_layer.get_myself().id)) self.assertEqual(binary_data, true_binary_data)
def test_find_node(self): """ Business layer creates find node message using protobuf_utils and passes it on to the lower layer. """ peer = Peer(2, "127.33.21.22", 3233, False) _run(self.business_layer.lower_layer._routing_table.insert(peer)) status = _run(self.business_layer.find_node(2332, 2)) self.assertIs(status, StatusMessage.SUCCESS) message = _run(self.lower[1].get()) self.assertIsInstance(message, Message) self.assertEqual(message.type, Message.FIND_NODE) find_node_message = putils.create_find_node_message( sender=self.business_layer.get_myself(), receiver=peer, guid=2332) find_node_message.uuid = message.uuid self.assertEqual(message, find_node_message) status = _run( self.business_layer.find_node(guid=266, id_of_peer_to_ask=88)) self.assertIs(status, StatusMessage.FAILURE)
def setUp(self): self.sender = Peer(123, '123.123.123.123', 8022, True) self.receiver = Peer(11, '66.22.66.22', 9090, False)
def test_add_peer(self): peer = Peer(999, "83.34.65.32", 90, False) _run(self.p2pl.add_peer(peer)) self.assertIs(peer, _run(self.p2pl.get_peer_by_id(999)))