def test_dont_query_myself(self): logger.debug('test start') msg = message.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH_ZERO) expected = [ Query(msg, tc.NODES_LD_IH[159][0]), Query(msg, tc.NODES_LD_IH[158][1]), Query(msg, tc.NODES_LD_IH[157][3]), Query(msg, tc.NODES_LD_IH[155][4]), ] result = self.lookup.start() return for i, r, e in zip(range(len(result)), result, expected): eq_(r.msg.info_hash, e.msg.info_hash) eq_(r.dstnode, e.dstnode) #OUTDATED!!!!!!!!!!!!!!!!!!!!!!!!! # Ongoing queries to (sorted: oldest first): # 155-4, 157-3, # Queued nodes to query (sorted by log_distance to info_hash): # 158-1, 159-0 # Notice 159-2 is kicked out from the queue eq_(self.lookup.num_parallel_queries, 4) nodes = [Node(tc.CLIENT_ADDR, self.lookup._my_id)] self.lookup.on_response_received( *_gen_nodes_args(tc.NODES_LD_IH[157][3], nodes)) return eq_(self.lookup._get_announce_candidates(), [ tc.NODES_LD_IH[157][3], ]) # This response triggers a new query to 158-1 (ignoring myself) eq_(self.lookup.num_parallel_queries, 2) # Ongoing queries to (sorted: oldest first): # 155-4, 158-1 # Queued nodes to query (sorted by log_distance to info_hash): # 159-0 self.lookup.on_timeout(tc.NODES_LD_IH[155][4]) # This timeout triggers a new query (to 159-0) eq_(self.lookup.num_parallel_queries, 2) self.lookup.on_timeout(tc.NODES_LD_IH[158][1]) # No more nodes to send queries to eq_(self.lookup.num_parallel_queries, 1) ok_(not self.lookup.is_done) self.lookup.on_timeout(tc.NODES_LD_IH[159][0]) # No more nodes to send queries to eq_(self.lookup.num_parallel_queries, 0) ok_(self.lookup.is_done)
def test_ping_with_timeout(self): # Client creates a query ping_msg = message.OutgoingPingQuery(tc.CLIENT_ID) q = Query(ping_msg, tc.SERVER_NODE) timeout_task = minitwisted.Task(TIMEOUT_DELAY, None) # Client registers query bencoded_msg = self.querier.register_query(q, timeout_task) # Client sends bencoded_msg time.sleep(3) # The server never responds and the timeout is triggered stored_q = self.querier.on_timeout(tc.SERVER_ADDR) assert stored_q is q
def do_maintenance(self): self.maintenance_counter += 1 maintenance_delay = .0000001 if self.maintenance_counter == 1: # bootstrap ping msg = message.OutgoingPingQuery(self.my_node.id) queries_to_send = [Query(msg, tc.SERVER_NODE)] maintenance_lookup_target = None elif self.maintenance_counter == 2: queries_to_send = [] maintenance_lookup_target = tc.CLIENT_ID else: queries_to_send = [] maintenance_lookup_target = None return (maintenance_delay, queries_to_send, maintenance_lookup_target)
def test_error(self): # Client creates a query ping_msg = message.OutgoingPingQuery(tc.CLIENT_ID) q = Query(ping_msg, tc.SERVER_NODE) timeout_task = minitwisted.Task(TIMEOUT_DELAY, None) # Client registers query bencoded_msg = self.querier.register_query(q, timeout_task) # Client sends bencoded_msg time.sleep(1) # Server gets bencoded_msg and creates response ping_r_msg_out = message.OutgoingErrorMsg(message.GENERIC_E) bencoded_r = ping_r_msg_out.encode(tc.TID) # The client receives the bencoded message ping_r_in = message.IncomingMsg(bencoded_r, tc.SERVER_ADDR) stored_q = self.querier.on_error_received(ping_r_in, tc.SERVER_ADDR) assert stored_q is None
def test_ping_with_response(self): # Client creates a query ping_msg = message.OutgoingPingQuery(tc.CLIENT_ID) q = Query(ping_msg, tc.SERVER_NODE) # Querier.register_query sets a TID and timeout_task q.tid = tc.TID q.timeout_task = minitwisted.Task(TIMEOUT_DELAY, None) q.query_ts = time.time() # The query is sent time.sleep(1) # The server creates a response ping_r_msg_out = message.OutgoingPingResponse(tc.SERVER_ID) bencoded_r = ping_r_msg_out.encode(tc.TID) # The client receives the bencoded message ping_r_in = message.IncomingMsg(bencoded_r, tc.SERVER_ADDR) q.on_response_received(ping_r_in) assert 1 < q.rtt < 1.1 assert q.lookup_obj is None
def test_find_node_with_error(self): # Client creates a query fn_msg = message.OutgoingFindNodeQuery(tc.CLIENT_ID, tc.TARGET_ID) # the destination's ID is unknown q = Query(fn_msg, node.Node(tc.SERVER_ADDR)) # Querier.register_query sets a TID and timeout_task q.tid = tc.TID q.timeout_task = minitwisted.Task(TIMEOUT_DELAY, None) q.query_ts = time.time() # The query is sent # The server creates a response fn_r_out = message.OutgoingErrorMsg(message.GENERIC_E) bencoded_fn_r = fn_r_out.encode(tc.TID) time.sleep(1) # The client receives the bencoded message fn_r_in = message.IncomingMsg(bencoded_fn_r, tc.SERVER_ADDR) q.on_error_received(fn_r_in) assert 1 < q.rtt < 1.1 assert q.lookup_obj is None
def test_get_peers_with_response(self): # Client creates a query fn_msg = message.OutgoingGetPeersQuery(tc.CLIENT_ID, tc.INFO_HASH) # the destination's ID is unknown # This query belongs to a lookup q = Query(fn_msg, node.Node(tc.SERVER_ADDR), LOOKUP_OBJ) # Querier.register_query sets a TID and timeout_task q.tid = tc.TID q.timeout_task = minitwisted.Task(TIMEOUT_DELAY, None) q.query_ts = time.time() # The query is sent # The server creates a response fn_r_out = message.OutgoingGetPeersResponse(tc.SERVER_ID, nodes=tc.NODES) bencoded_fn_r = fn_r_out.encode(tc.TID) time.sleep(1) # The client receives the bencoded message fn_r_in = message.IncomingMsg(bencoded_fn_r, tc.SERVER_ADDR) q.on_response_received(fn_r_in) assert 1 < q.rtt < 1.1 assert q.lookup_obj is LOOKUP_OBJ
def test_complete(self): to_send = self.lookup.start() # The node won't query itself del self.bootstrap_nodes[2] expected = [Query(self.get_peers_msg, n) for n in self.bootstrap_nodes] for result, expected in zip(to_send, expected): eq_(result.msg, expected.msg) eq_(result.dstnode, expected.dstnode) eq_(self.lookup.num_parallel_queries, 4) # Node receives a response from a node node_ = tc.NODES_LD_IH[158][1] nodes = [tc.NODES_LD_IH[156][5]] msg = message.OutgoingGetPeersResponse(node_.id, 'token', nodes) msg = msg.encode('Z') msg = message.IncomingMsg(msg, node_.addr) #print 'nodes2', msg.nodes2 result = self.lookup.on_response_received(msg, node_) expected = [Query(self.get_peers_msg, nodes[0])] eq_(result[0].msg, expected[0].msg) eq_(result[0].dstnode, expected[0].dstnode) eq_(self.lookup.num_parallel_queries, 4) # Timeout eq_(self.lookup.on_timeout(tc.NODES_LD_IH[159][0]), []) eq_(self.lookup.num_parallel_queries, 3) return """Start sends two parallel queries to the closest bootstrap nodes (to the INFO_HASH) """ # Ongoing queries to (sorted: oldest first): # 155-4, 157-3, # Queued nodes to query (sorted by log_distance to info_hash): # 158-1, 159-0 # Notice 159-2 is kicked out from the queue logger.critical("") eq_(self.lookup.num_parallel_queries, 2) nodes = [ tc.NODES_LD_IH[157][5], tc.NODES_LD_IH[152][6], tc.NODES_LD_IH[158][7] ] self.lookup.on_response_received( *_gen_nodes_args(tc.NODES_LD_IH[157][3], nodes)) eq_(self.lookup._get_announce_candidates(), [ tc.NODES_LD_IH[157][3], ]) # This response triggers a new query (to 152-6) eq_(self.lookup.num_parallel_queries, 2) # Ongoing queries to (sorted: oldest first): # 155-4, 152-6 # Queued nodes to query (sorted by log_distance to info_hash): # 157-5, 158-1, 158-7, 159-0 self.lookup.on_timeout(tc.NODES_LD_IH[155][4]) eq_(self.lookup.num_parallel_queries, 2) # This timeout triggers a new query (to 157-5) eq_(self.lookup.num_parallel_queries, 2) # Ongoing queries to (sorted: oldest first): # 155-4, 157-5 # Queued nodes to query (sorted by log_distance to info_hash): # 158-1, 158-7, 159-0 self.lookup.on_timeout(tc.NODES_LD_IH[155][4]) # This timeout triggers a new query (to 158-1) eq_(self.lookup.num_parallel_queries, 2) # Ongoing queries to (sorted: oldest first): # 152-6, 158-1 # Queued nodes to query (sorted by log_distance to info_hash): # 158-7, 159-0 nodes = [tc.NODES_LD_IH[151][8], tc.NODES_LD_IH[150][9]] self.lookup.on_response( *_gen_nodes_args(tc.NODES_LD_IH[152][6], nodes)) eq_(self.lookup._get_announce_candidates(), [ tc.NODES_LD_IH[152][6], tc.NODES_LD_IH[157][3], ]) # This response triggers a new query (to 150-9) eq_(self.lookup.num_parallel_queries, 2) # Ongoing queries to (sorted: oldest first): # 157-5, 150-9 # Queued nodes to query (sorted by log_distance to info_hash): # 151-8, 158-7, 159-0 nodes = [ tc.NODES_LD_IH[151][10], tc.NODES_LD_IH[151][11], tc.NODES_LD_IH[156][12], tc.NODES_LD_IH[156][13], ] self.lookup.on_response_received( *_gen_nodes_args(tc.NODES_LD_IH[157][5], nodes)) eq_(self.lookup._get_announce_candidates(), [ tc.NODES_LD_IH[152][6], tc.NODES_LD_IH[157][3], tc.NODES_LD_IH[157][5], ]) # This response triggers a new query (to 151-8) eq_(self.lookup.num_parallel_queries, 2) # Ongoing queries to (sorted: oldest first): # 150-9, 151-8 # Queued nodes to query (sorted by log_distance to info_hash): # 151-10, 151-11, 156-12, 156-13 # Notice that the lookup queue size limit is 4, therefore # 158-7 and 159-0 are removed from the queue self.lookup.on_error_received(None, tc.NODES_LD_IH[151][8]) # This error triggers a new query (to 151-8) eq_(self.lookup.num_parallel_queries, 2) # Ongoing queries to (sorted: oldest first): # 150-9, 151-10 # Queued nodes to query (sorted by log_distance to info_hash): # 151-11, 156-12, 156-13 self.lookup.on_timeout(tc.NODES_LD_IH[151][8]) # This timeout triggers a new query (to 151-11) eq_(self.lookup.num_parallel_queries, 2) # Ongoing queries to (sorted: oldest first): # 151-10, 151-11 # Queued nodes to query (sorted by log_distance to info_hash): # 156-12, 156-13 nodes = [ tc.NODES_LD_IH[144][14], tc.NODES_LD_IH[145][15], tc.NODES_LD_IH[145][16], tc.NODES_LD_IH[145][17], ] self.lookup.on_response_received( *_gen_nodes_args(tc.NODES_LD_IH[151][10], nodes)) eq_(self.lookup._get_announce_candidates(), [ tc.NODES_LD_IH[151][10], tc.NODES_LD_IH[152][6], tc.NODES_LD_IH[157][3], ]) # This response triggers a new query (to 144-14) eq_(self.lookup.num_parallel_queries, 2) # Ongoing queries to (sorted: oldest first): # 151-11, 144-14 # Queued nodes to query (sorted by log_distance to info_hash): # Notice 156-13 is removed # 145-15, 145-16, 145-17, 156-12 peers = [tc.NO_ADDR] ok_(not self.got_peers) self.lookup.on_response_received( *_gen_peers_args(tc.NODES_LD_IH[144][14], peers)) eq_(self.lookup._get_announce_candidates(), [ tc.NODES_LD_IH[144][14], tc.NODES_LD_IH[151][10], tc.NODES_LD_IH[152][6], ]) ok_(self.got_peers) self.got_peers = False # The response with peers halves parallelism to 1. # No new query is triggered. eq_(self.lookup.num_parallel_queries, 1) # Ongoing queries to (sorted: oldest first): # 151-11 # Queued nodes to query (sorted by log_distance to info_hash): # 145-15, 145-16, 156-12 self.lookup.on_timeout(tc.NODES_LD_IH[151][11]) # This timeout triggers a new query (to 145-15) eq_(self.lookup.num_parallel_queries, 1) # Ongoing queries to (sorted: oldest first): # 145-15 # Queued nodes to query (sorted by log_distance to info_hash): # 145-16, 145-17, 156-12 peers = [tc.NO_ADDR] ok_(not self.got_peers) self.lookup.on_response_received( *_gen_peers_args(tc.NODES_LD_IH[145][15], peers)) # This response triggers a new query (to 145-16) # The parallelism is not halved (remains 1). eq_(self.lookup.num_parallel_queries, 1) # Ongoing queries to (sorted: oldest first): # 145-16 # Queued nodes to query (sorted by log_distance to info_hash): # 145-17, 156-12 eq_(self.lookup._get_announce_candidates(), [ tc.NODES_LD_IH[144][14], tc.NODES_LD_IH[145][15], tc.NODES_LD_IH[151][10], ]) ok_(self.got_peers) self.got_peers = False self.lookup.on_timeout(tc.NODES_LD_IH[145][16]) # This timeout triggers a new query (to 145-17) eq_(self.lookup.num_parallel_queries, 1) # Ongoing queries to (sorted: oldest first): # 145-17 # Queued nodes to query (sorted by log_distance to info_hash): # 156-12 self.lookup.on_timeout(tc.NODES_LD_IH[145][17]) # This timeout triggers a new query (to 156-12) return eq_(self.lookup.num_parallel_queries, 1) # Ongoing queries to (sorted: oldest first): # 156-12 # Queued nodes to query (sorted by log_distance to info_hash): # nodes = [ tc.NODES_LD_IH[144][18], tc.NODES_LD_IH[145][19], ] self.lookup.on_response_received( *_gen_nodes_args(tc.NODES_LD_IH[156][12], nodes)) eq_(self.lookup._get_announce_candidates(), [ tc.NODES_LD_IH[144][14], tc.NODES_LD_IH[145][15], tc.NODES_LD_IH[151][10], ]) # This response triggers a new query (to 144-18) eq_(self.lookup.num_parallel_queries, 1) # Ongoing queries to (sorted: oldest first): # 144-18 # Queued nodes to query (sorted by log_distance to info_hash): # 145-19 peers = [tc.NO_ADDR] ok_(not self.got_peers) self.lookup.on_response_received( *_gen_peers_args(tc.NODES_LD_IH[144][18], peers)) eq_(self.lookup._get_announce_candidates(), [ tc.NODES_LD_IH[144][14], tc.NODES_LD_IH[144][18], tc.NODES_LD_IH[145][15], ]) ok_(self.got_peers) self.got_peers = False # This timeout triggers a new query (145-19) eq_(self.lookup.num_parallel_queries, 0) # Ongoing queries to (sorted: oldest first): # 145-19 # Queued nodes to query (sorted by log_distance to info_hash): # ok_(not self.lookup.is_done) self.lookup.on_timeout(tc.NODES_LD_IH[145][19]) # THE END eq_(self.lookup.num_parallel_queries, 0) ok_(self.lookup.is_done)