|
Patrick Uiterwijk |
571575 |
# -*- coding: utf-8 -*-
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
"""
|
|
Patrick Uiterwijk |
571575 |
(c) 2017 - Copyright Red Hat Inc
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
Authors:
|
|
Patrick Uiterwijk |
571575 |
Patrick Uiterwijk <puiterwijk@redhat.com></puiterwijk@redhat.com>
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
"""
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
import pprint
|
|
Patrick Uiterwijk |
571575 |
import os
|
|
Patrick Uiterwijk |
571575 |
import traceback
|
|
Patrick Uiterwijk |
571575 |
import types
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
import pygit2
|
|
Patrick Uiterwijk |
571575 |
import _pygit2
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
real_pygit2_repository = pygit2.Repository
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
TOTALS = {'walks': 0,
|
|
Patrick Uiterwijk |
571575 |
'steps': 0}
|
|
Patrick Uiterwijk |
571575 |
REQUESTS = []
|
|
Patrick Uiterwijk |
571575 |
STATS = {}
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
class PerfRepoMeta(type):
|
|
Patrick Uiterwijk |
571575 |
def __new__(cls, name, parents, dct):
|
|
Patrick Uiterwijk |
571575 |
# create a class_id if it's not specified
|
|
Patrick Uiterwijk |
571575 |
if 'class_id' not in dct:
|
|
Patrick Uiterwijk |
571575 |
dct['class_id'] = name.lower()
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
# we need to call type.__new__ to complete the initialization
|
|
Patrick Uiterwijk |
571575 |
return super(PerfRepoMeta, cls).__new__(cls, name, parents, dct)
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __getattr__(cls, attr):
|
|
Patrick Uiterwijk |
571575 |
real = getattr(real_pygit2_repository, attr)
|
|
Patrick Uiterwijk |
571575 |
if type(real).__name__ in ['function', 'builtin_function_or_method']:
|
|
Patrick Uiterwijk |
571575 |
def fake(*args, **kwargs):
|
|
Patrick Uiterwijk |
571575 |
return real(*args, **kwargs)
|
|
Patrick Uiterwijk |
571575 |
return fake
|
|
Patrick Uiterwijk |
571575 |
else:
|
|
Patrick Uiterwijk |
571575 |
return real
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
class FakeWalker(object):
|
|
Patrick Uiterwijk |
571575 |
def __init__(self, parent):
|
|
Patrick Uiterwijk |
571575 |
self.parent = parent
|
|
Patrick Uiterwijk |
571575 |
self.wid = STATS['counters']['walks']
|
|
Patrick Uiterwijk |
571575 |
STATS['counters']['walks'] += 1
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
STATS['walks'][self.wid] = {
|
|
Patrick Uiterwijk |
571575 |
'steps': 0,
|
|
Patrick Uiterwijk |
571575 |
'type': 'walker',
|
|
Patrick Uiterwijk |
571575 |
'init': traceback.extract_stack(limit=3)[0],
|
|
Patrick Uiterwijk |
571575 |
'iter': None}
|
|
Patrick Uiterwijk |
571575 |
TOTALS['walks'] += 1
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __getattr__(self, attr):
|
|
Patrick Uiterwijk |
571575 |
return getattr(self.parent, attr)
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __iter__(self):
|
|
Patrick Uiterwijk |
571575 |
STATS['walks'][self.wid]['iter'] = traceback.extract_stack(limit=2)[0]
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
return self
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def next(self):
|
|
Patrick Uiterwijk |
571575 |
STATS['walks'][self.wid]['steps'] += 1
|
|
Patrick Uiterwijk |
571575 |
TOTALS['steps'] += 1
|
|
Patrick Uiterwijk |
571575 |
resp = self.parent.next()
|
|
Patrick Uiterwijk |
571575 |
return resp
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
class FakeDiffHunk(object):
|
|
Patrick Uiterwijk |
571575 |
def __init__(self, parent):
|
|
Patrick Uiterwijk |
571575 |
self.parent = parent
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __getattr__(self, attr):
|
|
Patrick Uiterwijk |
571575 |
print 'Getting Fake Hunk %s' % attr
|
|
Patrick Uiterwijk |
571575 |
resp = getattr(self.parent, attr)
|
|
Patrick Uiterwijk |
571575 |
print 'Response: %s' % resp
|
|
Patrick Uiterwijk |
571575 |
return resp
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
class FakeDiffPatch(object):
|
|
Patrick Uiterwijk |
571575 |
def __init__(self, parent):
|
|
Patrick Uiterwijk |
571575 |
self.parent = parent
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __getattr__(self, attr):
|
|
Patrick Uiterwijk |
571575 |
if attr == 'hunks':
|
|
Patrick Uiterwijk |
571575 |
return [FakeDiffHunk(h) for h in self.parent.hunks]
|
|
Patrick Uiterwijk |
571575 |
return getattr(self.parent, attr)
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
class FakeDiffer(object):
|
|
Patrick Uiterwijk |
571575 |
def __init__(self, parent):
|
|
Patrick Uiterwijk |
571575 |
self.parent = parent
|
|
Patrick Uiterwijk |
571575 |
self.iter = None
|
|
Patrick Uiterwijk |
571575 |
self.did = STATS['counters']['diffs']
|
|
Patrick Uiterwijk |
571575 |
STATS['counters']['diffs'] += 1
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
STATS['diffs'][self.did] = {
|
|
Patrick Uiterwijk |
571575 |
'init': traceback.extract_stack(limit=3)[0],
|
|
Patrick Uiterwijk |
571575 |
'steps': 0,
|
|
Patrick Uiterwijk |
571575 |
'iter': None}
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __getattr__(self, attr):
|
|
Patrick Uiterwijk |
571575 |
return getattr(self.parent, attr)
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __dir__(self):
|
|
Patrick Uiterwijk |
571575 |
return dir(self.parent)
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __iter__(self):
|
|
Patrick Uiterwijk |
571575 |
STATS['diffs'][self.did]['iter'] = traceback.extract_stack(limit=2)[0]
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
self.iter = self.parent.__iter__()
|
|
Patrick Uiterwijk |
571575 |
return self
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def next(self):
|
|
Patrick Uiterwijk |
571575 |
STATS['diffs'][self.did]['steps'] += 1
|
|
Patrick Uiterwijk |
571575 |
resp = self.iter.next()
|
|
Patrick Uiterwijk |
571575 |
if isinstance(resp, _pygit2.Patch):
|
|
Patrick Uiterwijk |
571575 |
resp = FakeDiffPatch(resp)
|
|
Patrick Uiterwijk |
571575 |
else:
|
|
Patrick Uiterwijk |
571575 |
raise Exception('Unexpected %s returned from differ' % resp)
|
|
Patrick Uiterwijk |
571575 |
return resp
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __len__(self):
|
|
Patrick Uiterwijk |
571575 |
return len(self.parent)
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
class PerfRepo(object):
|
|
Patrick Uiterwijk |
571575 |
""" An utility class allowing to go around pygit2's inability to be
|
|
Patrick Uiterwijk |
571575 |
stable.
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
"""
|
|
Patrick Uiterwijk |
571575 |
__metaclass__ = PerfRepoMeta
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __init__(self, path):
|
|
Patrick Uiterwijk |
571575 |
STATS['repo_inits'].append((path, traceback.extract_stack(limit=2)[0]))
|
|
Patrick Uiterwijk |
571575 |
STATS['counters']['inits'] += 1
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
self.repo = real_pygit2_repository(path)
|
|
Patrick Uiterwijk |
571575 |
self.iter = None
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __getattr__(self, attr):
|
|
Patrick Uiterwijk |
571575 |
real = getattr(self.repo, attr)
|
|
Patrick Uiterwijk |
571575 |
if type(real) in [types.FunctionType,
|
|
Patrick Uiterwijk |
571575 |
types.BuiltinFunctionType,
|
|
Patrick Uiterwijk |
571575 |
types.BuiltinMethodType]:
|
|
Patrick Uiterwijk |
571575 |
def fake(*args, **kwargs):
|
|
Patrick Uiterwijk |
571575 |
resp = real(*args, **kwargs)
|
|
Patrick Uiterwijk |
571575 |
if isinstance(resp, _pygit2.Walker):
|
|
Patrick Uiterwijk |
571575 |
resp = FakeWalker(resp)
|
|
Patrick Uiterwijk |
571575 |
elif isinstance(resp, _pygit2.Diff):
|
|
Patrick Uiterwijk |
571575 |
resp = FakeDiffer(resp)
|
|
Patrick Uiterwijk |
571575 |
return resp
|
|
Patrick Uiterwijk |
571575 |
return fake
|
|
Patrick Uiterwijk |
571575 |
elif isinstance(real, dict):
|
|
Patrick Uiterwijk |
571575 |
real_getitem = real.__getitem__
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def fake_getitem(self, item):
|
|
Patrick Uiterwijk |
571575 |
return real_getitem(item)
|
|
Patrick Uiterwijk |
571575 |
real.__getitem__ = fake_getitem
|
|
Patrick Uiterwijk |
571575 |
return real
|
|
Patrick Uiterwijk |
571575 |
else:
|
|
Patrick Uiterwijk |
571575 |
return real
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __getitem__(self, item):
|
|
Patrick Uiterwijk |
571575 |
return self.repo.__getitem__(item)
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __contains__(self, item):
|
|
Patrick Uiterwijk |
571575 |
return self.repo.__contains__(item)
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def __iter__(self):
|
|
Patrick Uiterwijk |
571575 |
self.wid = STATS['counters']['walks']
|
|
Patrick Uiterwijk |
571575 |
STATS['counters']['walks'] += 1
|
|
Patrick Uiterwijk |
571575 |
STATS['walks'][self.wid] = {
|
|
Patrick Uiterwijk |
571575 |
'steps': 0,
|
|
Patrick Uiterwijk |
571575 |
'type': 'iter',
|
|
Patrick Uiterwijk |
571575 |
'iter': traceback.extract_stack(limit=3)[0]}
|
|
Patrick Uiterwijk |
571575 |
TOTALS['walks'] += 1
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
self.iter = self.repo.__iter__()
|
|
Patrick Uiterwijk |
571575 |
return self
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def next(self):
|
|
Patrick Uiterwijk |
571575 |
STATS['walks'][self.wid]['steps'] += 1
|
|
Patrick Uiterwijk |
571575 |
TOTALS['steps'] += 1
|
|
Patrick Uiterwijk |
571575 |
return self.iter.next()
|
|
Patrick Uiterwijk |
571575 |
|
|
Pierre-Yves Chibon |
79825b |
|
|
Patrick Uiterwijk |
571575 |
pygit2.Repository = PerfRepo
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def reset_stats():
|
|
Patrick Uiterwijk |
571575 |
"""Resets STATS to be clear for the next request."""
|
|
Patrick Uiterwijk |
571575 |
global STATS
|
|
Patrick Uiterwijk |
571575 |
STATS = {'walks': {},
|
|
Patrick Uiterwijk |
571575 |
'diffs': {},
|
|
Patrick Uiterwijk |
571575 |
'repo_inits': [],
|
|
Patrick Uiterwijk |
571575 |
'counters': {'walks': 0,
|
|
Patrick Uiterwijk |
571575 |
'diffs': 0,
|
|
Patrick Uiterwijk |
571575 |
'inits': 0}}
|
|
Patrick Uiterwijk |
571575 |
|
|
Pierre-Yves Chibon |
a34537 |
|
|
Patrick Uiterwijk |
571575 |
# Make sure we start blank
|
|
Patrick Uiterwijk |
571575 |
reset_stats()
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
def print_stats(response):
|
|
Patrick Uiterwijk |
571575 |
"""Finalizes stats for the current request, and prints them possibly."""
|
|
Patrick Uiterwijk |
571575 |
REQUESTS.append(STATS)
|
|
Patrick Uiterwijk |
571575 |
if not os.environ.get('PAGURE_PERFREPO_VERBOSE'):
|
|
Patrick Uiterwijk |
571575 |
return response
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
print 'Statistics:'
|
|
Patrick Uiterwijk |
571575 |
pprint.pprint(STATS)
|
|
Patrick Uiterwijk |
571575 |
|
|
Patrick Uiterwijk |
571575 |
return response
|