46
51
def _collect_stats():
47
52
"Collect and return some dummy profile data."
48
ret, stats = lsprof.profile(_junk_callable)
53
from bzrlib.lsprof import profile
54
ret, stats = profile(_junk_callable)
52
class TestStats(tests.TestCaseInTempDir):
58
class TestStatsSave(tests.TestCaseInTempDir):
54
_test_needs_features = [features.lsprof_feature]
60
_test_needs_features = [LSProfFeature]
57
63
super(tests.TestCaseInTempDir, self).setUp()
58
64
self.stats = _collect_stats()
60
def _temppath(self, ext):
61
return osutils.pathjoin(self.test_dir, "tmp_profile_data." + ext)
63
def test_save_to_txt(self):
64
path = self._temppath("txt")
68
self.assertEqual(lines[0], _TXT_HEADER)
70
def test_save_to_callgrind(self):
71
path1 = self._temppath("callgrind")
72
self.stats.save(path1)
73
with open(path1) as f:
74
self.assertEqual(f.readline(), "events: Ticks\n")
76
path2 = osutils.pathjoin(self.test_dir, "callgrind.out.foo")
77
self.stats.save(path2)
78
with open(path2) as f:
79
self.assertEqual(f.readline(), "events: Ticks\n")
66
def _tempfile(self, ext):
68
return bzrlib.osutils.pathjoin(dir, "tmp_profile_data." + ext)
70
def test_stats_save_to_txt(self):
71
f = self._tempfile("txt")
73
lines = open(f).readlines()
74
self.assertEqual(lines[0], _TXT_HEADER)
76
def test_stats_save_to_callgrind(self):
77
f = self._tempfile("callgrind")
79
lines = open(f).readlines()
80
self.assertEqual(lines[0], "events: Ticks\n")
81
f = bzrlib.osutils.pathjoin(self.test_dir, "callgrind.out.foo")
83
lines = open(f).readlines()
84
self.assertEqual(lines[0], "events: Ticks\n")
81
85
# Test explicit format nommination
82
path3 = self._temppath("txt")
83
self.stats.save(path3, format="callgrind")
84
with open(path3) as f:
85
self.assertEqual(f.readline(), "events: Ticks\n")
87
def test_save_to_pickle(self):
88
path = self._temppath("pkl")
90
with open(path, 'rb') as f:
91
data1 = pickle.load(f)
92
self.assertEqual(type(data1), lsprof.Stats)
96
code_list = [d.inlinetime for d in self.stats.data]
97
self.assertEqual(code_list, sorted(code_list, reverse=True))
99
def test_sort_totaltime(self):
100
self.stats.sort('totaltime')
101
code_list = [d.totaltime for d in self.stats.data]
102
self.assertEqual(code_list, sorted(code_list, reverse=True))
104
def test_sort_code(self):
105
"""Cannot sort by code object would need to get filename etc."""
106
self.assertRaises(ValueError, self.stats.sort, 'code')
86
f2 = self._tempfile("txt")
87
self.stats.save(f2, format="callgrind")
88
lines2 = open(f2).readlines()
89
self.assertEqual(lines2[0], "events: Ticks\n")
91
def test_stats_save_to_pickle(self):
92
f = self._tempfile("pkl")
94
data1 = cPickle.load(open(f))
95
self.assertEqual(type(data1), bzrlib.lsprof.Stats)
109
98
class TestBzrProfiler(tests.TestCase):
111
_test_needs_features = [features.lsprof_feature]
100
_test_needs_features = [LSProfFeature]
113
102
def test_start_call_stuff_stop(self):
114
profiler = lsprof.BzrProfiler()
103
profiler = bzrlib.lsprof.BzrProfiler()
117
106
def a_function():
127
116
def test_block_0(self):
128
117
# When profiler_block is 0, reentrant profile requests fail.
129
self.overrideAttr(lsprof.BzrProfiler, 'profiler_block', 0)
118
self.overrideAttr(bzrlib.lsprof.BzrProfiler, 'profiler_block', 0)
133
profiler = lsprof.BzrProfiler()
121
profiler = bzrlib.lsprof.BzrProfiler()
134
122
self.assertRaises(errors.BzrError, profiler.start)
135
123
inner_calls.append(True)
136
lsprof.profile(inner)
124
bzrlib.lsprof.profile(inner)
137
125
self.assertLength(1, inner_calls)
139
127
def test_block_1(self):
140
128
# When profiler_block is 1, concurrent profiles serialise.
141
129
# This is tested by manually acquiring the profiler lock, then
142
# starting a thread that tries to profile, and releasing the lock.
130
# starting a thread that tries to profile, and releasing the lock.
143
131
# We know due to test_block_0 that two profiles at once hit the lock,
144
132
# so while this isn't perfect (we'd want a callback on the lock being
145
133
# entered to allow lockstep evaluation of the actions), its good enough
146
134
# to be confident regressions would be caught. Alternatively, if this
147
135
# is flakey, a fake Lock object can be used to trace the calls made.
151
138
calls.append('profiled')
153
139
def do_profile():
154
lsprof.profile(profiled)
140
bzrlib.lsprof.profile(profiled)
155
141
calls.append('after_profiled')
156
142
thread = threading.Thread(target=do_profile)
157
lsprof.BzrProfiler.profiler_lock.acquire()
143
bzrlib.lsprof.BzrProfiler.profiler_lock.acquire()
162
lsprof.BzrProfiler.profiler_lock.release()
148
bzrlib.lsprof.BzrProfiler.profiler_lock.release()
165
151
self.assertLength(2, calls)