Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2691)

Side by Side Diff: Lib/test/test_dtrace.py

Issue 13405: Add DTrace probes
Patch Set: Created 1 year, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Lib/test/dtrace_sample.py ('k') | Makefile.pre.in » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 import sys, unittest, subprocess, os.path, dis, types
2 from test.test_support import TESTFN, run_unittest, findfile
3
4 sample = os.path.abspath(findfile("dtrace_sample.py"))
5 v = sys.trace_instrumentation
6 if (v is None) or (v[0].lower() != "dtrace") :
7 raise unittest.SkipTest, "dtrace support not compiled in"
8
9 dscript = """
10 pid$target::PyEval_EvalCode:entry
11 """
12 dscript = dscript.replace("\r", "").replace("\n", "")
13 result, _ = subprocess.Popen(["dtrace", "-q", "-l", "-n", dscript,
14 "-c", "%s %s" %(sys.executable, sample)], stdout=subprocess.PIPE,
15 stderr=subprocess.STDOUT).communicate()
16 if result.split("\n")[1].split()[-2:] != ["PyEval_EvalCode", "entry"] :
17 result2 = repr(result)
18 raise unittest.SkipTest("dtrace seems not to be working. " + \
19 "Please, check your privileges. " +
20 "Result: " +result2)
21
22 class DTraceTestsNormal(unittest.TestCase) :
23 def setUp(self) :
24 self.optimize = False
25
26 def test_function_entry_return(self) :
27 dscript = """
28 python$target:::function-entry
29 /(copyinstr(arg0)=="%(path)s") &&
30 (copyinstr(arg1)=="test_entry_return_and_stack")/
31 {
32 self->trace = 1;
33 }
34 python$target:::function-entry,python$target:::function-return
35 /(copyinstr(arg0)=="%(path)s") && (self->trace)/
36 {
37 printf("**%%s*%%s*%%s*%%d\\n", probename, copyinstr(arg0),
38 copyinstr(arg1), arg2);
39 }
40 python$target:::function-return
41 /(copyinstr(arg0)=="%(path)s") &&
42 (copyinstr(arg1)=="test_entry_return_and_stack")/
43 {
44 self->trace = 0;
45 }
46 """ %{"path":sample}
47
48 dscript = dscript.replace("\r", "").replace("\n", "")
49 expected_result = """
50 **function-entry*%(path)s*test_entry_return_and_stack*25
51 **function-entry*%(path)s*function_1*6
52 **function-return*%(path)s*function_1*7
53 **function-entry*%(path)s*function_2*10
54 **function-entry*%(path)s*function_1*6
55 **function-return*%(path)s*function_1*7
56 **function-return*%(path)s*function_2*11
57 **function-entry*%(path)s*function_3*14
58 **function-return*%(path)s*function_3*15
59 **function-entry*%(path)s*function_4*18
60 **function-return*%(path)s*function_4*19
61 **function-entry*%(path)s*function_5*22
62 **function-return*%(path)s*function_5*23
63 **function-return*%(path)s*test_entry_return_and_stack*30
64 """ %{"path":sample}
65
66 command = "%s %s" %(sys.executable, sample)
67 if self.optimize :
68 command = "%s -OO %s" %(sys.executable, sample)
69 actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
70 dscript,
71 "-c", command],
72 stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
73
74 actual_result = actual_result.replace("\r", "").replace("\n",
75 "").replace(" ", "")
76 expected_result = expected_result.replace("\r", "").replace("\n",
77 "").replace(" ", "")
78 self.assertEqual(actual_result, expected_result)
79
80 def test_stack(self) :
81 dscript = """
82 python$target:::function-entry
83 /(copyinstr(arg0)=="%(path)s") &&
84 (copyinstr(arg1)=="test_entry_return_and_stack")/
85 {
86 self->trace = 1;
87 }
88 python$target:::function-entry
89 /(copyinstr(arg0)=="%(path)s") && (self->trace)/
90 {
91 printf("[x]");
92 jstack();
93 }
94 python$target:::function-return
95 /(copyinstr(arg0)=="%(path)s") &&
96 (copyinstr(arg1)=="test_entry_return_and_stack")/
97 {
98 self->trace = 0;
99 }
100 """ %{"path":sample}
101
102 dscript = dscript.replace("\r", "").replace("\n", "")
103 expected_result = """
104 [x]
105 [%(path)s:25(test_entry_return_and_stack)]
106 [x]
107 [%(path)s:6(function_1)]
108 [%(path)s:26(test_entry_return_and_stack)]
109 [x]
110 [%(path)s:10(function_2)]
111 [%(path)s:27(test_entry_return_and_stack)]
112 [x]
113 [%(path)s:6(function_1)]
114 [%(path)s:11(function_2)]
115 [%(path)s:27(test_entry_return_and_stack)]
116 [x]
117 [%(path)s:14(function_3)]
118 [%(path)s:28(test_entry_return_and_stack)]
119 [x]
120 [%(path)s:18(function_4)]
121 [%(path)s:29(test_entry_return_and_stack)]
122 [x]
123 [%(path)s:22(function_5)]
124 [%(path)s:30(test_entry_return_and_stack)]
125 """ %{"path":sample}
126
127 command = "%s %s" %(sys.executable, sample)
128 if self.optimize :
129 command = "%s -OO %s" %(sys.executable, sample)
130 actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
131 dscript,
132 "-c", command],
133 stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
134
135 actual_result = [i for i in actual_result.split("\n") if (("[" in i)
136 and not i.endswith(" (<module>) ]"))]
137 actual_result = "".join(actual_result)
138 actual_result = actual_result.replace("\r", "").replace("\n",
139 "").replace(" ", "")
140 expected_result = expected_result.replace("\r", "").replace("\n",
141 "").replace(" ", "")
142 self.assertEqual(actual_result, expected_result)
143
144 def test_garbage_collection(self) :
145 dscript = """
146 python$target:::gc-start,python$target:::gc-done
147 {
148 printf("**%s(%ld)\\n", probename, arg0);
149 }
150 """
151
152 dscript = dscript.replace("\r", "").replace("\n", "")
153 command = "%s %s" %(sys.executable, sample)
154 if self.optimize :
155 command = "%s -OO %s" %(sys.executable, sample)
156 actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
157 dscript,
158 "-c", command],
159 stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
160
161 actual_result = "".join(actual_result)
162 actual_result = actual_result.replace("\r", "").replace("\n",
163 "").replace(" ", "")
164 for i in xrange(10) :
165 actual_result = actual_result.replace(str(i), "")
166 expected_result = "**gc-start()**gc-done()" * \
167 actual_result.count("**gc-start()**")
168
169 self.assertEqual(actual_result, expected_result)
170
171 def test_verify_opcodes(self) :
172 # Verify that we are checking:
173 opcodes = set(["CALL_FUNCTION", "CALL_FUNCTION_VAR",
174 "CALL_FUNCTION_KW", "CALL_FUNCTION_VAR_KW"])
175 obj = compile(open(sample).read(), "sample", "exec")
176 class dump() :
177 def __init__(self) :
178 self.buf = []
179 def write(self, v) :
180 self.buf.append(v)
181
182 dump = dump()
183 stdout = sys.stdout
184 sys.stdout = dump
185 for i in obj.co_consts :
186 if isinstance(i, types.CodeType) and \
187 (i.co_name == 'test_entry_return_and_stack') :
188 dis.dis(i)
189 sys.stdout = stdout
190 dump = "\n".join(dump.buf)
191 dump = dump.replace("\r", "").replace("\n", "").split()
192 for i in dump :
193 opcodes.discard(i)
194 # Are we verifying all the relevant opcodes?
195 self.assertEqual(set(), opcodes) # Are we verifying all opcodes?
196
197 def test_line(self) :
198 dscript = """
199 python$target:::line
200 /(copyinstr(arg0)=="%(path)s") &&
201 (copyinstr(arg1)=="test_line")/
202 {
203 printf("**%%s*%%s*%%s*%%d\\n", probename, copyinstr(arg0),
204 copyinstr(arg1), arg2);
205 }
206 """ %{"path":sample}
207
208 dscript = dscript.replace("\r", "").replace("\n", "")
209 expected_result = """
210 **line*%(path)s*test_line*33
211 **line*%(path)s*test_line*34
212 **line*%(path)s*test_line*35
213 **line*%(path)s*test_line*36
214 **line*%(path)s*test_line*37
215 **line*%(path)s*test_line*38
216 **line*%(path)s*test_line*34
217 **line*%(path)s*test_line*35
218 **line*%(path)s*test_line*36
219 **line*%(path)s*test_line*37
220 **line*%(path)s*test_line*38
221 **line*%(path)s*test_line*34
222 **line*%(path)s*test_line*39
223 """ %{"path":sample}
224
225 command = "%s %s" %(sys.executable, sample)
226 if self.optimize :
227 command = "%s -OO %s" %(sys.executable, sample)
228 actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
229 dscript,
230 "-c", command],
231 stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
232
233 actual_result = actual_result.replace("\r", "").replace("\n",
234 "").replace(" ", "")
235 expected_result = expected_result.replace("\r", "").replace("\n",
236 "").replace(" ", "")
237 self.assertEqual(actual_result, expected_result)
238
239 def test_instance_creation_destruction(self) :
240 dscript = """
241 python$target:::function-entry
242 /(copyinstr(arg0)=="%(path)s") &&
243 (copyinstr(arg1)=="test_instance_creation_destruction")/
244 {
245 self->trace = 1;
246 }
247
248 python$target:::instance-new-start,
249 python$target:::instance-new-done,
250 python$target:::instance-delete-start,
251 python$target:::instance-delete-done
252 /self->trace/
253 {
254 printf("**%%s* (%%s.%%s)\\n", probename, copyinstr(arg1), copyinstr(arg0));
255 }
256
257 python$target:::function-return
258 /(copyinstr(arg0)=="%(path)s") &&
259 (copyinstr(arg1)=="test_instance_creation_destruction")/
260 {
261 self->trace = 0;
262 }
263 """ %{"path":sample}
264
265 dscript = dscript.replace("\r", "").replace("\n", "")
266 expected_result = """
267 **instance-new-start*(__main__.old_style_class)
268 **instance-new-done*(__main__.old_style_class)
269 **instance-delete-start*(__main__.old_style_class)
270 **instance-delete-done*(__main__.old_style_class)
271 **instance-new-start*(__main__.new_style_class)
272 **instance-new-done*(__main__.new_style_class)
273 **instance-delete-start*(__main__.new_style_class)
274 **instance-delete-done*(__main__.new_style_class)
275 **instance-new-start*(__main__.old_style_class)
276 **instance-new-done*(__main__.old_style_class)
277 **instance-new-start*(__main__.new_style_class)
278 **instance-new-done*(__main__.new_style_class)
279 **instance-delete-start*(__main__.old_style_class)
280 **instance-delete-done*(__main__.old_style_class)
281 **instance-delete-start*(__main__.new_style_class)
282 **instance-delete-done*(__main__.new_style_class)
283 """
284
285 command = "%s %s" %(sys.executable, sample)
286 if self.optimize :
287 command = "%s -OO %s" %(sys.executable, sample)
288 actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
289 dscript,
290 "-c", command],
291 stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
292
293 actual_result = actual_result.replace("\r", "").replace("\n",
294 "").replace(" ", "")
295 expected_result = expected_result.replace("\r", "").replace("\n",
296 "").replace(" ", "")
297 self.assertEqual(actual_result, expected_result)
298
299
300
301 # This class try to verify that dtrace probes
302 # are still working with optimizations enabled in the bytecode.
303 #
304 # Some tests will not actually verify it. For instance,
305 # source code compilation follows optimization status of
306 # current working Python. So, you should run the test
307 # both with an optimizing and a non optimizing Python.
308 class DTraceTestsOptimize(DTraceTestsNormal) :
309 def setUp(self) :
310 self.optimize = True
311
312
313 def test_main():
314 run_unittest(DTraceTestsNormal)
315 run_unittest(DTraceTestsOptimize)
316
317 if __name__ == '__main__':
318 test_main()
319
OLDNEW
« no previous file with comments | « Lib/test/dtrace_sample.py ('k') | Makefile.pre.in » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld cbc36f91f3f7