Commit c217a116 authored by Laurence Rowe's avatar Laurence Rowe

Fixed analyze.py and added test.

parent f99946d4
......@@ -12,6 +12,8 @@ Bugs Fixed
- Fixed intermittent failures in the MVCCMappingStorage tests.
- Fixed analyze.py and added test.
3.9.0b1 (2009-05-04)
====================
......
#!/usr/bin/env python2.3
#!/usr/bin/env python2.4
# Based on a transaction analyzer by Matt Kromer.
......@@ -7,6 +7,17 @@ import re
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):
......@@ -87,15 +98,12 @@ def analyze_trans(report, txn):
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 @@ def analyze_rec(report, record):
except Exception, err:
print err
def main():
if __name__ == "__main__":
path = sys.argv[1]
report(analyze(path))
if __name__ == "__main__":
main()
......@@ -336,6 +336,72 @@ class FileStorageNoRestoreRecoveryTest(FileStorageRecoveryTest):
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 @@ def test_suite():
suite = unittest.TestSuite()
for klass in [FileStorageTests, Corruption.FileStorageCorruptTests,
FileStorageRecoveryTest, FileStorageNoRestoreRecoveryTest,
FileStorageTestsWithBlobsEnabled,
FileStorageTestsWithBlobsEnabled, AnalyzeDotPyTest,
]:
suite.addTest(unittest.makeSuite(klass, "check"))
suite.addTest(doctest.DocTestSuite(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment