def test_DoneDeleteUnreferencedButNotExpiredAliases(self): # LibraryFileAliases can be removed only after they have expired. # If an explicit expiry is set and in recent past (currently up to # one week ago), the files hang around. # Merge the duplicates. Both our aliases now point to the same # LibraryFileContent librariangc.merge_duplicates(self.con) # Flag one of our LibraryFileAliases with an expiry date in the # recent past. self.ztm.begin() f1 = LibraryFileAlias.get(self.f1_id) f1.expires = self.recent_past del f1 self.ztm.commit() # Delete unreferenced LibraryFileAliases. This should not remove our # example aliases, as one is unreferenced with a NULL expiry and # the other is unreferenced with an expiry in the recent past. librariangc.delete_unreferenced_aliases(self.con) # Make sure both our example files are still there self.ztm.begin() # Our recently expired LibraryFileAlias is still available. LibraryFileAlias.get(self.f1_id)
def main(self): librariangc.log = self.logger if self.options.loglevel <= logging.DEBUG: librariangc.debug = True # XXX wgrant 2011-09-18 bug=853066: Using Storm's raw connection # here is wrong. We should either create our own or use # Store.execute or cursor() and the transaction module. conn = IStore(LibraryFileAlias)._connection._raw_connection # Refuse to run if we have significant clock skew between the # librarian and the database. librariangc.confirm_no_clock_skew(conn) # Note that each of these next steps will issue commit commands # as appropriate to make this script transaction friendly if not self.options.skip_expiry: librariangc.expire_aliases(conn) if not self.options.skip_content: # First sweep. librariangc.delete_unreferenced_content(conn) if not self.options.skip_blobs: librariangc.delete_expired_blobs(conn) if not self.options.skip_duplicates: librariangc.merge_duplicates(conn) if not self.options.skip_aliases: librariangc.delete_unreferenced_aliases(conn) if not self.options.skip_content: # Second sweep. librariangc.delete_unreferenced_content(conn) if not self.options.skip_files: librariangc.delete_unwanted_files(conn)
def test_DeleteUnreferencedAliases2(self): # Don't delete LibraryFileAliases accessed recently # Merge the duplicates. Both our aliases now point to the same # LibraryFileContent librariangc.merge_duplicates(self.con) # We now have two aliases sharing the same content. self.ztm.begin() f1 = LibraryFileAlias.get(self.f1_id) f2 = LibraryFileAlias.get(self.f2_id) self.assertEqual(f1.content, f2.content) # Flag one of our LibraryFileAliases as being recently created f1.date_created = self.recent_past del f1 del f2 self.ztm.commit() # Delete unreferenced LibraryFileAliases. This should remove # the alias with the ID self.f2_id, but the other should stay, # as it was accessed recently. librariangc.delete_unreferenced_aliases(self.con) self.ztm.begin() LibraryFileAlias.get(self.f1_id) self.assertRaises(SQLObjectNotFound, LibraryFileAlias.get, self.f2_id)
def test_DeleteUnreferencedAliases(self): self.ztm.begin() # Confirm that our sample files are there. f1 = LibraryFileAlias.get(self.f1_id) f2 = LibraryFileAlias.get(self.f2_id) # Grab the content IDs related to these # unreferenced LibraryFileAliases c1_id = f1.contentID c2_id = f2.contentID del f1, f2 self.ztm.abort() # Delete unreferenced aliases librariangc.delete_unreferenced_aliases(self.con) # This should have committed self.ztm.begin() # Confirm that the LibaryFileContents are still there. LibraryFileContent.get(c1_id) LibraryFileContent.get(c2_id) # But the LibraryFileAliases should be gone self.assertRaises(SQLObjectNotFound, LibraryFileAlias.get, self.f1_id) self.assertRaises(SQLObjectNotFound, LibraryFileAlias.get, self.f2_id)
def test_DeleteUnreferencedAndWellExpiredAliases(self): # LibraryFileAliases can be removed after they have expired # Merge the duplicates. Both our aliases now point to the same # LibraryFileContent librariangc.merge_duplicates(self.con) # Flag one of our LibraryFileAliases with an expiry date in the past self.ztm.begin() f1 = LibraryFileAlias.get(self.f1_id) f1.expires = self.ancient_past del f1 self.ztm.commit() # Delete unreferenced LibraryFileAliases. This should remove our # example aliases, as one is unreferenced with a NULL expiry and # the other is unreferenced with an expiry in the past. librariangc.delete_unreferenced_aliases(self.con) # Make sure both our example files are gone self.ztm.begin() self.assertRaises(SQLObjectNotFound, LibraryFileAlias.get, self.f1_id) self.assertRaises(SQLObjectNotFound, LibraryFileAlias.get, self.f2_id)
def test_DeleteExpiredBlobs(self): # Delete expired blobs from the TemporaryBlobStorage table librariangc.delete_expired_blobs(self.con) cur = self.con.cursor() # Our expired blob should be gone cur.execute(""" SELECT * FROM TemporaryBlobStorage WHERE id=%s """, (self.expired_blob_id,) ) self.failUnless(cur.fetchone() is None) # As should our expired blob linked elsewhere. cur.execute(""" SELECT * FROM TemporaryBlobStorage WHERE id=%s """, (self.expired2_blob_id,) ) self.failUnless(cur.fetchone() is None) # But our unexpired blob is still hanging around. cur.execute(""" SELECT * FROM TemporaryBlobStorage WHERE id=%s """, (self.unexpired_blob_id,) ) self.failUnless(cur.fetchone() is not None) # Now delete our unreferenced aliases and unreferenced content cur.execute( "SELECT id FROM LibraryFileAlias WHERE id IN (%s, %s, %s)", (self.expired_lfa_id, self.expired2_lfa_id, self.unexpired_lfa_id)) librariangc.delete_unreferenced_aliases(self.con) librariangc.delete_unreferenced_content(self.con) cur.execute( "SELECT id FROM LibraryFileAlias WHERE id IN (%s, %s, %s)", (self.expired_lfa_id, self.expired2_lfa_id, self.unexpired_lfa_id)) # The first expired blob should now be entirely gone cur.execute(""" SELECT * FROM LibraryFileAlias WHERE id=%s """, (self.expired_lfa_id,)) self.failUnless(cur.fetchone() is None) cur.execute(""" SELECT * FROM LibraryFileContent WHERE id=%s """, (self.expired_lfc_id,)) self.failUnless(cur.fetchone() is None) # The second expired blob will has lost its LibraryFileAlias, # but the content is still hanging around because something else # linked to it. cur.execute(""" SELECT * FROM LibraryFileAlias WHERE id=%s """, (self.expired2_lfa_id,)) self.failUnless(cur.fetchone() is None) cur.execute(""" SELECT * FROM LibraryFileContent WHERE id=%s """, (self.expired2_lfc_id,)) self.failUnless(cur.fetchone() is not None) # The unexpired blob should be unaffected cur.execute(""" SELECT * FROM LibraryFileAlias WHERE id=%s """, (self.unexpired_lfa_id,)) self.failUnless(cur.fetchone() is not None) cur.execute(""" SELECT * FROM LibraryFileContent WHERE id=%s """, (self.unexpired_lfc_id,)) self.failUnless(cur.fetchone() is not None)