def test_basic_server_transaction(self): """Tests the server transaction protocol and logic""" db = ContentDB() tc = db.add_messages([Message('fubar'), Message('foo'), Message('bar')]) with TestServerHelper() as server_helper, TestClientHelper() as client_helper: srv_transaction = ServerTransaction(server_helper.sock, db) test_client = SocketTransaction(client_helper.sock, b'\n') """Run the server transaction in a separate thread to allow client access""" thread = threading.Thread(target=srv_transaction.process) thread.start() """Check greeting from server""" rcv = test_client._read() self.assertEqual(rcv, Protocol.create_greeting_message(db.id).encode()) """Check response to mdgid list req""" test_client._write(Protocol.create_message_id_list_request(tc).encode()) rcv = test_client._read() self.assertEqual(rcv, Protocol.create_message_id_list(tc, None).encode()) """Check response to mdg req""" test_client._write(Protocol.create_message_list_request([msg.id for msg in db.get_messages()]).encode()) rcv = test_client._read() self.assertEqual(rcv, Protocol.create_message_list(db.get_messages()).encode()) """Wait for server (will time out if no requests)""" thread.join(2*TIMEOUT)
def test_identity_info(self): """Test the IdentityInfo class""" db = ContentDB(tempfile.NamedTemporaryFile().name) id_a = dandelion.identity.generate() db.add_identities([id_a]) # Test creation id_info_a = IdentityInfo(db, id_a) self.assertEqual(id_info_a.db, db) self.assertEqual(id_info_a.id.fingerprint, id_a.fingerprint) self.assertIsNone(id_info_a.nick) self.assertTrue(id_info_a.is_private()) self.assertFalse(IdentityInfo(db, id_a.public_identity()).is_private()) # Test nick set/get id_info_a.nick = "me" self.assertEqual(id_info_a.nick, "me") id_info_a.nick = "you" self.assertEqual(id_info_a.nick, "you") id_info_a.nick = None self.assertIsNone(id_info_a.nick) # Test bad input self.assertRaises(TypeError, id_info_a.nick, 0) self.assertRaises(TypeError, id_info_a.nick, b'')
def test_client_server_transaction(self): """Tests the whole, client driven transaction protocol and logic""" client_db = ContentDB() server_db = ContentDB() server_db.add_messages([Message('fubar'), Message('foo'), Message('bar')]) self.assertEqual(client_db.message_count, 0) self.assertEqual(server_db.message_count, 3) with TestServerHelper() as server_helper, TestClientHelper() as client_helper: client_transaction = ClientTransaction(client_helper.sock, client_db) server_transaction = ServerTransaction(server_helper.sock, server_db) """Run the client transactions asynchronously""" server_thread = threading.Thread(target=server_transaction.process) client_thread = threading.Thread(target=client_transaction.process) server_thread.start() client_thread.start() """Wait for client to hang up""" client_thread.join(1) # One sec should be plenty server_thread.join(2*TIMEOUT) """Make sure the client has updated the db""" self.assertEqual(client_db.message_count, 3) self.assertEqual(server_db.message_count, 3) self.assertEqual(len([srvmsg for srvmsg in server_db.get_messages() if srvmsg not in client_db.get_messages()]), 0)
def test_basic_client_transaction(self): """Tests the client transaction protocol and logic""" client_db = ContentDB() srv_db = ContentDB() tc = srv_db.add_messages( [Message('fubar'), Message('foo'), Message('bar')]) self.assertEqual(client_db.message_count, 0) self.assertEqual(srv_db.message_count, 3) with TestServerHelper() as server_helper, TestClientHelper( ) as client_helper: client_transaction = ClientTransaction(client_helper.sock, client_db) srv_sock = SocketTransaction(server_helper.sock, b'\n') """Run the client transaction in a separate thread""" thread = threading.Thread(target=client_transaction.process) thread.start() """Send a greeting (should be req. by client)""" srv_sock._write( Protocol.create_greeting_message(srv_db.id).encode()) """Reading msg id list request""" rcv = srv_sock._read() self.assertEqual( rcv, Protocol.create_message_id_list_request().encode()) """Sending the msg id list""" srv_sock._write( Protocol.create_message_id_list( tc, srv_db.get_messages()).encode()) """Reading msg list request""" rcv = srv_sock._read() self.assertEqual( rcv, Protocol.create_message_list_request( [msg.id for msg in srv_db.get_messages()]).encode()) """Sending the msg id list""" srv_sock._write( Protocol.create_message_list(srv_db.get_messages()).encode()) """Wait for client to hang up""" thread.join(2 * TIMEOUT) """Make sure the client has updated the db""" self.assertEqual(client_db.message_count, 3) self.assertEqual(srv_db.message_count, 3) self.assertEqual( len([ srvmsg for srvmsg in srv_db.get_messages() if srvmsg not in client_db.get_messages() ]), 0)
def test_client_server_transaction(self): """Tests the whole, client driven transaction protocol and logic""" client_db = ContentDB() server_db = ContentDB() server_db.add_messages( [Message('fubar'), Message('foo'), Message('bar')]) self.assertEqual(client_db.message_count, 0) self.assertEqual(server_db.message_count, 3) with TestServerHelper() as server_helper, TestClientHelper( ) as client_helper: client_transaction = ClientTransaction(client_helper.sock, client_db) server_transaction = ServerTransaction(server_helper.sock, server_db) """Run the client transactions asynchronously""" server_thread = threading.Thread(target=server_transaction.process) client_thread = threading.Thread(target=client_transaction.process) server_thread.start() client_thread.start() """Wait for client to hang up""" client_thread.join(1) # One sec should be plenty server_thread.join(2 * TIMEOUT) """Make sure the client has updated the db""" self.assertEqual(client_db.message_count, 3) self.assertEqual(server_db.message_count, 3) self.assertEqual( len([ srvmsg for srvmsg in server_db.get_messages() if srvmsg not in client_db.get_messages() ]), 0)
def test_get_messages(self): """Test message retrieval.""" db = ContentDB(tempfile.NamedTemporaryFile().name) _, mlist = db.get_messages() self.assertEqual(mlist, []) id1 = dandelion.identity.generate() id2 = dandelion.identity.generate() m1 = Message('M1') m2 = Message('M2') m3 = dandelion.message.create('M3', 1337, id1, id2) db.add_identities([id1]) db.add_messages([m1, m2, m3]) _, mlist = db.get_messages() self.assertTrue(m1 in mlist) self.assertTrue(m2 in mlist) self.assertTrue(m3 in mlist) _, mlist = db.get_messages([m1.id, m3.id]) self.assertTrue(m1 in mlist) self.assertFalse(m2 in mlist) self.assertTrue(m3 in mlist)
def test_single_message_interface(self): """Test functions relating to storing and recovering single messages""" db = ContentDB() first_msg = Message("A message") # Try to add junk self.assertRaises(ValueError, db.add_messages, None) self.assertRaises(TypeError, db.add_messages, 23) self.assertRaises(TypeError, db.add_messages, [None]) # Add a single message db.add_messages([first_msg]) self.assertEqual(db.message_count, 1) self.assertEqual(db.contains_messages([first_msg]), [True])
def __init__(self, config_file='dandelion.conf'): self._cfg_file_name = config_file self._server_config = ServerConfig() self._synchronizer_config = SynchronizerConfig() self._discoverer_config = DiscovererConfig() self._id_manager_config = IdentityConfig() self._ui_config = UiConfig() self.read_file() self._content_db = ContentDB(self._server_config.db_file) if self._id_manager_config.my_id is not None and not self._content_db.contains_identity(decode_b64_bytes(self._id_manager_config.my_id.encode())) : print("WARNING! Bad or non existing ID requested in config. Requested:", self._id_manager_config.my_id) self._id_manager_config.my_id = None if self._id_manager_config.my_id is not None: fp = decode_b64_bytes(self._id_manager_config.my_id.encode()) try: self._identity = self._content_db.get_private_identity(fp) print("My claimed ID:", self._id_manager_config.my_id) return except ValueError: pass self._identity = dandelion.identity.generate() self._content_db.add_private_identity(self._identity) id_str = encode_b64_bytes(self._identity.fingerprint).decode() self._id_manager_config.my_id = id_str
def test_get_identities(self): """Test identity retrieval.""" db = ContentDB(tempfile.NamedTemporaryFile().name) id1 = dandelion.identity.generate() id2 = dandelion.identity.generate().public_identity() id3 = dandelion.identity.generate() db.add_identities([id1, id2, id3]) db.add_messages([Message("fu")]) _, idlist = db.get_identities() self.assertTrue(id1 in idlist) self.assertTrue(id2 in idlist) self.assertTrue(id3 in idlist) for id in idlist: self.assertFalse(id.rsa_key.is_private) self.assertFalse(id.dsa_key.is_private) _, idlist = db.get_identities(fingerprints=[id1.fingerprint, id2.fingerprint]) self.assertTrue(id1 in idlist) self.assertTrue(id2 in idlist) self.assertFalse(id3 in idlist) for id in idlist: self.assertFalse(id.rsa_key.is_private) self.assertFalse(id.dsa_key.is_private)
def test_singleton(self): """Test the singleton register / unregister function.""" self.assertEqual(ContentDB.db, None) self.assertRaises(ContentDBException, ContentDB.register, None) self.assertRaises(ContentDBException, ContentDB.register, 23) self.assertRaises(ContentDBException, ContentDB.unregister) db = ContentDB(":memory:") ContentDB.register(db) self.assertRaises(ContentDBException, ContentDB.register, db) self.assertRaises(ContentDBException, ContentDB.register, ContentDB(":memory:")) db_back = ContentDB.db self.assertNotEqual(db_back, None) self.assertEqual(db_back, db) ContentDB.unregister() self.assertEqual(ContentDB.db, None)
def test_client_server_transaction(self): """Tests the whole, client driven transaction protocol and logic""" client_db = ContentDB(tempfile.NamedTemporaryFile().name) server_db = ContentDB(tempfile.NamedTemporaryFile().name) id1 = dandelion.identity.generate() id2 = dandelion.identity.generate() server_db.add_identities([id1, id2]) server_db.add_messages([Message("fubar"), dandelion.message.create("foo", None, id1, id2), Message("bar")]) self.assertEqual(client_db.message_count, 0) self.assertEqual(client_db.identity_count, 0) self.assertEqual(server_db.message_count, 3) self.assertEqual(server_db.identity_count, 2) with TestServerHelper() as server_helper, TestClientHelper() as client_helper: client_transaction = ClientTransaction(client_helper.sock, client_db) server_transaction = ServerTransaction(server_helper.sock, server_db) """Run the client transactions asynchronously""" server_thread = threading.Thread(target=server_transaction.process) client_thread = threading.Thread(target=client_transaction.process) server_thread.start() client_thread.start() """Wait for client to hang up""" client_thread.join(1) # One sec should be plenty server_thread.join(2 * TIMEOUT) """Make sure the client has updated the db""" self.assertEqual(client_db.message_count, 3) self.assertEqual(server_db.message_count, 3) self.assertEqual(client_db.identity_count, 2) self.assertEqual(server_db.identity_count, 2) self.assertEqual( len([srvmsg for srvmsg in server_db.get_messages()[1] if srvmsg not in client_db.get_messages()[1]]), 0 ) self.assertEqual( len([srvid for srvid in server_db.get_identities()[1] if srvid not in client_db.get_identities()[1]]), 0 )
def test_get_messages(self): """Test the message retrieval from msg id list""" db = ContentDB() m1 = Message('M1') m2 = Message('M2') m3 = Message('M3') db.add_messages([m1, m2, m3]) mlist = db.get_messages() self.assertTrue(m1 in mlist) self.assertTrue(m2 in mlist) self.assertTrue(m3 in mlist) mlist = db.get_messages([m1.id, m3.id]) self.assertTrue(m1 in mlist) self.assertFalse(m2 in mlist) self.assertTrue(m3 in mlist)
def test_do_sync(self): cm = dandelion.config.ConfigManager(self.TEST_FILE) remote_db = ContentDB(tempfile.NamedTemporaryFile().name) local_db = ContentDB(tempfile.NamedTemporaryFile().name) d = dandelion.discoverer.Discoverer(cm.discoverer_config, cm.server_config) d.start() s = dandelion.synchronizer.Synchronizer(d, cm, local_db) s.start() # Start the "remote" server sc = ServerConfig() sc.ip = "127.0.0.1" sc.port = 12345 server = Server(sc, remote_db, None) server.start() # Adding the node to the discoverer should prompt it to start synchronizing. d.add_node("127.0.0.1", 12345, pin=True) msg = local_db.get_messages() self.assertEqual(len(msg[1]), 0) remote_db.add_messages([Message("fubar")]) # Need to wait for the sync to complete... time.sleep(5) # Complete sync, so we have the message locally msg = local_db.get_messages() self.assertEqual(len(msg[1]), 1) # Cleanup s.stop() d.stop() server.stop()
def test_sqlite(self): """Perform some SQLite specific tests.""" tmp = tempfile.NamedTemporaryFile() sqlitedb = ContentDB(tmp.name) self.assertTrue(len(sqlitedb.id), ContentDB._DBID_LENGTH_BYTES) self.assertTrue(ContentDB._TCID_LENGTH_BYTES > 1) self.assertTrue(isinstance(sqlitedb.id, bytes)) self.assertEqual(sqlitedb.message_count, 0) m1 = Message('a') tc1 = sqlitedb.add_messages([m1, Message('b')]) self.assertEqual(sqlitedb.message_count, 2) sqlitedb2 = ContentDB(tmp.name, sqlitedb.id) # New db is the same as old self.assertEqual(sqlitedb.id, sqlitedb2.id) self.assertEqual(sqlitedb.message_count, 2) tc2 = sqlitedb2.add_messages([Message('c')]) self.assertEqual(sqlitedb.message_count, 3) self.assertEqual(sqlitedb2.message_count, 3) self.assertNotEqual(tc1, tc2)
def test_basic_server_transaction(self): """Tests the server transaction protocol and logic""" db = ContentDB(tempfile.NamedTemporaryFile().name) db.add_identities([dandelion.identity.generate(), dandelion.identity.generate()]) tc = db.add_messages([Message("fubar"), Message("foo"), Message("bar")]) with TestServerHelper() as server_helper, TestClientHelper() as client_helper: srv_transaction = ServerTransaction(server_helper.sock, db) test_client = SocketTransaction(client_helper.sock, b"\n") """Run the server transaction in a separate thread to allow client access""" thread = threading.Thread(target=srv_transaction.process) thread.start() """Check greeting from server""" rcv = test_client._read() self.assertEqual(rcv, dandelion.protocol.create_greeting_message(db.id).encode()) """Check response to mdgid list req""" test_client._write(dandelion.protocol.create_message_id_list_request(tc).encode()) rcv = test_client._read() self.assertEqual(rcv, dandelion.protocol.create_message_id_list(tc, None).encode()) """Check response to identityid list req""" test_client._write(dandelion.protocol.create_identity_id_list_request(tc).encode()) rcv = test_client._read() self.assertEqual(rcv, dandelion.protocol.create_identity_id_list(tc, None).encode()) """Check response to mdg req""" test_client._write( dandelion.protocol.create_message_list_request([msg.id for msg in db.get_messages()[1]]).encode() ) rcv = test_client._read() self.assertEqual(rcv, dandelion.protocol.create_message_list(db.get_messages()[1]).encode()) """Check response to identity req""" test_client._write( dandelion.protocol.create_identity_list_request( [id.fingerprint for id in db.get_identities()[1]] ).encode() ) rcv = test_client._read() self.assertEqual(rcv, dandelion.protocol.create_identity_list(db.get_identities()[1]).encode()) """Wait for server (will time out if no requests)""" thread.join(2 * TIMEOUT)
def test_basic_server_transaction(self): """Tests the server transaction protocol and logic""" db = ContentDB() tc = db.add_messages( [Message('fubar'), Message('foo'), Message('bar')]) with TestServerHelper() as server_helper, TestClientHelper( ) as client_helper: srv_transaction = ServerTransaction(server_helper.sock, db) test_client = SocketTransaction(client_helper.sock, b'\n') """Run the server transaction in a separate thread to allow client access""" thread = threading.Thread(target=srv_transaction.process) thread.start() """Check greeting from server""" rcv = test_client._read() self.assertEqual(rcv, Protocol.create_greeting_message(db.id).encode()) """Check response to mdgid list req""" test_client._write( Protocol.create_message_id_list_request(tc).encode()) rcv = test_client._read() self.assertEqual( rcv, Protocol.create_message_id_list(tc, None).encode()) """Check response to mdg req""" test_client._write( Protocol.create_message_list_request( [msg.id for msg in db.get_messages()]).encode()) rcv = test_client._read() self.assertEqual( rcv, Protocol.create_message_list(db.get_messages()).encode()) """Wait for server (will time out if no requests)""" thread.join(2 * TIMEOUT)
def __init__(self, config_file=None): if config_file is None: self._cfg_file_name = 'dandelion.conf' else: self._cfg_file_name = config_file self._server_config = ServerConfig() self._synchronizer_config = SynchronizerConfig() self._id_manager_config = IdentityConfig() self._ui_config = UiConfig() self.read_file() self._content_db = ContentDB()
def test_client_transaction_protocol_violation(self): """Tests the client transaction protocol and logic""" client_db = ContentDB() with TestServerHelper() as server_helper, TestClientHelper( ) as client_helper: client_transaction = ClientTransaction(client_helper.sock, client_db) srv_sock = SocketTransaction(server_helper.sock, b'\n') """Run the client transaction in a separate thread""" thread = threading.Thread(target=client_transaction.process) thread.start() """Send a greeting (should be req. by client)""" srv_sock._write(b'NON PROTOCOL MESSAGE\n') self.assertRaises(socket.timeout, srv_sock._read) """Wait for client to hang up""" thread.join(2 * TIMEOUT)
def test_server_transaction_protocol_violation(self): """Tests the servers response to an invalid request""" db = ContentDB() with TestServerHelper() as server_helper, TestClientHelper( ) as client_helper: srv_transaction = ServerTransaction(server_helper.sock, db) test_client = SocketTransaction(client_helper.sock, b'\n') """Run the server transaction in a separate thread to allow client access""" thread = threading.Thread(target=srv_transaction.process) thread.start() """Check greeting from server""" rcv = test_client._read() self.assertEqual(rcv, Protocol.create_greeting_message(db.id).encode()) """Check response to mdgid list req""" test_client._write(b'NON PROTOCOL MESSAGE\n') self.assertRaises(socket.timeout, test_client._read) """Wait for server (will time out if no requests)""" thread.join(2 * TIMEOUT) server_helper, client_helper = None, None
def __init__(self, config_file=None): self._cfg = self.CONFIG_DEFAULTS.copy() if not config_file: self._config_file = self.DEFAULT_CONFIG_FILE else: self._config_file = config_file if not self._config_file_exists(): self.write_defaults_to_config_file() self.load_config() self._content_db = ContentDB() # store all dict values as attributes so we can access the like this # self.server_time (the same as self_cfg['synchronization']['server_time'] # one downfall is that we cant have settings with the same name even though they are # in different sections. for key in self._cfg: setattr(self, key, self._cfg[key]) for k, v in self._cfg[key].items(): setattr(self.__class__, k, v)
def test_basic_client_transaction(self): """Tests the client transaction protocol and logic""" client_db = ContentDB() srv_db = ContentDB() tc = srv_db.add_messages([Message('fubar'), Message('foo'), Message('bar')]) self.assertEqual(client_db.message_count, 0) self.assertEqual(srv_db.message_count, 3) with TestServerHelper() as server_helper, TestClientHelper() as client_helper: client_transaction = ClientTransaction(client_helper.sock, client_db) srv_sock = SocketTransaction(server_helper.sock, b'\n') """Run the client transaction in a separate thread""" thread = threading.Thread(target=client_transaction.process) thread.start() """Send a greeting (should be req. by client)""" srv_sock._write(Protocol.create_greeting_message(srv_db.id).encode()) """Reading msg id list request""" rcv = srv_sock._read() self.assertEqual(rcv, Protocol.create_message_id_list_request().encode()) """Sending the msg id list""" srv_sock._write(Protocol.create_message_id_list(tc, srv_db.get_messages()).encode()) """Reading msg list request""" rcv = srv_sock._read() self.assertEqual(rcv, Protocol.create_message_list_request([msg.id for msg in srv_db.get_messages()]).encode()) """Sending the msg id list""" srv_sock._write(Protocol.create_message_list(srv_db.get_messages()).encode()) """Wait for client to hang up""" thread.join(2*TIMEOUT) """Make sure the client has updated the db""" self.assertEqual(client_db.message_count, 3) self.assertEqual(srv_db.message_count, 3) self.assertEqual(len([srvmsg for srvmsg in srv_db.get_messages() if srvmsg not in client_db.get_messages()]), 0)
def test_time_cookies(self): """Test the data base time cookies (revision) functionality""" db = ContentDB() # Adding a message first_msg = Message('A Single Message') first_cookie = db.add_messages([first_msg]) self.assertNotEqual(first_cookie, None) # Same message again self.assertEqual(first_cookie, db.add_messages([first_msg])) # New message, new cookie second_msg = Message('Another Single Message') second_cookie = db.add_messages([second_msg]) self.assertNotEqual(second_cookie, None) self.assertNotEqual(second_cookie, first_cookie) # Since first should only be second tc, some_messages = db.messages_since(first_cookie) self.assertNotEqual(some_messages, None) self.assertEqual(tc, second_cookie) self.assertEqual(len(some_messages), 1) self.assertEqual(some_messages[0], second_msg) # Nothing new since last message was added tc, last_messages = db.messages_since(second_cookie) self.assertNotEqual(last_messages, None) self.assertEqual(len(last_messages), 0) self.assertEqual(tc, second_cookie) # Trying some bad input self.assertRaises(TypeError, db.messages_since, 0) self.assertRaises(TypeError, db.messages_since, '') self.assertRaises(TypeError, db.messages_since, 'fubar') self.assertRaises(ValueError, db.messages_since, b'') self.assertRaises(ValueError, db.messages_since, b'1337')
def test_basic_client_transaction(self): """Tests the client transaction protocol and logic""" client_db = ContentDB(tempfile.NamedTemporaryFile().name) srv_db = ContentDB(tempfile.NamedTemporaryFile().name) self.assertEqual(client_db.message_count, 0) srv_db.add_identities([dandelion.identity.generate(), dandelion.identity.generate()]) tc = srv_db.add_messages([Message("fubar"), Message("foo"), Message("bar")]) self.assertEqual(client_db.message_count, 0) self.assertEqual(client_db.identity_count, 0) self.assertEqual(srv_db.message_count, 3) self.assertEqual(srv_db.identity_count, 2) with TestServerHelper() as server_helper, TestClientHelper() as client_helper: client_transaction = ClientTransaction(client_helper.sock, client_db) srv_sock = SocketTransaction(server_helper.sock, b"\n") """Run the client transaction in a separate thread""" thread = threading.Thread(target=client_transaction.process) thread.start() """Send a greeting (should be req. by client)""" srv_sock._write(dandelion.protocol.create_greeting_message(srv_db.id).encode()) """Reading msg id list request""" rcv = srv_sock._read() self.assertEqual(rcv, dandelion.protocol.create_message_id_list_request().encode()) """Sending the msg id list""" srv_sock._write(dandelion.protocol.create_message_id_list(tc, srv_db.get_messages()[1]).encode()) """Reading msg list request""" rcv = srv_sock._read() expected_msgs = ( dandelion.protocol.create_message_list_request([msg.id for msg in srv_db.get_messages()[1]]) .split(" ")[1][:-1] .split(";") ) for msg in expected_msgs: self.assertNotEqual(rcv.find(msg.encode()), -1) """Sending the msg id list""" srv_sock._write(dandelion.protocol.create_message_list(srv_db.get_messages()[1]).encode()) """Reading identity id list request""" rcv = srv_sock._read() self.assertEqual(rcv, dandelion.protocol.create_identity_id_list_request().encode()) """Sending the identity id list""" srv_sock._write(dandelion.protocol.create_identity_id_list(tc, srv_db.get_identities()[1]).encode()) """Reading identity list request""" rcv = srv_sock._read() expected_ids = ( dandelion.protocol.create_identity_list_request([id.fingerprint for id in srv_db.get_identities()[1]]) .split(" ")[1][:-1] .split(";") ) for id in expected_ids: self.assertNotEqual(rcv.find(id.encode()), -1) """Sending the msg id list""" srv_sock._write(dandelion.protocol.create_identity_list(srv_db.get_identities()[1]).encode()) """Wait for client to hang up""" thread.join(2 * TIMEOUT) """Make sure the client has updated the db""" self.assertEqual(client_db.message_count, 3) self.assertEqual(srv_db.message_count, 3) self.assertEqual( len([srvmsg for srvmsg in srv_db.get_messages()[1] if srvmsg not in client_db.get_messages()[1]]), 0 )
def test_message_interface(self): """Test functions relating to storing and recovering messages.""" db = ContentDB(tempfile.NamedTemporaryFile().name) id1 = dandelion.identity.generate() id2 = dandelion.identity.generate() first_msg_list = [Message('A'), Message('B'), Message('III', timestamp=3), dandelion.message.create("W Sender", sender=id1), dandelion.message.create("W Receiver", receiver=id2), dandelion.message.create("W Sender And Receiver", sender=id1, receiver=id2)] # Try to add junk self.assertRaises(TypeError, db.add_messages, None) self.assertRaises(TypeError, db.add_messages, 23) self.assertRaises(AttributeError, db.add_messages, [None]) # Add a message list self.assertEqual(db.message_count, 0) db.add_messages(first_msg_list) self.assertNotEqual(db.message_count, None) self.assertEqual(db.message_count, len(first_msg_list)) self.assertEqual([db.contains_message(m.id) for m in first_msg_list], [True, True, True, True, True, True]) # And for another message list? second_msg_list = [Message('C'), Message('A')] self.assertEqual([db.contains_message(m.id) for m in second_msg_list], [False, True]) # Adding the second message list db.add_messages(second_msg_list) self.assertEqual(db.message_count, 7) self.assertEqual([db.contains_message(m.id) for m in first_msg_list], [True, True, True, True, True, True]) self.assertEqual([db.contains_message(m.id) for m in second_msg_list], [True, True]) # Remove a list db.remove_messages(first_msg_list) self.assertEqual(db.message_count, 1) self.assertEqual([db.contains_message(m.id) for m in first_msg_list], [False, False, False, False, False, False]) self.assertEqual([db.contains_message(m.id) for m in second_msg_list], [True, False]) # Remove same message list db.remove_messages(first_msg_list) self.assertEqual(db.message_count, 1) self.assertEqual([db.contains_message(m.id) for m in first_msg_list], [False, False, False, False, False, False]) self.assertEqual([db.contains_message(m.id) for m in second_msg_list], [True, False]) # Remove all messages db.remove_messages() self.assertEqual(db.message_count, 0) self.assertEqual([db.contains_message(m.id) for m in first_msg_list], [False, False, False, False, False, False]) self.assertEqual([db.contains_message(m.id) for m in second_msg_list], [False, False])
def test_remote_cookies(self): """Test the remote time cookie interface""" db = ContentDB(tempfile.NamedTemporaryFile().name) remotefp_1 = b"1337" remotefp_2 = b"2342" remotetc_1 = b"1" remotetc_2 = b"2" # No time cookie for the db yet self.assertIsNone(db.get_last_time_cookie(remotefp_1)) # Initial tc db.update_last_time_cookie(remotefp_1, remotetc_1) self.assertEqual(db.get_last_time_cookie(remotefp_1), remotetc_1) # Same tc again db.update_last_time_cookie(remotefp_1, remotetc_1) self.assertEqual(db.get_last_time_cookie(remotefp_1), remotetc_1) # Second tc db.update_last_time_cookie(remotefp_1, remotetc_2) self.assertEqual(db.get_last_time_cookie(remotefp_1), remotetc_2) # Second db db.update_last_time_cookie(remotefp_2, remotetc_1) self.assertEqual(db.get_last_time_cookie(remotefp_1), remotetc_2) self.assertEqual(db.get_last_time_cookie(remotefp_2), remotetc_1)
def test_list_message_interface(self): """Test functions relating to storing and recovering single messages""" db = ContentDB() first_msg_list = [Message('A'), Message('B')] # Add a message list db.add_messages(first_msg_list) self.assertNotEqual(db.message_count, None) self.assertEqual(db.message_count, len(first_msg_list)) self.assertEqual(db.contains_messages(first_msg_list), [True, True]) # And for another message list? second_msg_list = [Message('C'), Message('A')] self.assertEqual(db.contains_messages(second_msg_list), [False, True]) # Adding the second message list db.add_messages(second_msg_list) self.assertEqual(db.message_count, 3) self.assertEqual(db.contains_messages(first_msg_list), [True, True]) self.assertEqual(db.contains_messages(second_msg_list), [True, True]) # Remove a list db.remove_messages(first_msg_list) self.assertEqual(db.message_count, 1) self.assertEqual(db.contains_messages(first_msg_list), [False, False]) self.assertEqual(db.contains_messages(second_msg_list), [True, False]) # Remove same message list db.remove_messages(first_msg_list) self.assertEqual(db.message_count, 1) self.assertEqual(db.contains_messages(first_msg_list), [False, False]) self.assertEqual(db.contains_messages(second_msg_list), [True, False]) # Remove all messages db.remove_messages() self.assertEqual(db.message_count, 0) self.assertEqual(db.contains_messages(first_msg_list), [False, False]) self.assertEqual(db.contains_messages(second_msg_list), [False, False])
class ConfigManager: def __init__(self, config_file='dandelion.conf'): self._cfg_file_name = config_file self._server_config = ServerConfig() self._synchronizer_config = SynchronizerConfig() self._discoverer_config = DiscovererConfig() self._id_manager_config = IdentityConfig() self._ui_config = UiConfig() self.read_file() self._content_db = ContentDB(self._server_config.db_file) if self._id_manager_config.my_id is not None and not self._content_db.contains_identity(decode_b64_bytes(self._id_manager_config.my_id.encode())) : print("WARNING! Bad or non existing ID requested in config. Requested:", self._id_manager_config.my_id) self._id_manager_config.my_id = None if self._id_manager_config.my_id is not None: fp = decode_b64_bytes(self._id_manager_config.my_id.encode()) try: self._identity = self._content_db.get_private_identity(fp) print("My claimed ID:", self._id_manager_config.my_id) return except ValueError: pass self._identity = dandelion.identity.generate() self._content_db.add_private_identity(self._identity) id_str = encode_b64_bytes(self._identity.fingerprint).decode() self._id_manager_config.my_id = id_str @property def config_file(self): return self._cfg_file_name @property def server_config(self): return self._server_config @property def synchronizer_config(self): return self._synchronizer_config @property def discoverer_config(self): return self._discoverer_config @property def identity_manager_config(self): return self._id_manager_config @property def ui_config(self): return self._ui_config @property def content_db(self): return self._content_db @property def identity(self): return self._identity def write_file(self): confparser = configparser.ConfigParser() self._server_config.store(confparser) self._ui_config.store(confparser) self._id_manager_config.store(confparser) self._discoverer_config.store(confparser) with open(self._cfg_file_name, 'w') as configfile: confparser.write(configfile) def read_file(self): confparser = configparser.ConfigParser() confparser.read(self._cfg_file_name) self._server_config.load(confparser) self._ui_config.load(confparser) self._id_manager_config.load(confparser) self._discoverer_config.load(confparser)
def test_identity_info_nick(self): """"Test getting and setting nickname""" db = ContentDB(tempfile.NamedTemporaryFile().name) id_a = dandelion.identity.generate() db.add_identities([id_a]) # Check for empty nicks self.assertIsNone(db.get_nick(b'1337')) self.assertIsNone(db.get_nick(id_a.fingerprint)) # Test setting a nick db.set_nick(id_a.fingerprint, "me") self.assertEqual(db.get_nick(id_a.fingerprint), "me") db.set_nick(id_a.fingerprint, "you") self.assertEqual(db.get_nick(id_a.fingerprint), "you") db.set_nick(id_a.fingerprint, None) self.assertIsNone(db.get_nick(id_a.fingerprint)) # Trying some bad input self.assertRaises(TypeError, db.get_nick, 0) self.assertRaises(TypeError, db.get_nick, '') self.assertRaises(TypeError, db.get_nick, None) self.assertRaises(ValueError, db.get_nick, b'') self.assertRaises(TypeError, db.set_nick, id_a.fingerprint, 0) self.assertRaises(TypeError, db.set_nick, id_a.fingerprint, b'') self.assertRaises(TypeError, db.set_nick, None, "qwerty") self.assertRaises(TypeError, db.set_nick, 0, "qwerty") self.assertRaises(TypeError, db.set_nick, '', "qwerty") self.assertRaises(ValueError, db.set_nick, b'', "qwerty")
def test_private_identities(self): """Test private id interface""" db = ContentDB(tempfile.NamedTemporaryFile().name) id_priv = dandelion.identity.generate() id_pub = dandelion.identity.generate().public_identity() # Add junk self.assertRaises(TypeError, db.add_private_identity, None) self.assertRaises(ValueError, db.add_private_identity, id_pub) # Add, get, remove db.add_private_identity(id_priv) id = db.get_private_identity(id_priv.fingerprint) self.assertEqual(id_priv.fingerprint, id.fingerprint) self.assertEqual(id_priv, id) self.assertTrue(IdentityInfo(db, id).is_private()) db.remove_private_identity(id_priv, keep_public_identity=False) self.assertFalse(db.contains_identity(id_priv.fingerprint)) # Add and remove private, but keep public db.add_private_identity(id_priv) db.remove_private_identity(id_priv, keep_public_identity=True) self.assertTrue(db.contains_identity(id_priv.fingerprint)) self.assertFalse(IdentityInfo(db, db.get_identities([id_priv.fingerprint])[1][0]).is_private()) self.assertRaises(ValueError, db.get_private_identity, id_priv.fingerprint)
def test_time_cookies(self): """Test the data base time cookies (revision) functionality.""" db = ContentDB(tempfile.NamedTemporaryFile().name) # Adding a message first_msg = Message('A Single Message') first_cookie = db.add_messages([first_msg]) self.assertNotEqual(first_cookie, None) self.assertTrue(isinstance(first_cookie, bytes)) self.assertTrue((db.get_last_time_cookie(None) is None) or (db.get_last_time_cookie(None) == first_cookie)) # Same message again self.assertEqual(first_cookie, db.add_messages([first_msg])) # New message, new cookie id1 = dandelion.identity.generate() id2 = dandelion.identity.generate() second_msg = dandelion.message.create('Another Single Message', sender=id1, receiver=id2) second_cookie = db.add_messages([second_msg]) self.assertNotEqual(second_cookie, None) self.assertNotEqual(second_cookie, first_cookie) self.assertTrue((db.get_last_time_cookie(None) is None) or (db.get_last_time_cookie(None) == second_cookie)) # Since first should only be second tc, some_messages = db.get_messages(time_cookie=first_cookie) self.assertNotEqual(some_messages, None) self.assertEqual(tc, second_cookie) self.assertEqual(len(some_messages), 1) self.assertEqual(some_messages[0], second_msg) # Nothing new since last message was added tc, last_messages = db.get_messages(time_cookie=second_cookie) self.assertNotEqual(last_messages, None) self.assertEqual(len(last_messages), 0) self.assertEqual(tc, second_cookie) # Same id gives same tc self.assertEqual(second_cookie, db.add_messages([first_msg])) # New identity, new cookie identity = dandelion.identity.generate() third_cookie = db.add_identities([identity]) self.assertNotEqual(third_cookie, None) self.assertNotEqual(third_cookie, second_cookie) self.assertTrue(db.get_last_time_cookie() == third_cookie) # Trying some bad input self.assertRaises(TypeError, db.get_messages, [], 0) self.assertRaises(TypeError, db.get_messages, [], '') self.assertRaises(TypeError, db.get_messages, [], 'fubar') self.assertRaises(ValueError, db.get_messages, [], b'') self.assertRaises(ValueError, db.get_messages, [], b'1337')
def test_identity_interface(self): """Test functions relating to storing and recovering identities.""" db = ContentDB(tempfile.NamedTemporaryFile().name) _, idlist = db.get_identities() self.assertEqual(idlist, []) id_a = dandelion.identity.generate() id_b = dandelion.identity.generate() first_id_list = [id_a, id_b] # Try to add junk self.assertRaises(TypeError, db.add_identities, None) self.assertRaises(TypeError, db.add_identities, 23) self.assertRaises(AttributeError, db.add_identities, [None]) # Add a message list self.assertEqual(db.identity_count, 0) db.add_identities(first_id_list) self.assertNotEqual(db.identity_count, None) self.assertEqual(db.identity_count, len(first_id_list)) self.assertEqual([db.contains_identity(id.fingerprint) for id in first_id_list], [True, True]) # And for another message list? second_id_list = [dandelion.identity.generate(), id_a] self.assertEqual([db.contains_identity(id.fingerprint) for id in second_id_list], [False, True]) # Adding the second message list db.add_identities(second_id_list) self.assertEqual(db.identity_count, 3) self.assertEqual([db.contains_identity(id.fingerprint) for id in first_id_list], [True, True]) self.assertEqual([db.contains_identity(id.fingerprint) for id in second_id_list], [True, True]) # Remove a list db.remove_identities(first_id_list) self.assertEqual(db.identity_count, 1) self.assertEqual([db.contains_identity(id.fingerprint) for id in first_id_list], [False, False]) self.assertEqual([db.contains_identity(id.fingerprint) for id in second_id_list], [True, False]) # Remove same message list db.remove_identities(first_id_list) self.assertEqual(db.identity_count, 1) self.assertEqual([db.contains_identity(id.fingerprint) for id in first_id_list], [False, False]) self.assertEqual([db.contains_identity(id.fingerprint) for id in second_id_list], [True, False]) # Remove all messages db.remove_identities() self.assertEqual(db.identity_count, 0) self.assertEqual([db.contains_identity(id.fingerprint) for id in first_id_list], [False, False]) self.assertEqual([db.contains_identity(id.fingerprint) for id in second_id_list], [False, False])