示例#1
0
    def test_find_node_Received_sendsValidResponseMultipleNodes(self):
        # Create the protocol and populate its
        # routing table with nodes
        kresponder = Patched_KRPC_Responder()
        node_list = []
        node_gen = lambda num: contact.Node(num, ("127.0.0.%d" % num, num))
        for i in range(100):
            n = node_gen(i)
            if kresponder.routing_table.offer_node(n):
                node_list.append(n)

        querying_node = contact.Node(123, test_address)
        incoming_query = Query()
        incoming_query.rpctype = "find_node"
        incoming_query._from = querying_node.node_id
        incoming_query._transaction_id = 15
        incoming_query.target_id = 777777

        expected_response = Response()
        expected_response._from = kresponder.node_id
        expected_response._transaction_id = 15
        expected_response.rpctype = "find_node"
        node_list.sort(
            key=lambda node: node.distance(incoming_query.target_id))
        node_list = node_list[:constants.k]
        expected_response.nodes = node_list

        kresponder.datagramReceived(krpc_coder.encode(incoming_query),
                                    test_address)
        actual_response = kresponder.sendResponse.response
        self.assertEquals(expected_response, actual_response)
示例#2
0
 def test_better_than_bothOldWithNoQueries(self):
     self.clock.set(0)
     n1 = contact.Node(2**1, ("127.0.0.1", 1111))
     n2 = contact.Node(2**2, ("127.0.0.1", 2222))
     self.clock.set(constants.node_timeout + 1)
     self.assertFalse(n1.better_than(n2))
     self.assertFalse(n2.better_than(n1))
示例#3
0
 def test_better_than_oneFreshOneOld(self):
     self.clock.set(0)
     n_old = contact.Node(2**1, ("127.0.0.1", 1111))
     n_fresh = contact.Node(2**2, ("127.0.0.1", 2222))
     self.clock.set(constants.node_timeout + 1)
     n_fresh.successful_query(10)
     self.assertTrue(n_fresh.better_than(n_old))
     self.assertFalse(n_old.better_than(n_fresh))
示例#4
0
 def test_better_than_oneBetterRTT(self):
     self.clock.set(0)
     n_slow = contact.Node(2**1, ("127.0.0.1", 1111))
     n_fast = contact.Node(2**2, ("127.0.0.1", 2222))
     self.clock.set(10)
     n_slow.successful_query(0)
     n_fast.successful_query(5)
     self.assertTrue(n_fast.better_than(n_slow))
     self.assertFalse(n_slow.better_than(n_fast))
示例#5
0
 def test_distance(self):
     node_ids1 = [0, 1024, 2**150, 2**159 + 124, 2**34 - 58]
     node_ids2 = [0, 857081, 6**7, 8**9 + 7**3, 4**8 + 9**10 + 18]
     for id1 in node_ids1:
         for id2 in node_ids2:
             n = contact.Node(id1, ("127.0.0.1", 8000))
             self.assertEqual(id1 ^ id2, n.distance(id2))
             n = contact.Node(id2, ("127.0.0.1", 8000))
             self.assertEqual(id2 ^ id1, n.distance(id1))
示例#6
0
    def test_get_peers_Received_sendsValidResponseWithNodes(self):
        # Create the protocol and populate its
        # routing table with nodes
        # We need a node_id close to 'target_id' so that our kbuckets split
        # in a way that we will have the target id
        target_id = 76
        our_id = target_id - 1

        kresponder = Patched_KRPC_Responder(node_id=our_id)
        node_list = []
        node_gen = lambda num: contact.Node(num, ("127.0.0.%d" % num, num))
        for i in range(100):
            if i != our_id:
                n = node_gen(i)
                if kresponder.routing_table.offer_node(n):
                    node_list.append(n)

        # simulate that a get_peers query has been
        # received by making a fake get_peers query
        # and feeding it into "datagramReceived()"
        querying_node = contact.Node(123, test_address)
        incoming_query = Query()
        incoming_query.rpctype = "get_peers"
        incoming_query._from = querying_node.node_id
        incoming_query._transaction_id = 15
        # We have this target id in our routing table
        incoming_query.target_id = target_id

        # Create a response object and ensure
        # and the response (that the node sends)
        # matches what we made
        expected_response = Response()
        expected_response._from = kresponder.node_id
        expected_response._transaction_id = incoming_query._transaction_id
        expected_response.rpctype = "get_peers"
        # the specification calls for the resulting
        # nodes to be sorted by distance
        node_list.sort(
            key=lambda node: node.distance(incoming_query.target_id))
        node_list = node_list[:constants.k]
        expected_response.nodes = node_list

        # simulating the incoming query and capture
        # the outgoing response
        kresponder.datagramReceived(krpc_coder.encode(incoming_query),
                                    test_address)
        actual_response = kresponder.sendResponse.response
        # Grab the autogenerated token
        expected_response.token = actual_response.token

        self.assertEquals(expected_response, actual_response)
示例#7
0
 def test_fresh(self):
     n = contact.Node(2**17, ("127.0.0.1", 8012))
     self.assertTrue(n.fresh())
     # Simulate that `constants.node_timeout' time has passed
     self.clock.set(constants.node_timeout + 1)
     self.assertFalse(n.fresh())
     # Refresh the node with a new query
     n.successful_query(10)
     self.assertTrue(n.fresh())
示例#8
0
 def _save_received_node(self, krpc, address):
     """
     save node from the out request node if it is not in routing table yet
     """
     if self.routing_table.get_node(krpc._from):
         return
     node = contact.Node(node_id=krpc._from, address=address)
     self.routing_table.offer_node(node)
     log.msg("save the request from node(%s:%s) done" % address)
示例#9
0
    def test_find_node_Received_sendsValidResponseWithTargetNode(self):
        # Create the protocol and populate its
        # routing table with nodes
        # We need a node_id close to 'target_id' so that our kbuckets split
        # in a way that we will have the target id
        target_id = 76
        our_id = target_id - 1

        kresponder = Patched_KRPC_Responder(node_id=our_id)
        node_list = []
        node_gen = lambda num: contact.Node(num, ("127.0.0.%d" % num, num))
        for i in range(100):
            if i != our_id:
                n = node_gen(i)
                node_was_accepted = kresponder.routing_table.offer_node(n)
                if node_was_accepted:
                    node_list.append(n)

        querying_node = contact.Node(123, test_address)
        incoming_query = Query()
        incoming_query.rpctype = "find_node"
        incoming_query._from = querying_node.node_id
        incoming_query._transaction_id = 15
        # We have this target id in our routing table
        incoming_query.target_id = target_id

        expected_response = Response()
        expected_response._from = kresponder.node_id
        expected_response._transaction_id = 15
        expected_response.rpctype = "find_node"

        # The response node_list should contain only the target node
        node_list = filter(lambda node: node.node_id == target_id, node_list)
        expected_response.nodes = node_list
        if len(node_list) != 1:
            self.fail("Too many or too few nodes!")

        kresponder.datagramReceived(krpc_coder.encode(incoming_query),
                                    test_address)
        actual_response = kresponder.sendResponse.response
        self.assertEquals(expected_response, actual_response)
示例#10
0
 def _init_routing_table():
     """
     restore routing table
     """
     node_list = database["routing_table"].find()
     for _node in node_list:
         node = contact.Node(
             node_id=int(_node["_id"]),
             address=(_node["ip"], _node["port"]),
             last_updated=_node["last_updated"],
             totalrtt=_node["totalrtt"],
             successcount=_node["successcount"],
             failcount=_node["failcount"],
         )
         TreeRoutingTable._instance.offer_node(node)
示例#11
0
    def _query_success(self, response, address, transaction):
        """
        Handle a valid Response to an outstanding Query

        This callback records changes to the statistics for the
        node behind the address/response (ie, it updates its RTT
        and makes sures it is in the routing table)

        """
        # Pull the node corresponding to this response out
        # of our routing table, or create it if it doesn't exist
        response_node = self.routing_table.get_node(response._from)
        if response_node is None:
            response_node = contact.Node(response._from, address)
        response_node.successful_query(transaction.time)
        self.routing_table.offer_node(response_node)
        # Pass the response further down the callback chain
        return response
示例#12
0
    def _query_success_callback(self, response, address, transaction):
        """
        Handle a valid Response to an outstanding Query

        This callback records changes to the statistics for the
        node behind the address/response (ie, it updates its RTT
        and makes sures it is in the routing table)

        """
        # Pull the node corresponding to this response out
        # of our routing table, or create it if it doesn't exist
        log.msg("_query_success_callback")

        # get/create node, and update the node's activeness for later calculation
        rt_node = self.routing_table.get_node(response._from)
        responsenode = (rt_node if rt_node is not None
                        else contact.Node(response._from, address))
        responsenode.successful_query(transaction.time)

        self.routing_table.offer_node(responsenode)
        # Pass the response further down the callback chain
        return response
示例#13
0
from mdht import contact

_make_node = lambda x: contact.Node(x, ('127.0.0.1', x))
test_nodes = [_make_node(x) for x in range(1, 256)]


class Clock(object):
    """
    >>> import time
    >>> time.time = Clock()
    >>> time.time()
    0
    >>> time.time.set(5)
    >>> time.time()
    5
    >>> 
    """
    def __init__(self):
        self._time = 0

    def __call__(self):
        return self.time()

    def time(self):
        return self._time

    def set(self, time):
        self._time = time


class Counter(object):