[Checkins] SVN: ZODB/trunk/src/ Fixed analyze.py and added test.
Laurence Rowe
l at lrowe.co.uk
Tue May 26 12:10:58 EDT 2009
Log message for revision 100422:
Fixed analyze.py and added test.
Changed:
U ZODB/trunk/src/CHANGES.txt
U ZODB/trunk/src/ZODB/scripts/analyze.py
U ZODB/trunk/src/ZODB/tests/testFileStorage.py
-=-
Modified: ZODB/trunk/src/CHANGES.txt
===================================================================
--- ZODB/trunk/src/CHANGES.txt 2009-05-26 16:02:30 UTC (rev 100421)
+++ ZODB/trunk/src/CHANGES.txt 2009-05-26 16:10:57 UTC (rev 100422)
@@ -12,6 +12,8 @@
- Fixed intermittent failures in the MVCCMappingStorage tests.
+- Fixed analyze.py and added test.
+
3.9.0b1 (2009-05-04)
====================
Modified: ZODB/trunk/src/ZODB/scripts/analyze.py
===================================================================
--- ZODB/trunk/src/ZODB/scripts/analyze.py 2009-05-26 16:02:30 UTC (rev 100421)
+++ ZODB/trunk/src/ZODB/scripts/analyze.py 2009-05-26 16:10:57 UTC (rev 100422)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.3
+#!/usr/bin/env python2.4
# Based on a transaction analyzer by Matt Kromer.
@@ -7,7 +7,18 @@
import sys
import types
from ZODB.FileStorage import FileStorage
+from cStringIO import StringIO
+class FakeError(Exception):
+ def __init__(self, module, name):
+ Exception.__init__(self)
+ self.module = module
+ self.name = name
+
+class FakeUnpickler(pickle.Unpickler):
+ def find_class(self, module, name):
+ raise FakeError(module, name)
+
class Report:
def __init__(self):
self.OIDMAP = {}
@@ -87,15 +98,12 @@
def get_type(record):
try:
- classinfo = pickle.loads(record.data)[0]
- except SystemError, err:
- s = str(err)
- mo = re.match('Failed to import class (\S+) from module (\S+)', s)
- if mo is None:
- raise
- else:
- klass, mod = mo.group(1, 2)
- return "%s.%s" % (mod, klass)
+ unpickled = FakeUnpickler(StringIO(record.data)).load()
+ except FakeError, err:
+ return "%s.%s" % (err.module, err.name)
+ except:
+ raise
+ classinfo = unpickled[0]
if isinstance(classinfo, types.TupleType):
mod, klass = classinfo
return "%s.%s" % (mod, klass)
@@ -130,9 +138,6 @@
except Exception, err:
print err
-def main():
+if __name__ == "__main__":
path = sys.argv[1]
report(analyze(path))
-
-if __name__ == "__main__":
- main()
Modified: ZODB/trunk/src/ZODB/tests/testFileStorage.py
===================================================================
--- ZODB/trunk/src/ZODB/tests/testFileStorage.py 2009-05-26 16:02:30 UTC (rev 100421)
+++ ZODB/trunk/src/ZODB/tests/testFileStorage.py 2009-05-26 16:10:57 UTC (rev 100422)
@@ -336,6 +336,72 @@
pass
+class AnalyzeDotPyTest(StorageTestBase.StorageTestBase):
+
+ def setUp(self):
+ StorageTestBase.StorageTestBase.setUp(self)
+ self._storage = ZODB.FileStorage.FileStorage("Source.fs", create=True)
+
+ def checkanalyze(self):
+ import new, sys, pickle
+ from BTrees.OOBTree import OOBTree
+ from ZODB.scripts import analyze
+
+ # Set up a module to act as a broken import
+ module_name = 'brokenmodule'
+ module = new.module(module_name)
+ sys.modules[module_name] = module
+
+ class Broken(MinPO):
+ __module__ = module_name
+ module.Broken = Broken
+
+ oids = [[self._storage.new_oid(), None] for i in range(3)]
+ for i in range(2):
+ t = transaction.Transaction()
+ self._storage.tpc_begin(t)
+
+ # sometimes data is in this format
+ j = 0
+ oid, revid = oids[j]
+ serial = self._storage.store(oid, revid, pickle.dumps(OOBTree, 1), "", t)
+ oids[j][1] = serial
+
+ # and it could be from a broken module
+ j = 1
+ oid, revid = oids[j]
+ serial = self._storage.store(oid, revid, pickle.dumps(Broken, 1), "", t)
+ oids[j][1] = serial
+
+ # but mostly it looks like this
+ j = 2
+ o = MinPO(j)
+ oid, revid = oids[j]
+ serial = self._storage.store(oid, revid, zodb_pickle(o), "", t)
+ oids[j][1] = serial
+
+ self._storage.tpc_vote(t)
+ self._storage.tpc_finish(t)
+
+ # now break the import of the Broken class
+ del sys.modules[module_name]
+
+ # from ZODB.scripts.analyze.analyze
+ fsi = self._storage.iterator()
+ rep = analyze.Report()
+ for txn in fsi:
+ analyze.analyze_trans(rep, txn)
+
+ # from ZODB.scripts.analyze.report
+ typemap = rep.TYPEMAP.keys()
+ typemap.sort()
+ cumpct = 0.0
+ for t in typemap:
+ pct = rep.TYPESIZE[t] * 100.0 / rep.DBYTES
+ cumpct += pct
+
+ self.assertAlmostEqual(cumpct, 100.0, 0, "Failed to analyze some records")
+
# Raise an exception if the tids in FileStorage fs aren't
# strictly increasing.
def checkIncreasingTids(fs):
@@ -573,7 +639,7 @@
suite = unittest.TestSuite()
for klass in [FileStorageTests, Corruption.FileStorageCorruptTests,
FileStorageRecoveryTest, FileStorageNoRestoreRecoveryTest,
- FileStorageTestsWithBlobsEnabled,
+ FileStorageTestsWithBlobsEnabled, AnalyzeDotPyTest,
]:
suite.addTest(unittest.makeSuite(klass, "check"))
suite.addTest(doctest.DocTestSuite(
More information about the Checkins
mailing list