added a query script and test for utils

This commit is contained in:
Brian Muller 2015-01-06 21:52:01 -05:00
parent d126479bce
commit c0b05eb6d3
6 changed files with 104 additions and 8 deletions

View File

@ -20,6 +20,7 @@ This library aims to be as close to a reference implementation of the `Kademlia
:titlesonly: :titlesonly:
intro intro
querying
source/modules source/modules

12
docs/querying.rst Normal file
View File

@ -0,0 +1,12 @@
Querying the DHT
==================
If you just want to query the network, you can use the example query script. For instance::
$ python examples/query.py 1.2.3.4 8468 SpecialKey
The query script is simple:
.. literalinclude:: ../examples/query.py
Check out the examples folder for other examples.

33
examples/query.py Normal file
View File

@ -0,0 +1,33 @@
from twisted.internet import reactor
from twisted.python import log
from kademlia.network import Server
import sys
log.startLogging(sys.stdout)
if len(sys.argv) != 4:
print "Usage: python query.py <bootstrap ip> <bootstrap port> <key>"
sys.exit(1)
ip = sys.argv[1]
port = int(sys.argv[2])
key = sys.argv[3]
print "Getting %s (with bootstrap %s:%i)" % (key, ip, port)
def done(result):
print "Key result:"
print result
reactor.stop()
def bootstrapDone(found, server, key):
if len(found) == 0:
print "Could not connect to the bootstrap server."
reactor.stop()
server.get(key).addCallback(done)
server = Server()
server.listen(port)
server.bootstrap([(ip, port)]).addCallback(bootstrapDone, server, key)
reactor.run()

View File

@ -152,7 +152,7 @@ class RoutingTable(object):
if bucket.addNode(node): if bucket.addNode(node):
return return
# Per section 4.2 of paper, split if the bucket has the node in it's range # Per section 4.2 of paper, split if the bucket has the node in its range
# or if the depth is not congruent to 0 mod 5 # or if the depth is not congruent to 0 mod 5
if bucket.hasInRange(self.node) or bucket.depth() % 5 != 0: if bucket.hasInRange(self.node) or bucket.depth() % 5 != 0:
self.splitBucket(index) self.splitBucket(index)

View File

@ -0,0 +1,37 @@
import hashlib
from twisted.trial import unittest
from kademlia.utils import digest, sharedPrefix, OrderedSet
class UtilsTest(unittest.TestCase):
def test_digest(self):
d = hashlib.sha1('1').digest()
self.assertEqual(d, digest(1))
d = hashlib.sha1('another').digest()
self.assertEqual(d, digest('another'))
def test_sharedPrefix(self):
args = ['prefix', 'prefixasdf', 'prefix', 'prefixxxx']
self.assertEqual(sharedPrefix(args), 'prefix')
args = ['p', 'prefixasdf', 'prefix', 'prefixxxx']
self.assertEqual(sharedPrefix(args), 'p')
args = ['one', 'two']
self.assertEqual(sharedPrefix(args), '')
args = ['hi']
self.assertEqual(sharedPrefix(args), 'hi')
class OrderedSetTest(unittest.TestCase):
def test_order(self):
o = OrderedSet()
o.push('1')
o.push('1')
o.push('2')
o.push('1')
self.assertEqual(o, ['2', '1'])

View File

@ -15,13 +15,15 @@ def digest(s):
def deferredDict(d): def deferredDict(d):
""" """
Just like a C{defer.DeferredList} but instead accepts and returns a C{dict}. Just like a :class:`defer.DeferredList` but instead accepts and returns a :class:`dict`.
@param d: A C{dict} whose values are all C{Deferred} objects. Args:
d: A :class:`dict` whose values are all :class:`defer.Deferred` objects.
@return: A C{DeferredList} whose callback will be given a dictionary whose Returns:
keys are the same as the parameter C{d}'s and whose values are the results :class:`defer.DeferredList` whose callback will be given a dictionary whose
of each individual deferred call. keys are the same as the parameter :obj:`d` and whose values are the results
of each individual deferred call.
""" """
if len(d) == 0: if len(d) == 0:
return defer.succeed({}) return defer.succeed({})
@ -37,7 +39,15 @@ def deferredDict(d):
class OrderedSet(list): class OrderedSet(list):
"""
Acts like a list in all ways, except in the behavior of the :meth:`push` method.
"""
def push(self, thing): def push(self, thing):
"""
1. If the item exists in the list, it's removed
2. The item is pushed to the end of the list
"""
if thing in self: if thing in self:
self.remove(thing) self.remove(thing)
self.append(thing) self.append(thing)
@ -47,8 +57,11 @@ def sharedPrefix(args):
""" """
Find the shared prefix between the strings. Find the shared prefix between the strings.
For instance, sharedPrefix(['blahblah', 'blahwhat']) is For instance:
'blah'.
sharedPrefix(['blahblah', 'blahwhat'])
returns 'blah'.
""" """
i = 0 i = 0
while i < min(map(len, args)): while i < min(map(len, args)):