ยปCore Development>Code coverage>Lib/test/test_profile.py

Python code coverage for Lib/test/test_profile.py

#countcontent
1n/a"""Test suite for the profile module."""
2n/a
3n/aimport sys
4n/aimport pstats
5n/aimport unittest
6n/aimport os
7n/afrom difflib import unified_diff
8n/afrom io import StringIO
9n/afrom test.support import TESTFN, run_unittest, unlink
10n/afrom contextlib import contextmanager
11n/a
12n/aimport profile
13n/afrom test.profilee import testfunc, timer
14n/a
15n/a
16n/aclass ProfileTest(unittest.TestCase):
17n/a
18n/a profilerclass = profile.Profile
19n/a profilermodule = profile
20n/a methodnames = ['print_stats', 'print_callers', 'print_callees']
21n/a expected_max_output = ':0(max)'
22n/a
23n/a def tearDown(self):
24n/a unlink(TESTFN)
25n/a
26n/a def get_expected_output(self):
27n/a return _ProfileOutput
28n/a
29n/a @classmethod
30n/a def do_profiling(cls):
31n/a results = []
32n/a prof = cls.profilerclass(timer, 0.001)
33n/a start_timer = timer()
34n/a prof.runctx("testfunc()", globals(), locals())
35n/a results.append(timer() - start_timer)
36n/a for methodname in cls.methodnames:
37n/a s = StringIO()
38n/a stats = pstats.Stats(prof, stream=s)
39n/a stats.strip_dirs().sort_stats("stdname")
40n/a getattr(stats, methodname)()
41n/a output = s.getvalue().splitlines()
42n/a mod_name = testfunc.__module__.rsplit('.', 1)[1]
43n/a # Only compare against stats originating from the test file.
44n/a # Prevents outside code (e.g., the io module) from causing
45n/a # unexpected output.
46n/a output = [line.rstrip() for line in output if mod_name in line]
47n/a results.append('\n'.join(output))
48n/a return results
49n/a
50n/a def test_cprofile(self):
51n/a results = self.do_profiling()
52n/a expected = self.get_expected_output()
53n/a self.assertEqual(results[0], 1000)
54n/a for i, method in enumerate(self.methodnames):
55n/a if results[i+1] != expected[method]:
56n/a print("Stats.%s output for %s doesn't fit expectation!" %
57n/a (method, self.profilerclass.__name__))
58n/a print('\n'.join(unified_diff(
59n/a results[i+1].split('\n'),
60n/a expected[method].split('\n'))))
61n/a
62n/a def test_calling_conventions(self):
63n/a # Issue #5330: profile and cProfile wouldn't report C functions called
64n/a # with keyword arguments. We test all calling conventions.
65n/a stmts = [
66n/a "max([0])",
67n/a "max([0], key=int)",
68n/a "max([0], **dict(key=int))",
69n/a "max(*([0],))",
70n/a "max(*([0],), key=int)",
71n/a "max(*([0],), **dict(key=int))",
72n/a ]
73n/a for stmt in stmts:
74n/a s = StringIO()
75n/a prof = self.profilerclass(timer, 0.001)
76n/a prof.runctx(stmt, globals(), locals())
77n/a stats = pstats.Stats(prof, stream=s)
78n/a stats.print_stats()
79n/a res = s.getvalue()
80n/a self.assertIn(self.expected_max_output, res,
81n/a "Profiling {0!r} didn't report max:\n{1}".format(stmt, res))
82n/a
83n/a def test_run(self):
84n/a with silent():
85n/a self.profilermodule.run("int('1')")
86n/a self.profilermodule.run("int('1')", filename=TESTFN)
87n/a self.assertTrue(os.path.exists(TESTFN))
88n/a
89n/a def test_runctx(self):
90n/a with silent():
91n/a self.profilermodule.runctx("testfunc()", globals(), locals())
92n/a self.profilermodule.runctx("testfunc()", globals(), locals(),
93n/a filename=TESTFN)
94n/a self.assertTrue(os.path.exists(TESTFN))
95n/a
96n/a
97n/adef regenerate_expected_output(filename, cls):
98n/a filename = filename.rstrip('co')
99n/a print('Regenerating %s...' % filename)
100n/a results = cls.do_profiling()
101n/a
102n/a newfile = []
103n/a with open(filename, 'r') as f:
104n/a for line in f:
105n/a newfile.append(line)
106n/a if line.startswith('#--cut'):
107n/a break
108n/a
109n/a with open(filename, 'w') as f:
110n/a f.writelines(newfile)
111n/a f.write("_ProfileOutput = {}\n")
112n/a for i, method in enumerate(cls.methodnames):
113n/a f.write('_ProfileOutput[%r] = """\\\n%s"""\n' % (
114n/a method, results[i+1]))
115n/a f.write('\nif __name__ == "__main__":\n main()\n')
116n/a
117n/a@contextmanager
118n/adef silent():
119n/a stdout = sys.stdout
120n/a try:
121n/a sys.stdout = StringIO()
122n/a yield
123n/a finally:
124n/a sys.stdout = stdout
125n/a
126n/adef test_main():
127n/a run_unittest(ProfileTest)
128n/a
129n/adef main():
130n/a if '-r' not in sys.argv:
131n/a test_main()
132n/a else:
133n/a regenerate_expected_output(__file__, ProfileTest)
134n/a
135n/a
136n/a# Don't remove this comment. Everything below it is auto-generated.
137n/a#--cut--------------------------------------------------------------------------
138n/a_ProfileOutput = {}
139n/a_ProfileOutput['print_stats'] = """\
140n/a 28 27.972 0.999 27.972 0.999 profilee.py:110(__getattr__)
141n/a 1 269.996 269.996 999.769 999.769 profilee.py:25(testfunc)
142n/a 23/3 149.937 6.519 169.917 56.639 profilee.py:35(factorial)
143n/a 20 19.980 0.999 19.980 0.999 profilee.py:48(mul)
144n/a 2 39.986 19.993 599.830 299.915 profilee.py:55(helper)
145n/a 4 115.984 28.996 119.964 29.991 profilee.py:73(helper1)
146n/a 2 -0.006 -0.003 139.946 69.973 profilee.py:84(helper2_indirect)
147n/a 8 311.976 38.997 399.912 49.989 profilee.py:88(helper2)
148n/a 8 63.976 7.997 79.960 9.995 profilee.py:98(subhelper)"""
149n/a_ProfileOutput['print_callers'] = """\
150n/a:0(append) <- profilee.py:73(helper1)(4) 119.964
151n/a:0(exc_info) <- profilee.py:73(helper1)(4) 119.964
152n/a:0(hasattr) <- profilee.py:73(helper1)(4) 119.964
153n/a profilee.py:88(helper2)(8) 399.912
154n/aprofilee.py:110(__getattr__) <- :0(hasattr)(12) 11.964
155n/a profilee.py:98(subhelper)(16) 79.960
156n/aprofilee.py:25(testfunc) <- <string>:1(<module>)(1) 999.767
157n/aprofilee.py:35(factorial) <- profilee.py:25(testfunc)(1) 999.769
158n/a profilee.py:35(factorial)(20) 169.917
159n/a profilee.py:84(helper2_indirect)(2) 139.946
160n/aprofilee.py:48(mul) <- profilee.py:35(factorial)(20) 169.917
161n/aprofilee.py:55(helper) <- profilee.py:25(testfunc)(2) 999.769
162n/aprofilee.py:73(helper1) <- profilee.py:55(helper)(4) 599.830
163n/aprofilee.py:84(helper2_indirect) <- profilee.py:55(helper)(2) 599.830
164n/aprofilee.py:88(helper2) <- profilee.py:55(helper)(6) 599.830
165n/a profilee.py:84(helper2_indirect)(2) 139.946
166n/aprofilee.py:98(subhelper) <- profilee.py:88(helper2)(8) 399.912"""
167n/a_ProfileOutput['print_callees'] = """\
168n/a:0(hasattr) -> profilee.py:110(__getattr__)(12) 27.972
169n/a<string>:1(<module>) -> profilee.py:25(testfunc)(1) 999.769
170n/aprofilee.py:110(__getattr__) ->
171n/aprofilee.py:25(testfunc) -> profilee.py:35(factorial)(1) 169.917
172n/a profilee.py:55(helper)(2) 599.830
173n/aprofilee.py:35(factorial) -> profilee.py:35(factorial)(20) 169.917
174n/a profilee.py:48(mul)(20) 19.980
175n/aprofilee.py:48(mul) ->
176n/aprofilee.py:55(helper) -> profilee.py:73(helper1)(4) 119.964
177n/a profilee.py:84(helper2_indirect)(2) 139.946
178n/a profilee.py:88(helper2)(6) 399.912
179n/aprofilee.py:73(helper1) -> :0(append)(4) -0.004
180n/aprofilee.py:84(helper2_indirect) -> profilee.py:35(factorial)(2) 169.917
181n/a profilee.py:88(helper2)(2) 399.912
182n/aprofilee.py:88(helper2) -> :0(hasattr)(8) 11.964
183n/a profilee.py:98(subhelper)(8) 79.960
184n/aprofilee.py:98(subhelper) -> profilee.py:110(__getattr__)(16) 27.972"""
185n/a
186n/aif __name__ == "__main__":
187n/a main()