1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | Lib/test/test_profile.py
"""Test suite for the profile module.""" import sys import pstats import unittest from StringIO import StringIO from test.test_support import run_unittest import profile from test.profilee import testfunc, timer class ProfileTest(unittest.TestCase): profilerclass = profile.Profile methodnames = ['print_stats', 'print_callers', 'print_callees'] expected_output = {} expected_list_sort_output = ':0(sort)' @classmethod def do_profiling(cls): results = [] prof = cls.profilerclass(timer, 0.001) start_timer = timer() prof.runctx("testfunc()", globals(), locals()) results.append(timer() - start_timer) for methodname in cls.methodnames: s = StringIO() stats = pstats.Stats(prof, stream=s) stats.strip_dirs().sort_stats("stdname") getattr(stats, methodname)() results.append(s.getvalue()) return results def test_cprofile(self): results = self.do_profiling() self.assertEqual(results[0], 1000) for i, method in enumerate(self.methodnames): self.assertEqual(results[i+1], self.expected_output[method], "Stats.%s output for %s doesn't fit expectation!" % (method, self.profilerclass.__name__)) def test_calling_conventions(self): # Issue #5330: profile and cProfile wouldn't report C functions called # with keyword arguments. We test all calling conventions. stmts = [ "[].sort()", "[].sort(reverse=True)", "[].sort(*(None, None, True))", "[].sort(**dict(reverse=True))", ] for stmt in stmts: s = StringIO() prof = self.profilerclass(timer, 0.001) prof.runctx(stmt, globals(), locals()) stats = pstats.Stats(prof, stream=s) stats.print_stats() res = s.getvalue() self.assertIn(self.expected_list_sort_output, res, "Profiling {0!r} didn't report list.sort:\n{1}".format(stmt, res)) def regenerate_expected_output(filename, cls): filename = filename.rstrip('co') print 'Regenerating %s...' % filename results = cls.do_profiling() newfile = [] with open(filename, 'r') as f: for line in f: newfile.append(line) if line[:6] == '#--cut': break with open(filename, 'w') as f: f.writelines(newfile) for i, method in enumerate(cls.methodnames): f.write('%s.expected_output[%r] = """\\\n%s"""\n' % ( cls.__name__, method, results[i+1])) f.write('\nif __name__ == "__main__":\n main()\n') def test_main(): run_unittest(ProfileTest) def main(): if '-r' not in sys.argv: test_main() else: regenerate_expected_output(__file__, ProfileTest) # Don't remove this comment. Everything below it is auto-generated. #--cut-------------------------------------------------------------------------- ProfileTest.expected_output['print_stats'] = """\ 127 function calls (107 primitive calls) in 999.749 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 4 -0.004 -0.001 -0.004 -0.001 :0(append) 4 -0.004 -0.001 -0.004 -0.001 :0(exc_info) 12 -0.024 -0.002 11.964 0.997 :0(hasattr) 8 -0.008 -0.001 -0.008 -0.001 :0(range) 1 0.000 0.000 0.000 0.000 :0(setprofile) 1 -0.002 -0.002 999.751 999.751 <string>:1(<module>) 0 0.000 0.000 profile:0(profiler) 1 -0.002 -0.002 999.749 999.749 profile:0(testfunc()) 28 27.972 0.999 27.972 0.999 profilee.py:110(__getattr__) 1 269.996 269.996 999.753 999.753 profilee.py:25(testfunc) 23/3 149.937 6.519 169.917 56.639 profilee.py:35(factorial) 20 19.980 0.999 19.980 0.999 profilee.py:48(mul) 2 39.986 19.993 599.814 299.907 profilee.py:55(helper) 4 115.984 28.996 119.964 29.991 profilee.py:73(helper1) 2 -0.006 -0.003 139.942 69.971 profilee.py:84(helper2_indirect) 8 311.976 38.997 399.896 49.987 profilee.py:88(helper2) 8 63.968 7.996 79.944 9.993 profilee.py:98(subhelper) """ ProfileTest.expected_output['print_callers'] = """\ Ordered by: standard name Function was called by... :0(append) <- profilee.py:73(helper1)(4) 119.964 :0(exc_info) <- profilee.py:73(helper1)(4) 119.964 :0(hasattr) <- profilee.py:73(helper1)(4) 119.964 profilee.py:88(helper2)(8) 399.896 :0(range) <- profilee.py:98(subhelper)(8) 79.944 :0(setprofile) <- profile:0(testfunc())(1) 999.749 <string>:1(<module>) <- profile:0(testfunc())(1) 999.749 profile:0(profiler) <- profile:0(testfunc()) <- profile:0(profiler)(1) 0.000 profilee.py:110(__getattr__) <- :0(hasattr)(12) 11.964 profilee.py:98(subhelper)(16) 79.944 profilee.py:25(testfunc) <- <string>:1(<module>)(1) 999.751 profilee.py:35(factorial) <- profilee.py:25(testfunc)(1) 999.753 profilee.py:35(factorial)(20) 169.917 profilee.py:84(helper2_indirect)(2) 139.942 profilee.py:48(mul) <- profilee.py:35(factorial)(20) 169.917 profilee.py:55(helper) <- profilee.py:25(testfunc)(2) 999.753 profilee.py:73(helper1) <- profilee.py:55(helper)(4) 599.814 profilee.py:84(helper2_indirect) <- profilee.py:55(helper)(2) 599.814 profilee.py:88(helper2) <- profilee.py:55(helper)(6) 599.814 profilee.py:84(helper2_indirect)(2) 139.942 profilee.py:98(subhelper) <- profilee.py:88(helper2)(8) 399.896 """ ProfileTest.expected_output['print_callees'] = """\ Ordered by: standard name Function called... :0(append) -> :0(exc_info) -> :0(hasattr) -> profilee.py:110(__getattr__)(12) 27.972 :0(range) -> :0(setprofile) -> <string>:1(<module>) -> profilee.py:25(testfunc)(1) 999.753 profile:0(profiler) -> profile:0(testfunc())(1) 999.749 profile:0(testfunc()) -> :0(setprofile)(1) 0.000 <string>:1(<module>)(1) 999.751 profilee.py:110(__getattr__) -> profilee.py:25(testfunc) -> profilee.py:35(factorial)(1) 169.917 profilee.py:55(helper)(2) 599.814 profilee.py:35(factorial) -> profilee.py:35(factorial)(20) 169.917 profilee.py:48(mul)(20) 19.980 profilee.py:48(mul) -> profilee.py:55(helper) -> profilee.py:73(helper1)(4) 119.964 profilee.py:84(helper2_indirect)(2) 139.942 profilee.py:88(helper2)(6) 399.896 profilee.py:73(helper1) -> :0(append)(4) -0.004 :0(exc_info)(4) -0.004 :0(hasattr)(4) 11.964 profilee.py:84(helper2_indirect) -> profilee.py:35(factorial)(2) 169.917 profilee.py:88(helper2)(2) 399.896 profilee.py:88(helper2) -> :0(hasattr)(8) 11.964 profilee.py:98(subhelper)(8) 79.944 profilee.py:98(subhelper) -> :0(range)(8) -0.008 profilee.py:110(__getattr__)(16) 27.972 """ if __name__ == "__main__": main() |