Commit | Line | Data |
---|---|---|
a2f4fe7d | 1 | import datetime, os, os.path, subprocess, sys |
5200ae3c KH |
2 | |
3 | def duration(t1, t2): | |
4 | d = t2 - t1 | |
5 | return 86400*d.days + d.seconds + 1e-6*d.microseconds | |
6 | ||
7 | class Run(object): | |
8 | def __init__(self): | |
9 | self.__cwd = None | |
10 | self.__log = [] | |
a2f4fe7d KH |
11 | def __logfile(self, cmd): |
12 | fn = os.path.join(os.getcwd(), '%04d.log' % len(self.__log)) | |
13 | f = open(fn, 'w') | |
14 | f.write(' '.join(cmd) + '\n' + '-'*70 + '\n\n') | |
15 | f.close() | |
16 | return fn | |
5200ae3c | 17 | def __call__(self, *cmd, **args): |
a2f4fe7d KH |
18 | env = dict(os.environ) |
19 | env['STGIT_SUBPROCESS_LOG'] = 'profile:' + self.__logfile(cmd) | |
20 | kwargs = { 'cwd': self.__cwd, 'env': env } | |
5200ae3c KH |
21 | if args.get('capture_stdout', False): |
22 | kwargs['stdout'] = subprocess.PIPE | |
23 | start = datetime.datetime.now() | |
24 | p = subprocess.Popen(cmd, **kwargs) | |
25 | (out, err) = p.communicate() | |
26 | stop = datetime.datetime.now() | |
27 | self.__log.append((cmd, duration(start, stop))) | |
28 | return out | |
29 | def cd(self, dir): | |
30 | self.__cwd = dir | |
31 | def summary(self): | |
32 | def pcmd(c): return ' '.join(c) | |
33 | def ptime(t): return '%.3f' % t | |
34 | (cs, times) = zip(*self.__log) | |
35 | ttime = sum(times) | |
36 | cl = max(len(pcmd(c)) for c in cs) | |
37 | tl = max(len(ptime(t)) for t in list(times) + [ttime]) | |
38 | for (c, t) in self.__log: | |
39 | print '%*s %*s' % (tl, ptime(t), -cl, pcmd(c)) | |
40 | print '%*s' % (tl, ptime(ttime)) | |
41 | ||
42 | perftests = {} | |
43 | perftestdesc = {} | |
44 | def perftest(desc, name = None): | |
45 | def decorator(f): | |
46 | def g(): | |
47 | r = Run() | |
48 | f(r) | |
49 | r.summary() | |
50 | perftests[name or f.__name__] = g | |
51 | perftestdesc[name or f.__name__] = desc | |
52 | return g | |
53 | return decorator | |
54 | ||
55 | def copy_testdir(dir): | |
56 | tmp = dir + '.trash' | |
57 | r = Run() | |
58 | r('rsync', '-a', '--delete', dir + '.orig/', tmp) | |
59 | return tmp | |
60 | ||
61 | def new_rebase(r, ref): | |
62 | top = r('stg', 'top', capture_stdout = True) | |
63 | r('stg', 'pop', '-a') | |
64 | r('git', 'reset', '--hard', ref) | |
65 | r('stg', 'goto', top.strip()) | |
66 | ||
67 | def old_rebase(r, ref): | |
68 | r('stg', 'rebase', ref) | |
69 | ||
70 | def def_rebasetest(rebase, dir, tag): | |
71 | @perftest('%s rebase onto %s in %s' % (rebase, tag, dir), | |
72 | 'rebase-%srebase-%s-%s' % (rebase, tag, dir)) | |
73 | def rebasetest(r): | |
74 | r.cd(copy_testdir(dir)) | |
75 | r('stg', 'init') | |
76 | if dir == 'synt': | |
77 | r('stg', 'uncommit', '-n', '500') | |
78 | else: | |
79 | r('stg', 'uncommit', '-x', '-t', 'bomb-base') | |
80 | if rebase == 'new': | |
81 | new_rebase(r, tag) | |
82 | else: | |
83 | old_rebase(r, tag) | |
84 | for rebase in ['old', 'new']: | |
85 | for (dir, tag) in [('synt', 'add-file'), | |
86 | ('synt', 'modify-all'), | |
87 | ('linux', 'add-file')]: | |
88 | def_rebasetest(rebase, dir, tag) | |
89 | ||
90 | args = sys.argv[1:] | |
91 | if len(args) == 0: | |
92 | for (fun, desc) in sorted(perftestdesc.iteritems()): | |
93 | print '%s: %s' % (fun, desc) | |
94 | else: | |
95 | for test in args: | |
96 | perftests[test]() |