def test_dump_routing_table(self): """ Ensure the routing table is dumped into a data structure that can be serialised into JSON. """ version = get_version() data_dump = { 'contacts': [ { 'public_key': PUBLIC_KEY, 'version': version, 'uri': 'http://192.168.0.1:1908', }, ], 'blacklist': [ BAD_PUBLIC_KEY, ] } drog = Drogulus(PRIVATE_KEY, PUBLIC_KEY, self.event_loop, self.connector) drog._node.routing_table.restore(data_dump) result = drog.dump_routing_table() self.assertIsInstance(result, dict) self.assertIn('contacts', result) self.assertIn('blacklist', result) serialised = json.dumps(result) self.assertIsInstance(serialised, str)
def test_join_with_peers(self): """ Ensure that the join method works as expected given a valid list of existing contacts on the network. """ version = get_version() data_dump = { 'contacts': [ { 'public_key': PUBLIC_KEY, 'version': version, 'uri': 'http://192.168.0.1:1908', }, ], 'blacklist': [BAD_PUBLIC_KEY, ] } drog = Drogulus(PRIVATE_KEY, PUBLIC_KEY, self.event_loop, self.connector) result = asyncio.Future() drog._node.join = MagicMock(return_value=result) drog.join(data_dump) drog._node.join.assert_called_once_with(data_dump) drog.set = MagicMock() result.set_result(True) self.event_loop.run_until_complete(result) drog.set.assert_called_once_with(drog.whoami['public_key'], drog.whoami)
def setUp(self): """ Common vars. """ loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) self.event_loop = asyncio.get_event_loop() self.version = get_version() self.sender = mock.MagicMock() self.reply_port = 1908 self.node = Node(PUBLIC_KEY, PRIVATE_KEY, self.event_loop, self.sender, self.reply_port) self.target = TARGET self.seal = 'afakesealthatwillnotverify' node_list = [] remote_node_list = [] for i in range(100, 120): uri = 'netstring://192.168.0.%d:9999/' % i contact = PeerNode(ORDERED_HASHES[i], self.version, uri, 0) node_list.append(contact) remote_node_list.append((ORDERED_HASHES[i], self.version, uri)) self.nodes = tuple(sort_peer_nodes(node_list, self.target)) self.remote_nodes = tuple(remote_node_list) def side_effect(*args, **kwargs): return (str(uuid.uuid4()), asyncio.Future()) self.node.send_find = mock.MagicMock(side_effect=side_effect) self.contacts = [] node_list = [] for i in range(20): uri = 'netstring://192.168.0.%d:%d/' % (i, self.reply_port) contact = PeerNode(ORDERED_HASHES[i], self.version, uri, 0) self.node.routing_table.add_contact(contact) self.contacts.append((ORDERED_HASHES[i], self.version, uri))
def test_dump_routing_table(self): """ Ensure the routing table is dumped into a data structure that can be serialised into JSON. """ version = get_version() data_dump = { 'contacts': [ { 'public_key': PUBLIC_KEY, 'version': version, 'uri': 'http://192.168.0.1:1908', }, ], 'blacklist': [BAD_PUBLIC_KEY, ] } drog = Drogulus(PRIVATE_KEY, PUBLIC_KEY, self.event_loop, self.connector) drog._node.routing_table.restore(data_dump) result = drog.dump_routing_table() self.assertIsInstance(result, dict) self.assertIn('contacts', result) self.assertIn('blacklist', result) serialised = json.dumps(result) self.assertIsInstance(serialised, str)
def test_join_with_peers(self): """ Ensure that the join method works as expected given a valid list of existing contacts on the network. """ version = get_version() data_dump = { 'contacts': [ { 'public_key': PUBLIC_KEY, 'version': version, 'uri': 'http://192.168.0.1:1908', }, ], 'blacklist': [ BAD_PUBLIC_KEY, ] } drog = Drogulus(PRIVATE_KEY, PUBLIC_KEY, self.event_loop, self.connector) result = asyncio.Future() drog._node.join = MagicMock(return_value=result) drog.join(data_dump) drog._node.join.assert_called_once_with(data_dump) drog.set = MagicMock() result.set_result(True) self.event_loop.run_until_complete(result) drog.set.assert_called_once_with(drog.whoami['public_key'], drog.whoami)
def setUp(self): """ Gives us some messages to play with. """ self.uuid = str(uuid4()) self.node = PUBLIC_KEY self.recipient = PUBLIC_KEY self.sender = PUBLIC_KEY self.reply_port = 1908 self.value = 1.234 self.public_key = PUBLIC_KEY self.name = 'a_human_readable_key_name' self.key = construct_key(self.public_key, self.name) signed_dict = get_signed_item(self.key, self.value, self.public_key, PRIVATE_KEY, 1000) self.version = get_version() self.timestamp = signed_dict['timestamp'] self.expires = signed_dict['expires'] self.created_with = signed_dict['created_with'] self.signature = signed_dict['signature'] self.message = 'value' self.seal = 'afakesealthatwillnotwork' self.nodes = [[self.node, self.version, 'http://192.168.0.1:8080/'], ] self.mock_message = Value(self.uuid, self.node, self.node, self.reply_port, self.version, self.seal, self.key, self.value, self.timestamp, self.expires, self.created_with, self.public_key, self.name, self.signature)
def setUp(self): """ Set up a new throw-away event loop. """ loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) self.event_loop = asyncio.get_event_loop() self.version = get_version()
def test_get_version(self): """ Ensures the get_version function returns a dot separated expression of the VERSION. """ expected = '.'.join([str(i) for i in VERSION]) actual = get_version() self.assertEqual(expected, actual)
def test_hash(self): """ Ensure the hash for the object is correct. """ uri = 'netstring://192.168.0.1:9999' contact = PeerNode(PUBLIC_KEY, get_version(), uri, 0) expected = hash(sha512(PUBLIC_KEY.encode('ascii')).hexdigest()) self.assertEqual(expected, hash(contact))
def setUp(self): self.uuid = str(uuid4()) self.node = PUBLIC_KEY self.sender = PUBLIC_KEY self.recipient = PUBLIC_KEY self.reply_port = 1908 self.key = sha512(uuid4().bytes).hexdigest() self.version = get_version() self.seal = 'afakesealthatwillnotwork'
def setUp(self): """ A whole bunch of generic stuff we regularly need to faff about with that are set to some sane defaults. """ loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) self.event_loop = asyncio.get_event_loop() self.connector = NetstringConnector(self.event_loop) self.version = get_version()
def test_eq_wrong_type(self): """ Ensure equality returns false if comparing a PeerNode with some other type of object. """ uri = 'netstring://192.168.0.1:9999' version = get_version() last_seen = 123 contact = PeerNode(PUBLIC_KEY, version, uri, last_seen) self.assertFalse(12345 == contact)
def test_ne(self): """ Makes sure non-equality works between a string representation of an ID and a PeerNode object. """ uri = 'netstring://192.168.0.1:9999' version = get_version() last_seen = 123 contact = PeerNode(PUBLIC_KEY, version, uri, last_seen) self.assertTrue('54321' != contact)
def test_eq_other_peer(self): """ Ensure equality works between two PeerNode instances. """ uri = 'netstring://192.168.0.1:9999' version = get_version() last_seen = 123 contact1 = PeerNode(PUBLIC_KEY, version, uri, last_seen) contact2 = PeerNode(PUBLIC_KEY, version, uri, last_seen) self.assertTrue(contact1 == contact2)
def test_repr(self): """ Ensure the repr for the object is something useful. """ network_id = sha512(PUBLIC_KEY.encode('ascii')).hexdigest() uri = 'netstring://192.168.0.1:9999' version = get_version() last_seen = 123 contact = PeerNode(PUBLIC_KEY, version, uri, last_seen) expected = str((network_id, PUBLIC_KEY, version, uri, last_seen, 0)) self.assertEqual(expected, repr(contact))
def test_eq(self): """ Makes sure equality works between a string representation of an ID and a PeerNode object. """ network_id = sha512(PUBLIC_KEY.encode('ascii')).hexdigest() version = get_version() uri = 'netstring://192.168.0.1:9999' last_seen = 123 contact = PeerNode(PUBLIC_KEY, version, uri, last_seen) self.assertTrue(network_id == contact)
def test_str(self): """ Ensures the string representation of a contact is something useful. """ id = '12345' address = '192.168.0.1' port = 9999 version = get_version() last_seen = 123 contact = Contact(id, address, port, version, last_seen) expected = "('12345', '192.168.0.1', 9999, '%s')" % version self.assertEqual(expected, str(contact))
def test_ne(self): """ Makes sure non-equality works between a string representation of an ID and a contact object. """ id = '12345' address = '192.168.0.1' port = 9999 version = get_version() last_seen = 123 contact = Contact(id, address, port, version, last_seen) self.assertTrue('54321' != contact)
def test_init(self): """ Ensure the Drogulus instance is created as expected. """ d = Drogulus(PRIVATE_KEY, PUBLIC_KEY, self.event_loop, self.connector) self.assertEqual(d.private_key, PRIVATE_KEY) self.assertEqual(d.public_key, PUBLIC_KEY) self.assertEqual(d.event_loop, self.event_loop) self.assertEqual(d.connector, self.connector) self.assertIsInstance(d._node, Node) self.assertEqual(d._node.reply_port, 1908) self.assertEqual(d.whoami['public_key'], PUBLIC_KEY) self.assertEqual(d.whoami['version'], get_version())
def test_dump(self): """ Ensure the expected dictionary object is returned from a call to the instance's dump method (used for backing up the routing table). """ uri = 'netstring://192.168.0.1:9999' version = get_version() contact = PeerNode(PUBLIC_KEY, version, uri) result = contact.dump() self.assertEqual(result['public_key'], PUBLIC_KEY) self.assertEqual(result['version'], version) self.assertEqual(result['uri'], uri) self.assertEqual(3, len(result))
def test_init_with_whoami_dict(self): """ Ensure that arbitrary data passed in as the whoami argument ends up set in the node's whoami attribute. """ whoami = { 'name': 'fred' } d = Drogulus(PRIVATE_KEY, PUBLIC_KEY, self.event_loop, self.connector, whoami=whoami) self.assertEqual(d.whoami['public_key'], PUBLIC_KEY) self.assertEqual(d.whoami['version'], get_version()) self.assertEqual(d.whoami['name'], 'fred')
def test_init_with_int_id(self): """ If the ID is passed in as an int value ensure it's translated to the correct string representation of the hex version. """ id = 12345 address = '192.168.0.1' port = 9999 version = get_version() last_seen = 123 contact = Contact(id, address, port, version, last_seen) expected = '09' self.assertEqual(expected, contact.id) self.assertEqual(12345L, long(contact.id.encode('hex'), 16))
def test_check_seal_invalid_seal(self): """ Ensure a message with an invalid seal fails the check. """ ok_dict = { 'uuid': str(uuid.uuid4()), 'recipient': PUBLIC_KEY, 'sender': BAD_PUBLIC_KEY, 'reply_port': 1908, 'version': get_version() } seal = get_seal(ok_dict, PRIVATE_KEY) ok = OK(ok_dict['uuid'], ok_dict['recipient'], ok_dict['sender'], ok_dict['reply_port'], ok_dict['version'], seal) self.assertFalse(check_seal(ok))
def test_init(self): """ Ensures an object is created as expected. """ uri = 'netstring://192.168.0.1:9999' version = get_version() last_seen = 123 contact = PeerNode(PUBLIC_KEY, version, uri, last_seen) hex_digest = sha512(PUBLIC_KEY.encode('ascii')).hexdigest() self.assertEqual(contact.network_id, hex_digest) self.assertEqual(PUBLIC_KEY, contact.public_key) self.assertEqual(version, contact.version) self.assertEqual(uri, contact.uri) self.assertEqual(last_seen, contact.last_seen) self.assertEqual(0, contact.failed_RPCs)
def test_check_seal_bad_seal(self): """ Ensure a message with a bad seal (i.e. malformed junk) fails the check. """ ok_dict = { 'uuid': str(uuid.uuid4()), 'recipient': PUBLIC_KEY, 'sender': BAD_PUBLIC_KEY, 'reply_port': 1908, 'version': get_version() } seal = 'not a seal' ok = OK(ok_dict['uuid'], ok_dict['recipient'], ok_dict['sender'], ok_dict['reply_port'], ok_dict['version'], seal) self.assertFalse(check_seal(ok))
def test_send_message(self): """ Ensure the message passed into the protocol is turned into a netstring version of a msgpacked message. """ # Create a simple Ping message uuid = str(uuid4()) version = get_version() msg = Pong(uuid, self.node_id, version) # Send it down the wire... self.protocol.sendMessage(msg) # Check it's as expected. expected = self._to_netstring(to_msgpack(msg)) actual = self.transport.value() self.assertEqual(expected, actual)
def test_check_seal_bad_seal(self): """ Ensure a message with a bad seal (i.e. malformed junk) fails the check. """ ok_dict = { "uuid": str(uuid.uuid4()), "recipient": PUBLIC_KEY, "sender": BAD_PUBLIC_KEY, "reply_port": 1908, "version": get_version(), } seal = "not a seal" ok = OK( ok_dict["uuid"], ok_dict["recipient"], ok_dict["sender"], ok_dict["reply_port"], ok_dict["version"], seal ) self.assertFalse(check_seal(ok))
def test_string_received_good_message(self): """ Ensures the correct method on the local node object is called with the expected arguments. """ # Mock self.node.message_received = MagicMock(return_value=True) # Create a simple Ping message uuid = str(uuid4()) version = get_version() msg = Pong(uuid, self.node_id, version) # Receive it... raw = to_msgpack(msg) self.protocol.stringReceived(raw) # Check it results in a call to the node's message_received method. self.node.message_received.assert_called_once_with(msg, self.protocol)
def test_check_seal(self): """ Make sure message objects that contain a valid seal are correctly checked. """ ok_dict = { 'uuid': str(uuid.uuid4()), 'recipient': PUBLIC_KEY, 'sender': PUBLIC_KEY, 'reply_port': 1908, 'version': get_version() } seal = get_seal(ok_dict, PRIVATE_KEY) ok = OK(ok_dict['uuid'], ok_dict['recipient'], ok_dict['sender'], ok_dict['reply_port'], ok_dict['version'], seal) self.assertTrue(check_seal(ok))
def test_check_seal_invalid_seal(self): """ Ensure a message with an invalid seal fails the check. """ ok_dict = { "uuid": str(uuid.uuid4()), "recipient": PUBLIC_KEY, "sender": BAD_PUBLIC_KEY, "reply_port": 1908, "version": get_version(), } seal = get_seal(ok_dict, PRIVATE_KEY) ok = OK( ok_dict["uuid"], ok_dict["recipient"], ok_dict["sender"], ok_dict["reply_port"], ok_dict["version"], seal ) self.assertFalse(check_seal(ok))
def test_init(self): """ Ensures an object is created as expected. """ id = '12345' address = '192.168.0.1' port = 9999 version = get_version() last_seen = 123 contact = Contact(id, address, port, version, last_seen) self.assertEqual(id, contact.id) self.assertEqual(address, contact.address) self.assertEqual(port, contact.port) self.assertEqual(version, contact.version) self.assertEqual(last_seen, contact.last_seen) self.assertEqual(0, contact.failed_RPCs)
def test_check_seal(self): """ Make sure message objects that contain a valid seal are correctly checked. """ ok_dict = { "uuid": str(uuid.uuid4()), "recipient": PUBLIC_KEY, "sender": PUBLIC_KEY, "reply_port": 1908, "version": get_version(), } seal = get_seal(ok_dict, PRIVATE_KEY) ok = OK( ok_dict["uuid"], ok_dict["recipient"], ok_dict["sender"], ok_dict["reply_port"], ok_dict["version"], seal ) self.assertTrue(check_seal(ok))
def test_str(self): """ Ensures the string representation of a PeerContact is something useful. """ uri = 'netstring://192.168.0.1:9999' version = get_version() last_seen = 123 contact = PeerNode(PUBLIC_KEY, version, uri, last_seen) expected = str({ 'network_id': contact.network_id, 'public_key': contact.public_key, 'version': contact.version, 'uri': contact.uri, 'last_seen': contact.last_seen, 'failed_rpc': contact.failed_RPCs }) self.assertEqual(expected, str(contact))
def test_make_message(self): """ The good case returns an instance of the given class based upon the data provided. """ uuid = str(uuid4()) node = PUBLIC_KEY reply_port = 1908 version = get_version() result = make_message(OK, {'uuid': uuid, 'recipient': node, 'sender': node, 'reply_port': reply_port, 'version': version, 'seal': 'fakeseal'}) self.assertIsInstance(result, OK) self.assertEqual(uuid, result.uuid) self.assertEqual(node, result.recipient) self.assertEqual(node, result.sender) self.assertEqual(reply_port, result.reply_port) self.assertEqual(version, result.version) self.assertEqual('fakeseal', result.seal)
def run_tests(port, logfile): """ Send each sort of message to the node and check each response is as expected. """ private_key, public_key = get_keypair() version = get_version() tests = [func for name, func in inspect.getmembers(sys.modules[__name__]) if (inspect.isfunction(func) and name.startswith('test'))] fails = 0 for test in tests: msg = ''.join([GREEN, 'OK', ENDC]) try: test(port, version, public_key, private_key) except: msg = ''.join([RED, 'FAIL', ENDC]) msg += '\n{}'.format(traceback.format_exc()) fails += 1 print('{}... {}'.format(test.__name__, msg)) return fails
def test_expected_metadata(self): """ Ensure the item (dict) returned from the function contains the expected metadata. """ key = 'key' value = 'value' signed_item = get_signed_item(key, value, PUBLIC_KEY, PRIVATE_KEY) self.assertIn('timestamp', signed_item) self.assertIsInstance(signed_item['timestamp'], float) self.assertIn('expires', signed_item) self.assertIsInstance(signed_item['expires'], float) self.assertIn('created_with', signed_item) self.assertEqual(signed_item['created_with'], get_version()) self.assertIn('public_key', signed_item) self.assertEqual(signed_item['public_key'], PUBLIC_KEY) self.assertIn('signature', signed_item) self.assertIsInstance(signed_item['signature'], str) self.assertIn('key', signed_item) self.assertIsInstance(signed_item['key'], str) self.assertEqual(signed_item['key'], construct_key(PUBLIC_KEY, key)) self.assertEqual(signed_item['name'], key) self.assertEqual(signed_item['value'], value)
def test_dunder_version(self): """ Ensure that the __version__ attribute of the drogulus module is the expected version. """ self.assertEqual(__version__, get_version())
#!/usr/bin/env python from setuptools import setup from drogulus.version import get_version with open('README.rst') as f: readme = f.read() with open('CHANGES.rst') as f: changes = f.read() setup(name='drogulus', version=get_version(), description=' '.join([ 'A peer-to-peer data store built for simplicity,' 'security, openness and fun.' ]), long_description=readme + '\n\n' + changes, author='Nicholas H.Tollervey', author_email='*****@*****.**', url='http://drogul.us/', package_dir={'drogulus': 'drogulus'}, package_data={ '': [ 'ACCORD', 'AUTHORS', 'README.rst', 'CHANGES.rst', 'LICENSE', 'UNLICENSE', 'WAIVER' ] }, packages=[ 'drogulus', 'drogulus.contrib', 'drogulus.net', 'drogulus.commands', 'drogulus.dht' ], license='Public Domain',
def setUp(self): """ Common vars. """ self.version = get_version()