I wanted to post some code I had created earlier that generated profiling information during the repository unit tests. It is based on the older way of creating the repository in code, so for sure it would need updating.
import os, sys, tempfile, shutil
import tarfile, time
import profile, pstats
#import hotshot, hotshot.stats
from repository.persistence.XMLRepository import XMLRepository
class ProfileBase:
"""common setup routines for all profiling tests"""
def setupBase(self, testName, runCount = 100, createRepository = False, cleanupDir = True):
"""
Store common values, creates a temporary directory to run tests in and
if told to, builds a test repository.
@type testName: string
@param testName: base name used for repository and also for the
profile data filename.
@type runCount: integer
@param runCount: Number of times to run test. Default is 100.
@type createRepository: bool
@param createRepository: True if the repository is to be created by this class.
Default is False
@type createDir: bool
@param cleanupDir: True if the temporary directory should be removed after
the tests have run. Default is True.
@type ChandlerDir: string
@ivar ChandlerDir: Chandler Path
@type platform: string
@ivar platform: Hardware platform that test is being run on
@type testDir: string
@ivar testDir: Path to the temporary directory created to contain
any generated data.
@type repositoryFilename: string
@ivar repositoryFilename: Repository name.
@type repositoryName: string
@ivar repositoryName: Full path and name of the repository.
@type rep: XMLRepository
@ivar rep: Reference to the constructed repository.
@type profileFilename: string
@ivar profileFilename: Profile file name.
@type profileName: string
@ivar profileName: Full path and name of the profile data file.
@type statsFilename: string
@ivar statsFilename: Stats data file name.
@type statsName: string
@ivar statsName: Full path and name of the stats data file.
@type profiler: hotshot.Profile
@ivar profiler: Reference to the active hotshot Profile.
"""
self.testName = testName
self.runCount = runCount
self.createRepository = createRepository
self.cleanupDir = cleanupDir
self.ChandlerDir = os.environ['CHANDLERDIR']
self.runDate = time.strftime("
m%d", time.localtime())
# yes - copied from hardhatlib.py
if os.name == 'posix':
if sys.platform == 'darwin':
self.platform = 'osx'
else:
self.platform = 'linux'
else:
self.platform = 'win'
self.testDir = tempfile.mkdtemp()
self.repositoryFilename = self.testName
self.repositoryName = os.path.join(self.testDir, self.repositoryFilename)
if self.createRepository:
self.rep = XMLRepository(self.repositoryName)
self.rep.create()
schemaPack = os.path.join(self.ChandlerDir, 'repository', 'packs', 'schema.pack')
self.rep.loadPack(schemaPack)
self.rep.commit()
self.profileFilename = self.testName + '_' + self.runDate + '.profile'
self.profileName = os.path.join(self.testDir, self.profileFilename)
self.statsFilename = self.testName + '_' + self.runDate + '.stats'
self.statsName = os.path.join(self.testDir, self.statsFilename)
#self.profiler = hotshot.Profile(self.profileName)
def run(self, cmd):
#self.profiler.run(cmd)
profile.run(cmd, self.profileName)
def teardownBase(self, createProfileTarball = True):
"""
Cleans up any remaining mess from the test run.
If createProfileTarball is True, the generated profile data is written
to a common tarball that is named based on hardware platform and date.
@type createProfileTarball: bool
@param createProfileTarball: True if the profile data is to be added to the tarball.
Default is True.
"""
if self.createRepository:
self.rep.close()
self.rep.delete()
#self.profiler.close()
#stats = hotshot.stats.load(self.profileName)
stats = pstats.Stats(self.profileName)
statsFile = file(self.statsName, 'w+')
for func, (cc, numberCalls, totalTime, cumulativeTime, callers) in stats.stats.items():
if numberCalls == 0:
perCallTotal = ' '
else:
perCallTotal = '%8.3f' % (totalTime / numberCalls)
if cc != numberCalls:
calls = str(numberCalls) + '/' + str(cc)
else:
calls = str(numberCalls)
if cc == 0:
perCallCumulative = ' '
else:
perCallCumulative = '%8.3f' % (cumulativeTime / cc)
# functionPath = func[0], functionLine = func[1], functionName = func[2]
s = '%s | %s | %s | %s | %8.3f | %s | %8.3f | %s | %s | %d\n' %
(self.testName, self.runDate, func[2], calls, totalTime,
perCallTotal, cumulativeTime, perCallCumulative, func[0], func[1])
statsFile.write(s)
statsFile.close()
if createProfileTarball:
filename = 'profile_' + self.runDate + '.tar'
filename = os.path.join(self.ChandlerDir, filename)
if os.path.isfile(filename):
tar = tarfile.open(filename, "a")
else:
tar = tarfile.open(filename, "w")
tar.add(self.profileName, os.path.join(self.platform, self.profileFilename))
tar.add(self.statsName, os.path.join(self.platform, self.statsFilename))
tar.close()
if self.cleanupDir:
shutil.rmtree(self.testDir)