[Checkins] SVN: zodbupgrade/trunk/ - Add logging filter to suppress repeated messages

Christian Theune ct at gocept.com
Mon Jun 15 03:53:52 EDT 2009


Log message for revision 100957:
  - Add logging filter to suppress repeated messages
  - Re-add command line argument handling for `dry run` and `ignore missing`.
  - Fix `ignore missing` mode, add tests.
  - Refactor tests.
  

Changed:
  U   zodbupgrade/trunk/TODO.txt
  U   zodbupgrade/trunk/src/zodbupgrade/analyze.py
  U   zodbupgrade/trunk/src/zodbupgrade/main.py
  U   zodbupgrade/trunk/src/zodbupgrade/tests.py

-=-
Modified: zodbupgrade/trunk/TODO.txt
===================================================================
--- zodbupgrade/trunk/TODO.txt	2009-06-15 06:33:34 UTC (rev 100956)
+++ zodbupgrade/trunk/TODO.txt	2009-06-15 07:53:52 UTC (rev 100957)
@@ -1,15 +1,12 @@
 TODO
 ====
 
-- Compress repeated warnings, ignore warnings that are known to come from the
-  framework (factory PermissionSetting: Allow does not have __name__, can't
-  check canonical location)
+- Write out rewritten class names to file that can be read for offline
+  updating.
 
 - Provide "offline" updating: read a list of old/new pairs and update pickles
   directly without needing the old code. Use setuptools entry points for
   discovering those mappings?
 
-- Improve logging after refactoring
+- Review and accordingly improve logging.
 
-- Write out rewritten class names to file that can be read for offline
-  updating.

Modified: zodbupgrade/trunk/src/zodbupgrade/analyze.py
===================================================================
--- zodbupgrade/trunk/src/zodbupgrade/analyze.py	2009-06-15 06:33:34 UTC (rev 100956)
+++ zodbupgrade/trunk/src/zodbupgrade/analyze.py	2009-06-15 07:53:52 UTC (rev 100957)
@@ -33,6 +33,7 @@
         self.ignore_missing = ignore_missing
         self.dry = dry
         self.storage = storage
+        self.missing = set()
 
     def __call__(self):
         t = transaction.Transaction()
@@ -43,11 +44,14 @@
             new = self.update_record(current)
             if new == current:
                 continue
+            logger.debug('Updated %s' % ZODB.utils.oid_repr(oid))
             self.storage.store(oid, serial, new, '', t)
 
         if self.dry:
+            logger.info('Dry run selected, aborting transaction.')
             self.storage.tpc_abort(t)
         else:
+            logger.info('Committing changes.')
             self.storage.tpc_vote(t)
             self.storage.tpc_finish(t)
 
@@ -81,11 +85,17 @@
 
         # XXX Handle missing factories
         factory_module, factory_name = arg.split(' ')
-        module = __import__(factory_module, globals(), {}, [factory_name])
         try:
+            module = __import__(factory_module, globals(), {}, [factory_name])
             factory = getattr(module, factory_name)
-        except AttributeError:
-            raise ValueError()
+        except (AttributeError, ImportError):
+            name = '%s.%s' % (factory_module, factory_name)
+            message = 'Missing factory: %s' % name
+            logger.info(message)
+            self.missing.add(name)
+            if self.ignore_missing:
+                return
+            raise ValueError(message)
 
         if not hasattr(factory, '__name__'):
             logger.warn(

Modified: zodbupgrade/trunk/src/zodbupgrade/main.py
===================================================================
--- zodbupgrade/trunk/src/zodbupgrade/main.py	2009-06-15 06:33:34 UTC (rev 100956)
+++ zodbupgrade/trunk/src/zodbupgrade/main.py	2009-06-15 07:53:52 UTC (rev 100957)
@@ -33,6 +33,20 @@
 parser.add_option("-q", "--quiet", action="store_true",
                   help="suppress non-error messages")
 
+class DuplicateFilter(object):
+
+    def __init__(self):
+        self.seen = set()
+
+    def filter(self, record):
+        if record.msg in self.seen:
+            return False
+        self.seen.add(record.msg)
+        return True
+
+duplicate_filter = DuplicateFilter()
+
+
 def main():
     options, args = parser.parse_args()
 
@@ -54,6 +68,12 @@
         level = logging.INFO
     logging.getLogger().addHandler(logging.StreamHandler())
     logging.getLogger().setLevel(level)
+    logging.getLogger('zodbupgrade').addFilter(duplicate_filter)
 
-    upgrader = zodbupgrade.analyze.Upgrader(storage)
-    upgrader()
+    updater = zodbupgrade.analyze.Updater(storage,
+                                          dry=options.dry_run,
+                                          ignore_missing=options.ignore_missing)
+    try:
+        updater()
+    except Exception, e:
+        logging.error('Stopped processing, due to: %s' % e)

Modified: zodbupgrade/trunk/src/zodbupgrade/tests.py
===================================================================
--- zodbupgrade/trunk/src/zodbupgrade/tests.py	2009-06-15 06:33:34 UTC (rev 100956)
+++ zodbupgrade/trunk/src/zodbupgrade/tests.py	2009-06-15 07:53:52 UTC (rev 100957)
@@ -13,6 +13,7 @@
 ##############################################################################
 
 import ZODB
+import ZODB.broken
 import ZODB.FileStorage
 import logging 
 import os
@@ -47,13 +48,24 @@
         Factory.__module__ = 'module1'
 
         _, self.dbfile = tempfile.mkstemp()
-        self.db = None
-        self.reopen_db()
 
+        self.storage = ZODB.FileStorage.FileStorage(self.dbfile)
+        self.db = ZODB.DB(self.storage)
+        self.conn = self.db.open()
+        self.root = self.conn.root()
+
     def update(self, **args):
+        self.db.close()
+
+        self.storage = ZODB.FileStorage.FileStorage(self.dbfile)
         updater = zodbupgrade.analyze.Updater(self.storage, **args)
         updater()
         self.storage.close()
+
+        self.storage = ZODB.FileStorage.FileStorage(self.dbfile)
+        self.db = ZODB.DB(self.storage)
+        self.conn = self.db.open()
+        self.root = self.conn.root()
         return updater
 
     def tearDown(self):
@@ -66,27 +78,30 @@
         os.unlink(self.dbfile + '.tmp')
         os.unlink(self.dbfile + '.lock')
 
-    def reopen_storage(self):
-        self.storage = ZODB.FileStorage.FileStorage(self.dbfile)
+    def test_factory_missing(self):
+        # Create a ZODB with an object referencing a factory, then 
+        # remove the factory and analyze the ZODB.
+        self.root['test'] = sys.modules['module1'].Factory()
+        transaction.commit()
+        del sys.modules['module1'].Factory
 
-    def reopen_db(self):
-        self.reopen_storage()
-        self.db = ZODB.DB(self.storage)
-        self.conn = self.db.open()
-        self.root = self.conn.root()
+        self.assertRaises(ValueError, self.update)
 
-    def test_factory_missing(self):
+    def test_factory_ignore_missing(self):
         # Create a ZODB with an object referencing a factory, then 
         # remove the factory and analyze the ZODB.
         self.root['test'] = sys.modules['module1'].Factory()
         transaction.commit()
         del sys.modules['module1'].Factory
 
-        self.db.close()
-        self.reopen_storage()
+        self.update(ignore_missing=True)
 
-        self.assertRaises(ValueError, self.update)
+        self.assertEquals('cmodule1\nFactory\nq\x01.}q\x02.',
+                          self.storage.load(self.root['test']._p_oid, '')[0])
+        self.assert_(isinstance(self.root['test'],
+                                ZODB.broken.PersistentBroken))
 
+
     def test_factory_renamed(self):
         # Create a ZODB with an object referencing a factory, then 
         # rename the the factory but keep a reference from the old name in
@@ -99,15 +114,8 @@
         sys.modules['module1'].NewFactory = sys.modules['module1'].Factory
         sys.modules['module1'].NewFactory.__name__ = 'NewFactory'
 
-        self.db.close()
-        self.reopen_storage()
-
         self.update()
 
-        del sys.modules['module1'].Factory
-
-        self.reopen_db()
-
         self.assertEquals('cmodule1\nNewFactory\nq\x01.}q\x02.',
                           self.storage.load(self.root['test']._p_oid, '')[0])
         self.assertEquals('module1', self.root['test'].__class__.__module__)
@@ -123,20 +131,12 @@
         sys.modules['module1'].NewFactory = sys.modules['module1'].Factory
         sys.modules['module1'].NewFactory.__name__ = 'NewFactory'
 
-        self.db.close()
-        self.reopen_storage()
-
         self.update(dry=True)
 
-        self.reopen_db()
-
         self.assertEquals('cmodule1\nFactory\nq\x01.}q\x02.',
                           self.storage.load(self.root['test']._p_oid, '')[0])
 
-        self.db.close()
-        self.reopen_storage()
         self.update(dry=False)
-        self.reopen_db()
 
         self.assertEquals('cmodule1\nNewFactory\nq\x01.}q\x02.',
                           self.storage.load(self.root['test']._p_oid, '')[0])
@@ -161,8 +161,7 @@
                         AnonymousFactory)
         self.root['test'] = sys.modules['module1'].Anonymous
         transaction.commit()
-        self.db.close()
-        self.reopen_storage()
+
         self.update()
 
         self.assertEquals('module1', self.root['test'].__class__.__module__)



More information about the Checkins mailing list