def testSaveAndLoad(self): '''Test the manual saving and loading of the database''' dbFilename = "test.db" # Check that filename we want to use doesn't exist self.assertFalse(os.path.exists(dbFilename), "File %s shouldn't exist!" % dbFilename) db = supersimpledb.MurmeliDb(dbFilename) self.assertTrue( db.addOrUpdateProfile({ "torid": "1234567890ABCDEF", "displayName": "Lester", "name": "Lying Lion" })) db.saveToFile() # Check that file exists now self.assertTrue(os.path.exists(dbFilename), "File %s should exist now!" % dbFilename) db = None loaded = supersimpledb.MurmeliDb(dbFilename) self.assertEqual(len(loaded.getProfiles()), 1, "Profiles should have one entry") prof1 = loaded.getProfiles()[0] self.assertEqual(prof1['name'], 'Lying Lion', "Name should be set") self.assertEqual(prof1['displayName'], 'Lester', "displayName should be set") # Delete file again os.remove(dbFilename) # Check that file doesn't exist any more self.assertFalse(os.path.exists(dbFilename), "File %s shouldn't exist!" % dbFilename)
def testOutbox(self): '''Test the storage and retrieval of messages in the outbox''' db = supersimpledb.MurmeliDb() DbI.setDb(db) self.assertEqual(len(DbI.getOutboxMessages()), 0, "Outbox should be empty") # Add profile for this the target recipient DbI.updateProfile("ABC312", {"keyid":"ZYXW987", "status":"trusted", "name":"Best friend"}) # add one message to the outbox DbI.addToOutbox(ExampleMessage(["ABC312"], "Doesn't matter really what the message is")) self.assertEqual(len(DbI.getOutboxMessages()), 1, "Outbox should have one message") self.checkMessageIndexes(DbI.getOutboxMessages()) DbI.addToOutbox(ExampleMessage(["ABC312"], "A second message")) self.assertEqual(len(DbI.getOutboxMessages()), 2, "Outbox should have 2 messages") self.checkMessageIndexes(DbI.getOutboxMessages()) self.assertTrue(DbI.deleteFromOutbox(0)) self.assertEqual(len(DbI.getOutboxMessages()), 1, "Outbox should only have 1 message (1 empty)") nonEmptyMessages = DbI.getOutboxMessages() self.assertEqual(len(nonEmptyMessages), 1, "Outbox should only have 1 non-empty message") self.assertEqual(nonEmptyMessages[0]["_id"], 1, "Message 0 should have index 1") # See if index of third message is properly assigned DbI.addToOutbox(ExampleMessage(["ABC312"], "A third message")) self.assertEqual(len(DbI.getOutboxMessages()), 2, "Outbox should have 2 messages again") self.assertEqual(DbI.getOutboxMessages()[0]["_id"], 1, "Message 0 should have index 1") self.assertEqual(DbI.getOutboxMessages()[1]["_id"], 2, "Message 1 should have index 2") # done DbI.releaseDb()
def testBasics(self): '''Testing the basics of the interface with a super-simple db''' # Create new, empty database without file-storage db = supersimpledb.MurmeliDb() DbI.setDb(db) # Lists should be empty self.assertEqual(len(DbI.getMessageableProfiles()), 0, "Should be 0 messageables") self.assertEqual(len(DbI.getTrustedProfiles()), 0, "Should be 0 trusted") self.assertFalse(DbI.hasFriends(), "Shouldn't have any friends") # Store some profiles DbI.updateProfile("abc123", {"keyid":"ZYXW987", "status":"self", "name":"That's me"}) DbI.updateProfile("def123", {"keyid":"JKLM987", "status":"trusted", "name":"Jimmy"}) DbI.updateProfile("ghi123", {"keyid":"TUVWX987", "status":"untrusted", "name":"Dave"}) # Get my ids self.assertEqual(DbI.getOwnTorid(), "abc123", "Should find correct tor id") self.assertEqual(DbI.getOwnKeyid(), "ZYXW987", "Should find correct key id") # Get all profiles self.assertEqual(len(DbI.getProfiles()), 3, "Should be three profiles in total") self.assertEqual(len(DbI.getMessageableProfiles()), 2, "Should be two messageables") self.assertEqual(len(DbI.getTrustedProfiles()), 1, "Should be one trusted") self.assertEqual(DbI.getTrustedProfiles()[0]['displayName'], "Jimmy", "Jimmy should be trusted") self.assertTrue(DbI.hasFriends(), "Should have friends") # Update an existing profile DbI.updateProfile("def123", {"displayName":"Slippin' Jimmy"}) self.assertEqual(len(DbI.getTrustedProfiles()), 1, "Should still be one trusted") self.assertEqual(DbI.getTrustedProfiles()[0]['displayName'], "Slippin' Jimmy", "Slippin' Jimmy should be trusted") # Finished DbI.releaseDb()
def testConversationIds(self): '''Test the increment of conversation ids''' db = supersimpledb.MurmeliDb() DbI.setDb(db) # If we start with an empty db, the id should start at 1 for i in range(100): self.assertEqual(DbI.getNewConversationId(), i+1, "id should be 1 more than i") # Add profiles for us and a messages sender DbI.updateProfile("F055", {"keyid":"ZYXW987", "status":"self", "name":"That's me"}) DbI.updateProfile("ABC312", {"keyid":"ZYXW987", "status":"trusted", "name":"Best friend"}) # Add an inbox message with a conversation id DbI.addToInbox({"messageBody":"Gorgonzola and Camembert", "timestamp":"early 2017", "fromId":"ABC312"}) # Get this message again, and check the conversation id, should be 101 msg0 = DbI.getInboxMessages()[0] self.assertEqual(msg0.get("conversationid", 0), 101, "Id should now be 101") # Add another message with the parent hash referring to the first one DbI.addToInbox({"messageBody":"Fried egg sandwich", "timestamp":"middle 2017", "fromId":"ABC312", "parentHash":'40e98bae7a811c23b59b89bd0f11b0a0'}) msg1 = DbI.getInboxMessages()[0] self.assertTrue("Fried egg" in msg1.get("messageBody", ""), "Fried egg should be first") self.assertEqual(msg1.get("conversationid", 0), 101, "Id should now also be 101") # Add another message with an unrecognised parent hash DbI.addToInbox({"messageBody":"Red wine and chocolate", "timestamp":"late 2017", "fromId":"ABC312", "parentHash":'ff3'}) msg2 = DbI.getInboxMessages()[0] self.assertTrue("Red wine" in msg2.get("messageBody", ""), "Red wine should be first") self.assertEqual(msg2.get("conversationid", 0), 102, "Id should take 102") # done DbI.releaseDb()
def testSearching(self): '''Test the searching of the inbox''' db = supersimpledb.MurmeliDb() DbI.setDb(db) # Add some inbox messages with different text DbI.addToInbox({"messageBody":"There were some children playing in the park", "timestamp":"", "fromId":"ABC312"}) DbI.addToInbox({"messageBody":"There was a child playing in the castle", "timestamp":"", "fromId":"ABC312"}) DbI.addToInbox({"messageBody":"Children were making far too much noise", "timestamp":"", "fromId":"ABC312"}) # Get this message again, and check the conversation id, should be 101 self.assertEqual(len(DbI.getInboxMessages()), 3, "Inbox has 3") search1 = DbI.searchInboxMessages("child") self.assertEqual(len(search1), 2, "Only 2 match 'child'") search2 = DbI.searchInboxMessages("children") self.assertEqual(len(search2), 1, "Only 1 matches 'children'") search3 = DbI.searchInboxMessages("") self.assertEqual(len(search3), 3, "All match empty search string") search4 = DbI.searchInboxMessages("hild") self.assertEqual(len(search4), 3, "All match 'hild'") search5 = DbI.searchInboxMessages("noisy") self.assertEqual(len(search5), 0, "None are noisy") search6 = DbI.searchInboxMessages("Child") self.assertEqual(len(search6), 1, "Only 1 matches 'Child'") # done DbI.releaseDb()
def testMurmeliMessageBoxes(self): '''Test the Murmeli specifics of messages in the inbox and outbox''' # Create new, empty Murmeli database without file-storage db = supersimpledb.MurmeliDb() self.assertEqual(db.getNumTables(), 2, "Database should have two empty tables at the start") self.assertEqual(len(db.getInbox()), 0, "Inbox should be empty at the start") # Add a message to the inbox db.addMessageToInbox({"something": "amazing"}) self.assertEqual(len(db.getInbox()), 1, "Inbox should now have one message") self.assertEqual(len(db.getOutbox()), 0, "Outbox should be empty") # Add a message to the outbox db.addMessageToOutbox({"uncertainty": 3.4}) self.assertEqual(len(db.getInbox()), 1, "Inbox should have one message") self.assertEqual(len(db.getOutbox()), 1, "Outbox should have one message") self.assertEqual(db.getOutbox()[0]['_id'], 0, "First message has index 0") # Delete message from outbox self.assertTrue(db.deleteFromOutbox(0)) self.assertEqual(len(db.getOutbox()), 0, "Outbox should be empty") # Add another and check its id db.addMessageToOutbox({"another": "tantalising factlet"}) self.assertEqual(len(db.getOutbox()), 1, "Outbox should have one message") msg = db.getOutbox()[0] self.assertEqual(msg['_id'], 1, "First empty message has index 1 now") self.assertTrue(db.deleteFromOutbox(msg['_id'])) self.assertEqual(len(db.getOutbox()), 0, "Outbox should be empty again")
def testMurmeliProfiles(self): '''Test the Murmeli specifics of profiles''' db = supersimpledb.MurmeliDb() self.assertFalse(db.addOrUpdateProfile({"halloumi": "cheese"})) # no torid given # Add a new profile self.assertTrue( db.addOrUpdateProfile({ "torid": "1234567890ABCDEF", "halloumi": "cheese" })) self.assertEqual(len(db.getProfiles()), 1, "Profiles should have one entry") prof1 = db.getProfiles()[0] self.assertEqual(prof1['halloumi'], 'cheese', "Profile should be cheesy") self.assertEqual(prof1['name'], '1234567890ABCDEF', "Id should be used as name") # Update the profile to give a name self.assertTrue( db.addOrUpdateProfile({ "torid": "1234567890ABCDEF", "name": "Sylvester" })) prof1 = db.getProfiles()[0] self.assertEqual(prof1['halloumi'], 'cheese', "Profile should still be cheesy") self.assertEqual(prof1['name'], 'Sylvester', "Name should be given now") self.assertEqual(prof1['displayName'], 'Sylvester', "displayName should also be given now") self.assertTrue( db.addOrUpdateProfile({ "torid": "1234567890ABCDEF", "displayName": "cat", "appetite": "substantial" })) prof1 = db.getProfiles()[0] self.assertEqual(prof1['name'], 'Sylvester', "Name should be set") self.assertEqual(prof1['displayName'], 'cat', "displayName should be cat now") self.assertEqual(prof1['appetite'], 'substantial', "additional fields also set") self.assertEqual(len(db.getProfiles()), 1, "Profiles should still have only one entry") self.assertEqual(len(db.getProfiles()[0]), 5, "Profile should have five elements now") self.assertIsNone(db.getProfile(None)) self.assertIsNone(db.getProfile("")) self.assertIsNone(db.getProfile("lump")) self.assertIsNone(db.getProfile("1234567890ABCDEE")) self.assertIsNone(db.getProfile("1234567890abcdef")) self.assertIsNotNone(db.getProfile("1234567890ABCDEF"), "profile should be found by id") self.assertEqual( db.getProfile("1234567890ABCDEF")['displayName'], 'cat', "displayName should be cat now")
def testLoadingWithoutEmptyRows(self): '''Test that empty rows are ignored when loading the database from file''' dbFilename = "test.db" # Check that filename we want to use doesn't exist self.assertFalse(os.path.exists(dbFilename), "File %s shouldn't exist!" % dbFilename) db = supersimpledb.MurmeliDb(dbFilename) db.addMessageToOutbox({ "sender": "me", "recipient": "you", "messageBody": "Here is my message" }) db.addMessageToOutbox({ "sender": "me", "recipient": "you", "messageBody": "Here is another message" }) self.assertEqual(len(db.getOutbox()), 2, "Two messages in outbox") self.checkMessageIndexes(db.getOutbox()) self.assertTrue(db.deleteFromOutbox(0), "Delete of first message should work") self.assertEqual(len(db.getOutbox()), 1, "Now just 1 message in outbox") self.assertEqual(db.getOutbox()[0]["_id"], 1, "Message 0 should have index 1") db.saveToFile() # Check that file exists now self.assertTrue(os.path.exists(dbFilename), "File %s should exist now!" % dbFilename) db = None loaded = supersimpledb.MurmeliDb(dbFilename) self.assertEqual(len(loaded.getOutbox()), 1, "Should now be only 1 message in outbox") self.checkMessageIndexes(loaded.getOutbox()) # Delete file again os.remove(dbFilename) # Check that file doesn't exist any more self.assertFalse(os.path.exists(dbFilename), "File %s shouldn't exist!" % dbFilename)
def testReadLocking(self): '''Test that modifications of the Murmelidb are correctly handled by snapshotting''' # Create new, empty Murmeli database without file-storage db = supersimpledb.MurmeliDb() self.assertEqual(len(db.getInbox()), 0, "Inbox should be empty at the start") db.addMessageToInbox({"something": "amazing"}) self.assertEqual(len(db.getInbox()), 1, "Inbox should now have one message") # Without locking, access to the table will follow appends inbox = db.getInbox() db.addMessageToInbox({"another": "interesting thing"}) self.assertEqual(len(inbox), 1, "Inbox should now still have one message") self.assertEqual(len(db.getInbox()), 2, "Real Inbox should now have 2 message")
def testAvatars(self): '''Test the loading, storing and exporting of binary avatar images''' db = supersimpledb.MurmeliDb() DbI.setDb(db) inputPath = "testdata/example-avatar.jpg" outPath = "cache/avatar-deadbeef.jpg" if os.path.exists(outPath): os.remove(outPath) os.makedirs('cache', exist_ok=True) self.assertFalse(os.path.exists(outPath)) DbI.updateProfile("deadbeef", {"profilepicpath":inputPath}) # Output file still shouldn't exist, we didn't give a path to write picture to self.assertFalse(os.path.exists(outPath)) DbI.updateProfile("deadbeef", {"profilepicpath":inputPath}, "cache") # Output file should exist now self.assertTrue(os.path.exists(outPath)) # TODO: Any way to compare input with output? They're not the same. DbI.releaseDb()
def testAdminTable(self): '''Test the storage and retrieval from the admin table''' db = supersimpledb.MurmeliDb() self.assertIsNone(db.getAdminValue(None)) self.assertIsNone(db.getAdminValue("crocodile")) self.assertIsNone(db.getAdminValue("elephant")) # Add a value db.setAdminValue("elephant", 18.1) self.assertIsNone(db.getAdminValue("crocodile")) self.assertIsNotNone(db.getAdminValue("elephant")) self.assertEqual(db.getAdminValue("elephant"), 18.1, "Value should be read again") # Change it db.setAdminValue("elephant", "coelecanth") self.assertIsNone(db.getAdminValue("crocodile")) self.assertNotEqual(db.getAdminValue("elephant"), 18.1, "Value should have changed") self.assertEqual(db.getAdminValue("elephant"), "coelecanth", "Value should be read again")