Beispiel #1
0
 def setUp(self):
     #createDB = not os.path.isfile(SQL_DB)
     self.db = SimpleMetadataDB(CREATE_SQL_FILE, SQL_DB)
     self.underTest = MetadataDBHandler(self.db)
Beispiel #2
0
 def setUp(self):
     #createDB = not os.path.isfile(SQL_DB)
     self.db = SimpleMetadataDB(CREATE_SQL_FILE, SQL_DB)
     self.underTest = MetadataDBHandler(self.db)
Beispiel #3
0
class TestMetadataDBHandler(unittest.TestCase):
    _keypair1 = generate_keypair()
    aPermId = str(_keypair1.pub().get_der())
    _keypair2 = generate_keypair()
    anotherPermId = str(_keypair2.pub().get_der())

    def setUp(self):
        #createDB = not os.path.isfile(SQL_DB)
        self.db = SimpleMetadataDB(CREATE_SQL_FILE, SQL_DB)
        self.underTest = MetadataDBHandler(self.db)
    
    def tearDown(self):
        self.db.close()
        #if os.path.isfile(SQL_DB) :
            #os.remove(SQL_DB)
        
        
    
    def testInitHandler(self):
        self.assertTrue(self.underTest is not None)
        
    def testSingleton(self):
        
        instance1 = MetadataDBHandler.getInstance()
        instance2 = MetadataDBHandler.getInstance()
        self.assertTrue(instance1 is instance2)
        
    def testInsertNewMetadataSubs(self):
        metadataDTO = MockMetadataDTO(["nld","ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)
        
        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;" 
        results = self.db.fetchall(testquery, (bin2str(metadataDTO.channel),bin2str(metadataDTO.infohash)))
        
        self.assertTrue(len(results) == 1)
        tupl = results[0] 
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(bin2str(metadataDTO.channel),tupl[1])
        self.assertEquals(bin2str(metadataDTO.infohash),tupl[2])
        self.assertEquals(metadataDTO.description, tupl[3])
        self.assertEquals(metadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(metadataDTO.signature), tupl[5])
        
        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"
        
        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(2,len(subtitles))
        
        for lang in ("ita", "nld"):
            found = False
            foundSub = None
            for subtuple in subtitles:
                if subtuple[1] == lang:
                    found = True
                    foundSub = subtuple
                    break
                
            self.assertTrue(found)
            self.assertEquals(bin2str(metadataDTO.getSubtitle(lang).checksum), foundSub[3])
            
    
    def testGetMetadataInstance(self):
        metadataDTO = MockMetadataDTO(["nld","ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)
        
        retrievedMetadata = self.underTest.getMetadata(metadataDTO.channel,
                                                       metadataDTO.infohash)
        
        self.assertFalse(retrievedMetadata is None)
        self.assertFalse(retrievedMetadata is metadataDTO)
        self.assertEquals(metadataDTO,retrievedMetadata)
        
        
            
    
    def testInsertNewMetadataNoSubs(self):
        metadataDTO = MockMetadataDTO([])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)
        
        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;" 
            
        channel = bin2str(metadataDTO.channel)
        infohash = bin2str(metadataDTO.infohash)
        results = self.db.fetchall(testquery, (channel,infohash))
        
        self.assertTrue(len(results) == 1)
        tupl = results[0] 
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(channel,tupl[1])
        self.assertEquals(infohash,tupl[2])
        self.assertEquals(metadataDTO.description, tupl[3])
        self.assertEquals(metadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(metadataDTO.signature), tupl[5])
        
        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"
        
        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(0,len(subtitles))
    
    def testUpdateExistingWithOlder(self):
        
        
        metadataDTO = MockMetadataDTO(["nld", "ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)
        
        olderMetadataDTO = copy.copy(metadataDTO)
        olderMetadataDTO.timestamp = 1 #*really* old
        olderMetadataDTO.sign(olderMetadataDTO._keypair)
    
        self.underTest.insertMetadata(olderMetadataDTO)
        
        #assert the the older did not replace the newer
        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;" 
        channel = bin2str(metadataDTO.channel)
        infohash = bin2str(metadataDTO.infohash)
        results = self.db.fetchall(testquery, (channel,infohash))
        
        self.assertTrue(len(results) == 1)
        tupl = results[0] 
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(channel,tupl[1])
        self.assertEquals(infohash,tupl[2])
        self.assertEquals(metadataDTO.description, tupl[3])
        self.assertEquals(metadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(metadataDTO.signature), tupl[5])
        
        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"
        
        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(2,len(subtitles))
        
        for lang in ("ita", "nld"):
            found = False
            foundSub = None
            for subtuple in subtitles:
                if subtuple[1] == lang:
                    found = True
                    foundSub = subtuple
                    break
                
            self.assertTrue(found)
            self.assertEquals(bin2str(metadataDTO.getSubtitle(lang).checksum), foundSub[3])
        
        
    def testUpdateExistingWithNewerSameSub(self):
        metadataDTO = MockMetadataDTO(["nld", "ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)
        
        newerMetadataDTO = copy.copy(metadataDTO)
        newerMetadataDTO.description = u"I'm newer!"
        newerMetadataDTO.timestamp = newerMetadataDTO.timestamp +1 #newer 
        newerMetadataDTO.sign(newerMetadataDTO._keypair)
        
        
        self.underTest.insertMetadata(newerMetadataDTO)
        
        #assert the the older has been replaced
        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;" 
        
        channel = bin2str(metadataDTO.channel)
        infohash = bin2str(metadataDTO.infohash)
        results = self.db.fetchall(testquery, (channel,infohash))
        
        self.assertTrue(len(results) == 1)
        tupl = results[0] 
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(channel,tupl[1])
        self.assertEquals(infohash,tupl[2])
        self.assertEquals(newerMetadataDTO.description, tupl[3])
        self.assertEquals(newerMetadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(newerMetadataDTO.signature), tupl[5])
        
        #testing subtitles with the old once since they are not changed
        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"
        
        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(2,len(subtitles))
        
        for lang in ("ita", "nld"):
            found = False
            foundSub = None
            for subtuple in subtitles:
                if subtuple[1] == lang:
                    found = True
                    foundSub = subtuple
                    break
                
            self.assertTrue(found)
            self.assertEquals(bin2str(metadataDTO.getSubtitle(lang).checksum), foundSub[3])
    
    
    
    def testUpdateExistingWithNewerNewSubs(self):
        metadataDTO = MockMetadataDTO(["nld", "ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)
        
        newerMetadataDTO = MockMetadataDTO(["nld","ita","eng"])
        newerMetadataDTO.channel = metadataDTO.channel
        newerMetadataDTO.infohash = metadataDTO.infohash
        newerMetadataDTO._keypair = metadataDTO._keypair
        newerMetadataDTO.timestamp = metadataDTO.timestamp +1 #newer 
        newerMetadataDTO.sign(newerMetadataDTO._keypair)
        
        
        self.underTest.insertMetadata(newerMetadataDTO)
        
        #assert the the older has been replaced
        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;" 
            
        channel = bin2str(metadataDTO.channel)
        infohash = bin2str(metadataDTO.infohash)
        results = self.db.fetchall(testquery, (channel,infohash))
        
        self.assertTrue(len(results) == 1)
        tupl = results[0] 
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(channel,tupl[1])
        self.assertEquals(infohash,tupl[2])
        self.assertEquals(newerMetadataDTO.description, tupl[3])
        self.assertEquals(newerMetadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(newerMetadataDTO.signature), tupl[5])
        
        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"
        
        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(3,len(subtitles))
        
        for lang in ("ita", "nld","eng"):
            found = False
            foundSub = None
            for subtuple in subtitles:
                if subtuple[1] == lang:
                    found = True
                    foundSub = subtuple
                    break
                
            self.assertTrue(found)
            self.assertEquals(bin2str(newerMetadataDTO.getSubtitle(lang).checksum), foundSub[3])
    
    def testUpdateExistingWithNewerSubsDeleted(self):
        metadataDTO = MockMetadataDTO(["nld", "ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)
        
        newerMetadataDTO = MockMetadataDTO(["nld","eng"])
        newerMetadataDTO.channel = metadataDTO.channel
        newerMetadataDTO.infohash = metadataDTO.infohash
        newerMetadataDTO._keypair = metadataDTO._keypair
        newerMetadataDTO.timestamp = metadataDTO.timestamp +1 #newer 
        newerMetadataDTO.sign(newerMetadataDTO._keypair)
        
        
        self.underTest.insertMetadata(newerMetadataDTO)
        
        #assert the the older has been replaced
        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;" 
        channel = bin2str(metadataDTO.channel)
        infohash = bin2str(metadataDTO.infohash)
        results = self.db.fetchall(testquery, (channel,infohash))
        
        self.assertTrue(len(results) == 1)
        tupl = results[0] 
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(channel,tupl[1])
        self.assertEquals(infohash,tupl[2])
        self.assertEquals(newerMetadataDTO.description, tupl[3])
        self.assertEquals(newerMetadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(newerMetadataDTO.signature), tupl[5])
        
        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"
        
        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(2,len(subtitles))
        
        for lang in ("nld","eng"):
            found = False
            foundSub = None
            for subtuple in subtitles:
                if subtuple[1] == lang:
                    found = True
                    foundSub = subtuple
                    break
                
            self.assertTrue(found)
            self.assertEquals(bin2str(newerMetadataDTO.getSubtitle(lang).checksum), foundSub[3])
    
    def testGetAllMetadataForInfohashEmtpy(self):
        metadataDTO = MockMetadataDTO(["nld", "ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)
        
        
        otherinfohash = _generateFakeInfohash()
        
        results = self.underTest.getAllMetadataForInfohash(otherinfohash)
        self.assertTrue(len(results)==0)
    
    def testGetAllMetadataForInfohashNotEmpty(self):
        infohash = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld", "ita"],infohash)
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)
        
        #different channels since the channel is automatically
        #generated by MockMetadata DTO
        metadataDTO2 = MockMetadataDTO(["rus", "eng"],infohash)
        metadataDTO2.sign(metadataDTO2._keypair)
        self.underTest.insertMetadata(metadataDTO2)
        
        #a 3rd instance with different channel and infohash
        metadataDTO3 = MockMetadataDTO(["rus", "spa", "jpn"])
        metadataDTO3.sign(metadataDTO3._keypair)
        self.underTest.insertMetadata(metadataDTO3)
        
        results = self.underTest.getAllMetadataForInfohash(infohash)
        self.assertTrue(len(results)==2)
        
        #in checks for equality, not reference equality
        self.assertTrue(metadataDTO1 in results)
        self.assertTrue(metadataDTO2 in results)
        self.assertFalse(metadataDTO3 in results)
        
        
        
    def testDeleteSubtitle(self):
        infohash = _generateFakeInfohash()
        metadataDTO = MockMetadataDTO(["eng","kor"], infohash)
        
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)
        
        res = self.underTest.getAllSubtitles(metadataDTO.channel, infohash)
        self.assertTrue("eng" in res and "kor" in res)
        
        #delete a subtitle that does not exist
        self.underTest._deleteSubtitleByChannel(metadataDTO.channel, infohash, "ita")
        res = self.underTest.getAllSubtitles(metadataDTO.channel, infohash)
        self.assertTrue("eng" in res and "kor" in res)
        
        self.underTest._deleteSubtitleByChannel(metadataDTO.channel, infohash, "eng")
        res = self.underTest.getAllSubtitles(metadataDTO.channel, infohash)
        self.assertTrue("kor" in res and not "eng" in res)
        
        
    def testSelectLocalSubtitles(self):
        
        infohash1 = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["eng","kor"], infohash1)
           
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)
        
        res = self.underTest.getAllLocalSubtitles()
        
        self.assertTrue(len(res) == 0)
        
        infohash2 = _generateFakeInfohash()
        metadataDTO2 = MockMetadataDTO(["nld","spa"], infohash2)
        
        metadataDTO2.getSubtitle("nld").path = "/bla/bla"
        
        metadataDTO2.sign(metadataDTO2._keypair)
        self.underTest.insertMetadata(metadataDTO2)
        
        res = self.underTest.getAllLocalSubtitles()
        
        self.assertTrue(len(res) == 1)
        
        self.assertTrue(metadataDTO2.channel in res)
        
        self.assertTrue(infohash2 in res[metadataDTO2.channel])
        self.assertEquals(1, len(res[metadataDTO2.channel][infohash2]))
        
        self.assertEquals(metadataDTO2.getSubtitle("nld"), res[metadataDTO2.channel][infohash2][0])
        
    def testSelectLocalSubtitles2(self):
        infohash1 = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["eng","kor", "nld"], infohash1)
        
        metadataDTO1.getSubtitle("nld").path = "/bla/bla"
        metadataDTO1.getSubtitle("eng").path = "/bla/bla"
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)
        
        infohash2 = _generateFakeInfohash()
        metadataDTO2 = MockMetadataDTO(["ita","spa"], infohash2)
        metadataDTO2.getSubtitle("ita").path = "/a/b"
        metadataDTO2.getSubtitle("spa").path = "/c/d"
        metadataDTO2.sign(metadataDTO2._keypair)
        self.underTest.insertMetadata(metadataDTO2)
        
        
        res = self.underTest.getLocalSubtitles(metadataDTO1.channel, infohash1)
        self.assertEquals(2, len(res))

        self.assertTrue("eng" in res)
        self.assertEquals(metadataDTO1.getSubtitle("eng"), res["eng"])
        
        self.assertTrue("nld" in res)
        self.assertEquals(metadataDTO1.getSubtitle("nld"), res["nld"])
        
        self.assertFalse("kor" in res)
        
    def testUpdateSubtitlesWithNonePathValue(self):
        
        
        infohash1 = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["eng","kor"], infohash1)
        
        metadataDTO1.getSubtitle("eng").path = os.path.abspath(os.path.join("bla","bla"))
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)
        
        sub = self.underTest.getSubtitle(metadataDTO1.channel, infohash1, "eng")
        self.assertEquals(os.path.abspath(os.path.join("bla","bla")), sub.path)
        
        self.underTest.updateSubtitlePath(metadataDTO1.channel, infohash1,
                                          "eng", None, True)
        
        sub = self.underTest.getSubtitle(metadataDTO1.channel, infohash1, "eng")
        self.assertEquals(None, sub.path)
        
        
    def testUpdateSubtitles(self):
        sub1path= os.path.join(RES_DIR,"fake0.srt")
        sub2path=os.path.join(RES_DIR,"fake1.srt")
        infohash = _generateFakeInfohash()
        metadataDTO = MockMetadataDTO([], infohash)
        sub1 = SubtitleInfo("ita", None, _computeSHA1(sub1path))
        sub2 = SubtitleInfo("eng",None,_computeSHA1(sub2path))
        
        metadataDTO.addSubtitle(sub1)
        metadataDTO.addSubtitle(sub2)
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)
        
        res1 = self.underTest.getSubtitle(metadataDTO.channel, infohash,"ita")
        self.assertEquals(sub1,res1)
        
        res2 = self.underTest.getSubtitle(metadataDTO.channel, infohash, "eng")
        self.assertEquals(sub2,res2)
        
        sub1bis = copy.copy(sub1)
        sub1bis.path = sub1path
        sub2bis = copy.copy(sub2)
        sub2bis.path = sub2path
        
        self.underTest.updateSubtitlePath(metadataDTO.channel, infohash, 
                                      sub1bis.lang, sub1bis.path, False)
        self.underTest.updateSubtitlePath(metadataDTO.channel, infohash, 
                                      sub2bis.lang, sub2bis.path , False)
        
        
        self.underTest.commit()
        
        #still unchanged since I did not commit
        res1 = self.underTest.getSubtitle(metadataDTO.channel, infohash,"ita")
        self.assertTrue(sub1== res1 and sub1.path != res1.path)
        self.assertTrue(sub1bis == res1 and sub1bis.path == res1.path)
        
        res2 = self.underTest.getSubtitle(metadataDTO.channel, infohash, "eng")
        self.assertTrue(sub2 == res2 and sub2.path != res2.path)
        self.assertTrue(sub2bis == res2 and sub2bis.path == res2.path)
        
        
    # 30-05-2010 Testing of the new added table (SubtitlesHave) manipulation
    # methods.
    
    def testInsertAndGetHaveMask(self):
       
        
        infohash = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld","spa"], infohash)
        channel = metadataDTO1.channel
        
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)
        
        peer_id = TestMetadataDBHandler.anotherPermId
        
        #inserting a negative mask has to be refused
        havemask = -1
        funcToTest =\
            lambda : self.underTest.insertHaveMask(channel, infohash, 
                                                   peer_id, havemask)
        
        self.assertRaises(MetadataDBException, funcToTest)
        
        #also a bitmask must be smaller then 2**32
        havemask = 2**32
        
        funcToTest =\
            lambda : self.underTest.insertHaveMask(channel, infohash, 
                                                   peer_id, havemask)
        
        self.assertRaises(MetadataDBException, funcToTest)
        
        
        #now it's time for a correct value
        havemask1=0x80000001
        self.underTest.insertHaveMask(channel, infohash, peer_id, havemask1)
        
        mask = self.underTest.getHaveMask(channel, infohash,peer_id)
        self.assertEqual(mask,havemask1)
        
        #duplicate insertions should raise an error
        havemask2=0xffffffff
        funcToTest = \
           lambda : self.underTest.insertHaveMask(channel, infohash, 
                                                  peer_id, havemask2)
        
        self.assertRaises(MetadataDBException, funcToTest)
        
        #insertion for another peer should go fine
        self.underTest.insertHaveMask(channel, infohash, channel, havemask2)
        
        mask1 = self.underTest.getHaveMask(channel, infohash,peer_id)
        self.assertEqual(mask1,havemask1)
        mask2 = self.underTest.getHaveMask(channel, infohash,channel)
        self.assertEqual(mask2,havemask2)
        
        #getting an have mask for an unexistent channel, infohash shall
        #return None
        mask1 = \
            self.underTest.getHaveMask(channel, _generateFakeInfohash(),peer_id)
        self.assertTrue(mask1 is None)
        
        #as it should happen for asking for an unexisting peer_id
        mask1 = self.underTest.getHaveMask(channel, infohash,
                                           TestMetadataDBHandler.aPermId)
        self.assertTrue(mask1 is None)
        
    def testUpdateHaveMask(self):
        infohash = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld","spa"], infohash)
        channel = metadataDTO1.channel
        
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)
        
        peer_id = TestMetadataDBHandler.anotherPermId
        
        
        #adding an have mask to the db
        havemask1=0x80000001
        self.underTest.insertHaveMask(channel, infohash, peer_id, havemask1)
        
        mask = self.underTest.getHaveMask(channel, infohash,peer_id)
        self.assertEqual(mask,havemask1)
        
        #updating it to a different value
        new_havemask = 0x1111ffff
        self.underTest.updateHaveMask(channel, infohash, peer_id, 
                                      new_havemask)
        mask = self.underTest.getHaveMask(channel, infohash,peer_id)
        self.assertEqual(mask,new_havemask)
        
        #trying to update a non existing row should cause an error
        # -- currently this doesn't happen
        # implementing this beahaviour would slow down the db
        #funcToTest = \
        #    lambda: self.underTest.updateHaveMask(channel, infohash, 
        #                                         channel, new_havemask)
        # self.assertRaises(MetadataDBException, funcToTest)
    
    
    def testDeleteHaveEntry(self):
        infohash = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld","spa"], infohash)
        channel = metadataDTO1.channel
        
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)
        
        peer_id = TestMetadataDBHandler.anotherPermId
        
        
        #adding an have mask to the db
        havemask1=0x80000001
        self.underTest.insertHaveMask(channel, infohash, peer_id, havemask1)
        
        havemask2=0x02324123
        self.underTest.insertHaveMask(channel, infohash, channel, havemask2)
        
        self.underTest.deleteHaveEntry(channel, infohash, peer_id)
        
        mask = self.underTest.getHaveMask(channel, infohash, peer_id)
        self.assertTrue(mask is None)
        
        mask = self.underTest.getHaveMask(channel, infohash, channel)
        self.assertEquals(havemask2,mask)
        
        # deleting an entry that does not exist should leave
        # the db unchanged
        self.underTest.deleteHaveEntry(channel, infohash, peer_id)
        
        mask = self.underTest.getHaveMask(channel, infohash, channel)
        self.assertEquals(havemask2,mask)
        
    
    def testGetAllHaveEntries(self):
        
        infohash = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld","spa"], infohash)
        channel = metadataDTO1.channel
        
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)
        
        peer_id = TestMetadataDBHandler.anotherPermId
        
        
        #adding an have mask to the db
        havemask1=0x80000001
        self.underTest.insertHaveMask(channel, infohash, peer_id, havemask1)
        
        time.sleep(1) # otherwise they would have the same timestamp
        havemask2=0x02324123
        self.underTest.insertHaveMask(channel, infohash, channel, havemask2)
        
        d = self.underTest.getHaveEntries(channel, infohash)
        
        #the second inserted havemask has to be returned first
        # since it is newer
        firstTuple = d[0]
        self.assertEquals(channel, firstTuple[0])
        self.assertEquals(havemask2,firstTuple[1])
        self.assertTrue(firstTuple[2] is not None)
        
        self.assertEquals(peer_id, d[1][0])
        self.assertEquals(havemask1,d[1][1])
        self.assertTrue(d[1][2] is not None)
        
        
    
    def testCleanUpAllHave(self):
        infohash1 = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld","spa"], infohash1)
        channel1 = metadataDTO1.channel
        
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)
        
        infohash2 = _generateFakeInfohash()
        metadataDTO2 = MockMetadataDTO(["nld","spa"], infohash2)
        channel2 = metadataDTO2.channel
        
        metadataDTO2.sign(metadataDTO2._keypair)
        self.underTest.insertMetadata(metadataDTO2)
        
        
        peer_id1 = TestMetadataDBHandler.anotherPermId
        peer_id2 = TestMetadataDBHandler.aPermId
        
        #inserting some data: 4 have maskes for each of the two channels with
        # custom timestamps
        # older then 1275295300
        self.underTest.insertHaveMask(channel1, infohash1, channel1, 0x42, 1275295290)
        self.underTest.insertHaveMask(channel1, infohash1, peer_id1, 0x42, 1275295291)
        # newer then 1275295300
        self.underTest.insertHaveMask(channel1, infohash1, peer_id2, 0x42, 1275295300)
        self.underTest.insertHaveMask(channel1, infohash1, channel2, 0x42, 1275295301)
        
        
        # older then 1275295300
        self.underTest.insertHaveMask(channel2, infohash2, channel1, 0x42, 1275295290)
        self.underTest.insertHaveMask(channel2, infohash2, peer_id1, 0x42, 1275295291)
        
        # newer then 1275295300
        self.underTest.insertHaveMask(channel2, infohash2, peer_id2, 0x42, 1275295300)
        self.underTest.insertHaveMask(channel2, infohash2, channel2, 0x42, 1275295301)
        
        self.underTest.cleanupOldHave(1275295300)
        haveForEntry1 = self.underTest.getHaveEntries(channel1, infohash1)
        expectedList1 = [(channel2,0x42,1275295301), (peer_id2, 0x42, 1275295300), 
                         (channel1, 0x42, 1275295290)]
        self.assertEquals(expectedList1, haveForEntry1)
        
        haveForEntry2 = self.underTest.getHaveEntries(channel2, infohash2)
        expectedList2 = [(channel2, 0x42, 1275295301),(peer_id2, 0x42, 1275295300)]
        self.assertEquals(expectedList2,haveForEntry2)
Beispiel #4
0
class TestMetadataDBHandler(unittest.TestCase):
    _keypair1 = generate_keypair()
    aPermId = str(_keypair1.pub().get_der())
    _keypair2 = generate_keypair()
    anotherPermId = str(_keypair2.pub().get_der())

    def setUp(self):
        #createDB = not os.path.isfile(SQL_DB)
        self.db = SimpleMetadataDB(CREATE_SQL_FILE, SQL_DB)
        self.underTest = MetadataDBHandler(self.db)

    def tearDown(self):
        self.db.close()
        #if os.path.isfile(SQL_DB) :
            #os.remove(SQL_DB)



    def testInitHandler(self):
        self.assertTrue(self.underTest is not None)

    def testSingleton(self):

        instance1 = MetadataDBHandler.getInstance()
        instance2 = MetadataDBHandler.getInstance()
        self.assertTrue(instance1 is instance2)

    def testInsertNewMetadataSubs(self):
        metadataDTO = MockMetadataDTO(["nld","ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)

        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;"
        results = self.db.fetchall(testquery, (bin2str(metadataDTO.channel),bin2str(metadataDTO.infohash)))

        self.assertTrue(len(results) == 1)
        tupl = results[0]
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(bin2str(metadataDTO.channel),tupl[1])
        self.assertEquals(bin2str(metadataDTO.infohash),tupl[2])
        self.assertEquals(metadataDTO.description, tupl[3])
        self.assertEquals(metadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(metadataDTO.signature), tupl[5])

        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"

        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(2,len(subtitles))

        for lang in ("ita", "nld"):
            found = False
            foundSub = None
            for subtuple in subtitles:
                if subtuple[1] == lang:
                    found = True
                    foundSub = subtuple
                    break

            self.assertTrue(found)
            self.assertEquals(bin2str(metadataDTO.getSubtitle(lang).checksum), foundSub[3])


    def testGetMetadataInstance(self):
        metadataDTO = MockMetadataDTO(["nld","ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)

        retrievedMetadata = self.underTest.getMetadata(metadataDTO.channel,
                                                       metadataDTO.infohash)

        self.assertFalse(retrievedMetadata is None)
        self.assertFalse(retrievedMetadata is metadataDTO)
        self.assertEquals(metadataDTO,retrievedMetadata)




    def testInsertNewMetadataNoSubs(self):
        metadataDTO = MockMetadataDTO([])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)

        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;"

        channel = bin2str(metadataDTO.channel)
        infohash = bin2str(metadataDTO.infohash)
        results = self.db.fetchall(testquery, (channel,infohash))

        self.assertTrue(len(results) == 1)
        tupl = results[0]
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(channel,tupl[1])
        self.assertEquals(infohash,tupl[2])
        self.assertEquals(metadataDTO.description, tupl[3])
        self.assertEquals(metadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(metadataDTO.signature), tupl[5])

        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"

        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(0,len(subtitles))

    def testUpdateExistingWithOlder(self):


        metadataDTO = MockMetadataDTO(["nld", "ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)

        olderMetadataDTO = copy.copy(metadataDTO)
        olderMetadataDTO.timestamp = 1 #*really* old
        olderMetadataDTO.sign(olderMetadataDTO._keypair)

        self.underTest.insertMetadata(olderMetadataDTO)

        #assert the the older did not replace the newer
        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;"
        channel = bin2str(metadataDTO.channel)
        infohash = bin2str(metadataDTO.infohash)
        results = self.db.fetchall(testquery, (channel,infohash))

        self.assertTrue(len(results) == 1)
        tupl = results[0]
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(channel,tupl[1])
        self.assertEquals(infohash,tupl[2])
        self.assertEquals(metadataDTO.description, tupl[3])
        self.assertEquals(metadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(metadataDTO.signature), tupl[5])

        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"

        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(2,len(subtitles))

        for lang in ("ita", "nld"):
            found = False
            foundSub = None
            for subtuple in subtitles:
                if subtuple[1] == lang:
                    found = True
                    foundSub = subtuple
                    break

            self.assertTrue(found)
            self.assertEquals(bin2str(metadataDTO.getSubtitle(lang).checksum), foundSub[3])


    def testUpdateExistingWithNewerSameSub(self):
        metadataDTO = MockMetadataDTO(["nld", "ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)

        newerMetadataDTO = copy.copy(metadataDTO)
        newerMetadataDTO.description = u"I'm newer!"
        newerMetadataDTO.timestamp = newerMetadataDTO.timestamp +1 #newer
        newerMetadataDTO.sign(newerMetadataDTO._keypair)


        self.underTest.insertMetadata(newerMetadataDTO)

        #assert the the older has been replaced
        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;"

        channel = bin2str(metadataDTO.channel)
        infohash = bin2str(metadataDTO.infohash)
        results = self.db.fetchall(testquery, (channel,infohash))

        self.assertTrue(len(results) == 1)
        tupl = results[0]
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(channel,tupl[1])
        self.assertEquals(infohash,tupl[2])
        self.assertEquals(newerMetadataDTO.description, tupl[3])
        self.assertEquals(newerMetadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(newerMetadataDTO.signature), tupl[5])

        #testing subtitles with the old once since they are not changed
        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"

        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(2,len(subtitles))

        for lang in ("ita", "nld"):
            found = False
            foundSub = None
            for subtuple in subtitles:
                if subtuple[1] == lang:
                    found = True
                    foundSub = subtuple
                    break

            self.assertTrue(found)
            self.assertEquals(bin2str(metadataDTO.getSubtitle(lang).checksum), foundSub[3])



    def testUpdateExistingWithNewerNewSubs(self):
        metadataDTO = MockMetadataDTO(["nld", "ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)

        newerMetadataDTO = MockMetadataDTO(["nld","ita","eng"])
        newerMetadataDTO.channel = metadataDTO.channel
        newerMetadataDTO.infohash = metadataDTO.infohash
        newerMetadataDTO._keypair = metadataDTO._keypair
        newerMetadataDTO.timestamp = metadataDTO.timestamp +1 #newer
        newerMetadataDTO.sign(newerMetadataDTO._keypair)


        self.underTest.insertMetadata(newerMetadataDTO)

        #assert the the older has been replaced
        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;"

        channel = bin2str(metadataDTO.channel)
        infohash = bin2str(metadataDTO.infohash)
        results = self.db.fetchall(testquery, (channel,infohash))

        self.assertTrue(len(results) == 1)
        tupl = results[0]
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(channel,tupl[1])
        self.assertEquals(infohash,tupl[2])
        self.assertEquals(newerMetadataDTO.description, tupl[3])
        self.assertEquals(newerMetadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(newerMetadataDTO.signature), tupl[5])

        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"

        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(3,len(subtitles))

        for lang in ("ita", "nld","eng"):
            found = False
            foundSub = None
            for subtuple in subtitles:
                if subtuple[1] == lang:
                    found = True
                    foundSub = subtuple
                    break

            self.assertTrue(found)
            self.assertEquals(bin2str(newerMetadataDTO.getSubtitle(lang).checksum), foundSub[3])

    def testUpdateExistingWithNewerSubsDeleted(self):
        metadataDTO = MockMetadataDTO(["nld", "ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)

        newerMetadataDTO = MockMetadataDTO(["nld","eng"])
        newerMetadataDTO.channel = metadataDTO.channel
        newerMetadataDTO.infohash = metadataDTO.infohash
        newerMetadataDTO._keypair = metadataDTO._keypair
        newerMetadataDTO.timestamp = metadataDTO.timestamp +1 #newer
        newerMetadataDTO.sign(newerMetadataDTO._keypair)


        self.underTest.insertMetadata(newerMetadataDTO)

        #assert the the older has been replaced
        testquery = "SELECT * FROM Metadata WHERE publisher_id=?" \
            + " AND infohash=?;"
        channel = bin2str(metadataDTO.channel)
        infohash = bin2str(metadataDTO.infohash)
        results = self.db.fetchall(testquery, (channel,infohash))

        self.assertTrue(len(results) == 1)
        tupl = results[0]
        self.assertTrue(tupl[0] is not None and isinstance(tupl[0], int))
        self.assertEquals(channel,tupl[1])
        self.assertEquals(infohash,tupl[2])
        self.assertEquals(newerMetadataDTO.description, tupl[3])
        self.assertEquals(newerMetadataDTO.timestamp, tupl[4])
        self.assertEquals(bin2str(newerMetadataDTO.signature), tupl[5])

        subtitlesQuery = "SELECT * FROM Subtitles WHERE metadata_id_fk=?;"

        subtitles = self.db.fetchall(subtitlesQuery, (tupl[0],))
        self.assertEquals(2,len(subtitles))

        for lang in ("nld","eng"):
            found = False
            foundSub = None
            for subtuple in subtitles:
                if subtuple[1] == lang:
                    found = True
                    foundSub = subtuple
                    break

            self.assertTrue(found)
            self.assertEquals(bin2str(newerMetadataDTO.getSubtitle(lang).checksum), foundSub[3])

    def testGetAllMetadataForInfohashEmtpy(self):
        metadataDTO = MockMetadataDTO(["nld", "ita"])
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)


        otherinfohash = _generateFakeInfohash()

        results = self.underTest.getAllMetadataForInfohash(otherinfohash)
        self.assertTrue(len(results)==0)

    def testGetAllMetadataForInfohashNotEmpty(self):
        infohash = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld", "ita"],infohash)
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)

        #different channels since the channel is automatically
        #generated by MockMetadata DTO
        metadataDTO2 = MockMetadataDTO(["rus", "eng"],infohash)
        metadataDTO2.sign(metadataDTO2._keypair)
        self.underTest.insertMetadata(metadataDTO2)

        #a 3rd instance with different channel and infohash
        metadataDTO3 = MockMetadataDTO(["rus", "spa", "jpn"])
        metadataDTO3.sign(metadataDTO3._keypair)
        self.underTest.insertMetadata(metadataDTO3)

        results = self.underTest.getAllMetadataForInfohash(infohash)
        self.assertTrue(len(results)==2)

        #in checks for equality, not reference equality
        self.assertTrue(metadataDTO1 in results)
        self.assertTrue(metadataDTO2 in results)
        self.assertFalse(metadataDTO3 in results)



    def testDeleteSubtitle(self):
        infohash = _generateFakeInfohash()
        metadataDTO = MockMetadataDTO(["eng","kor"], infohash)

        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)

        res = self.underTest.getAllSubtitles(metadataDTO.channel, infohash)
        self.assertTrue("eng" in res and "kor" in res)

        #delete a subtitle that does not exist
        self.underTest._deleteSubtitleByChannel(metadataDTO.channel, infohash, "ita")
        res = self.underTest.getAllSubtitles(metadataDTO.channel, infohash)
        self.assertTrue("eng" in res and "kor" in res)

        self.underTest._deleteSubtitleByChannel(metadataDTO.channel, infohash, "eng")
        res = self.underTest.getAllSubtitles(metadataDTO.channel, infohash)
        self.assertTrue("kor" in res and not "eng" in res)


    def testSelectLocalSubtitles(self):

        infohash1 = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["eng","kor"], infohash1)

        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)

        res = self.underTest.getAllLocalSubtitles()

        self.assertTrue(len(res) == 0)

        infohash2 = _generateFakeInfohash()
        metadataDTO2 = MockMetadataDTO(["nld","spa"], infohash2)

        metadataDTO2.getSubtitle("nld").path = "/bla/bla"

        metadataDTO2.sign(metadataDTO2._keypair)
        self.underTest.insertMetadata(metadataDTO2)

        res = self.underTest.getAllLocalSubtitles()

        self.assertTrue(len(res) == 1)

        self.assertTrue(metadataDTO2.channel in res)

        self.assertTrue(infohash2 in res[metadataDTO2.channel])
        self.assertEquals(1, len(res[metadataDTO2.channel][infohash2]))

        self.assertEquals(metadataDTO2.getSubtitle("nld"), res[metadataDTO2.channel][infohash2][0])

    def testSelectLocalSubtitles2(self):
        infohash1 = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["eng","kor", "nld"], infohash1)

        metadataDTO1.getSubtitle("nld").path = "/bla/bla"
        metadataDTO1.getSubtitle("eng").path = "/bla/bla"
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)

        infohash2 = _generateFakeInfohash()
        metadataDTO2 = MockMetadataDTO(["ita","spa"], infohash2)
        metadataDTO2.getSubtitle("ita").path = "/a/b"
        metadataDTO2.getSubtitle("spa").path = "/c/d"
        metadataDTO2.sign(metadataDTO2._keypair)
        self.underTest.insertMetadata(metadataDTO2)


        res = self.underTest.getLocalSubtitles(metadataDTO1.channel, infohash1)
        self.assertEquals(2, len(res))

        self.assertTrue("eng" in res)
        self.assertEquals(metadataDTO1.getSubtitle("eng"), res["eng"])

        self.assertTrue("nld" in res)
        self.assertEquals(metadataDTO1.getSubtitle("nld"), res["nld"])

        self.assertFalse("kor" in res)

    def testUpdateSubtitlesWithNonePathValue(self):


        infohash1 = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["eng","kor"], infohash1)

        metadataDTO1.getSubtitle("eng").path = os.path.abspath(os.path.join("bla","bla"))
        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)

        sub = self.underTest.getSubtitle(metadataDTO1.channel, infohash1, "eng")
        self.assertEquals(os.path.abspath(os.path.join("bla","bla")), sub.path)

        self.underTest.updateSubtitlePath(metadataDTO1.channel, infohash1,
                                          "eng", None, True)

        sub = self.underTest.getSubtitle(metadataDTO1.channel, infohash1, "eng")
        self.assertEquals(None, sub.path)


    def testUpdateSubtitles(self):
        sub1path= os.path.join(RES_DIR,"fake0.srt")
        sub2path=os.path.join(RES_DIR,"fake1.srt")
        infohash = _generateFakeInfohash()
        metadataDTO = MockMetadataDTO([], infohash)
        sub1 = SubtitleInfo("ita", None, _computeSHA1(sub1path))
        sub2 = SubtitleInfo("eng",None,_computeSHA1(sub2path))

        metadataDTO.addSubtitle(sub1)
        metadataDTO.addSubtitle(sub2)
        metadataDTO.sign(metadataDTO._keypair)
        self.underTest.insertMetadata(metadataDTO)

        res1 = self.underTest.getSubtitle(metadataDTO.channel, infohash,"ita")
        self.assertEquals(sub1,res1)

        res2 = self.underTest.getSubtitle(metadataDTO.channel, infohash, "eng")
        self.assertEquals(sub2,res2)

        sub1bis = copy.copy(sub1)
        sub1bis.path = sub1path
        sub2bis = copy.copy(sub2)
        sub2bis.path = sub2path

        self.underTest.updateSubtitlePath(metadataDTO.channel, infohash,
                                      sub1bis.lang, sub1bis.path, False)
        self.underTest.updateSubtitlePath(metadataDTO.channel, infohash,
                                      sub2bis.lang, sub2bis.path , False)


        self.underTest.commit()

        #still unchanged since I did not commit
        res1 = self.underTest.getSubtitle(metadataDTO.channel, infohash,"ita")
        self.assertTrue(sub1== res1 and sub1.path != res1.path)
        self.assertTrue(sub1bis == res1 and sub1bis.path == res1.path)

        res2 = self.underTest.getSubtitle(metadataDTO.channel, infohash, "eng")
        self.assertTrue(sub2 == res2 and sub2.path != res2.path)
        self.assertTrue(sub2bis == res2 and sub2bis.path == res2.path)


    # 30-05-2010 Testing of the new added table (SubtitlesHave) manipulation
    # methods.

    def testInsertAndGetHaveMask(self):


        infohash = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld","spa"], infohash)
        channel = metadataDTO1.channel

        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)

        peer_id = TestMetadataDBHandler.anotherPermId

        #inserting a negative mask has to be refused
        havemask = -1
        funcToTest =\
            lambda : self.underTest.insertHaveMask(channel, infohash,
                                                   peer_id, havemask)

        self.assertRaises(MetadataDBException, funcToTest)

        #also a bitmask must be smaller then 2**32
        havemask = 2**32

        funcToTest =\
            lambda : self.underTest.insertHaveMask(channel, infohash,
                                                   peer_id, havemask)

        self.assertRaises(MetadataDBException, funcToTest)


        #now it's time for a correct value
        havemask1=0x80000001
        self.underTest.insertHaveMask(channel, infohash, peer_id, havemask1)

        mask = self.underTest.getHaveMask(channel, infohash,peer_id)
        self.assertEqual(mask,havemask1)

        #duplicate insertions should raise an error
        havemask2=0xffffffff
        funcToTest = \
           lambda : self.underTest.insertHaveMask(channel, infohash,
                                                  peer_id, havemask2)

        self.assertRaises(MetadataDBException, funcToTest)

        #insertion for another peer should go fine
        self.underTest.insertHaveMask(channel, infohash, channel, havemask2)

        mask1 = self.underTest.getHaveMask(channel, infohash,peer_id)
        self.assertEqual(mask1,havemask1)
        mask2 = self.underTest.getHaveMask(channel, infohash,channel)
        self.assertEqual(mask2,havemask2)

        #getting an have mask for an unexistent channel, infohash shall
        #return None
        mask1 = \
            self.underTest.getHaveMask(channel, _generateFakeInfohash(),peer_id)
        self.assertTrue(mask1 is None)

        #as it should happen for asking for an unexisting peer_id
        mask1 = self.underTest.getHaveMask(channel, infohash,
                                           TestMetadataDBHandler.aPermId)
        self.assertTrue(mask1 is None)

    def testUpdateHaveMask(self):
        infohash = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld","spa"], infohash)
        channel = metadataDTO1.channel

        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)

        peer_id = TestMetadataDBHandler.anotherPermId


        #adding an have mask to the db
        havemask1=0x80000001
        self.underTest.insertHaveMask(channel, infohash, peer_id, havemask1)

        mask = self.underTest.getHaveMask(channel, infohash,peer_id)
        self.assertEqual(mask,havemask1)

        #updating it to a different value
        new_havemask = 0x1111ffff
        self.underTest.updateHaveMask(channel, infohash, peer_id,
                                      new_havemask)
        mask = self.underTest.getHaveMask(channel, infohash,peer_id)
        self.assertEqual(mask,new_havemask)

        #trying to update a non existing row should cause an error
        # -- currently this doesn't happen
        # implementing this beahaviour would slow down the db
        #funcToTest = \
        #    lambda: self.underTest.updateHaveMask(channel, infohash,
        #                                         channel, new_havemask)
        # self.assertRaises(MetadataDBException, funcToTest)


    def testDeleteHaveEntry(self):
        infohash = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld","spa"], infohash)
        channel = metadataDTO1.channel

        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)

        peer_id = TestMetadataDBHandler.anotherPermId


        #adding an have mask to the db
        havemask1=0x80000001
        self.underTest.insertHaveMask(channel, infohash, peer_id, havemask1)

        havemask2=0x02324123
        self.underTest.insertHaveMask(channel, infohash, channel, havemask2)

        self.underTest.deleteHaveEntry(channel, infohash, peer_id)

        mask = self.underTest.getHaveMask(channel, infohash, peer_id)
        self.assertTrue(mask is None)

        mask = self.underTest.getHaveMask(channel, infohash, channel)
        self.assertEquals(havemask2,mask)

        # deleting an entry that does not exist should leave
        # the db unchanged
        self.underTest.deleteHaveEntry(channel, infohash, peer_id)

        mask = self.underTest.getHaveMask(channel, infohash, channel)
        self.assertEquals(havemask2,mask)


    def testGetAllHaveEntries(self):

        infohash = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld","spa"], infohash)
        channel = metadataDTO1.channel

        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)

        peer_id = TestMetadataDBHandler.anotherPermId


        #adding an have mask to the db
        havemask1=0x80000001
        self.underTest.insertHaveMask(channel, infohash, peer_id, havemask1)

        time.sleep(1) # otherwise they would have the same timestamp
        havemask2=0x02324123
        self.underTest.insertHaveMask(channel, infohash, channel, havemask2)

        d = self.underTest.getHaveEntries(channel, infohash)

        #the second inserted havemask has to be returned first
        # since it is newer
        firstTuple = d[0]
        self.assertEquals(channel, firstTuple[0])
        self.assertEquals(havemask2,firstTuple[1])
        self.assertTrue(firstTuple[2] is not None)

        self.assertEquals(peer_id, d[1][0])
        self.assertEquals(havemask1,d[1][1])
        self.assertTrue(d[1][2] is not None)



    def testCleanUpAllHave(self):
        infohash1 = _generateFakeInfohash()
        metadataDTO1 = MockMetadataDTO(["nld","spa"], infohash1)
        channel1 = metadataDTO1.channel

        metadataDTO1.sign(metadataDTO1._keypair)
        self.underTest.insertMetadata(metadataDTO1)

        infohash2 = _generateFakeInfohash()
        metadataDTO2 = MockMetadataDTO(["nld","spa"], infohash2)
        channel2 = metadataDTO2.channel

        metadataDTO2.sign(metadataDTO2._keypair)
        self.underTest.insertMetadata(metadataDTO2)


        peer_id1 = TestMetadataDBHandler.anotherPermId
        peer_id2 = TestMetadataDBHandler.aPermId

        #inserting some data: 4 have maskes for each of the two channels with
        # custom timestamps
        # older then 1275295300
        self.underTest.insertHaveMask(channel1, infohash1, channel1, 0x42, 1275295290)
        self.underTest.insertHaveMask(channel1, infohash1, peer_id1, 0x42, 1275295291)
        # newer then 1275295300
        self.underTest.insertHaveMask(channel1, infohash1, peer_id2, 0x42, 1275295300)
        self.underTest.insertHaveMask(channel1, infohash1, channel2, 0x42, 1275295301)


        # older then 1275295300
        self.underTest.insertHaveMask(channel2, infohash2, channel1, 0x42, 1275295290)
        self.underTest.insertHaveMask(channel2, infohash2, peer_id1, 0x42, 1275295291)

        # newer then 1275295300
        self.underTest.insertHaveMask(channel2, infohash2, peer_id2, 0x42, 1275295300)
        self.underTest.insertHaveMask(channel2, infohash2, channel2, 0x42, 1275295301)

        self.underTest.cleanupOldHave(1275295300)
        haveForEntry1 = self.underTest.getHaveEntries(channel1, infohash1)
        expectedList1 = [(channel2,0x42,1275295301), (peer_id2, 0x42, 1275295300),
                         (channel1, 0x42, 1275295290)]
        self.assertEquals(expectedList1, haveForEntry1)

        haveForEntry2 = self.underTest.getHaveEntries(channel2, infohash2)
        expectedList2 = [(channel2, 0x42, 1275295301),(peer_id2, 0x42, 1275295300)]
        self.assertEquals(expectedList2,haveForEntry2)