blob: 559f75623f4f2ed65fe83cea29b46b4bd517934e [file] [log] [blame]
Georg Brandl4d4313d2009-05-05 08:54:11 +00001# A test suite for pdb; at the moment, this only validates skipping of
2# specified test modules (RFE #5142).
3
4import imp
Georg Brandl4d4313d2009-05-05 08:54:11 +00005import sys
Jason R. Coombs5d032c02011-11-17 18:03:24 -05006import os
7import unittest
8import subprocess
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +08009import textwrap
Georg Brandl4d4313d2009-05-05 08:54:11 +000010
11from test import test_support
12# This little helper class is essential for testing pdb under doctest.
13from test_doctest import _FakeInput
14
15
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +080016class PdbTestCase(unittest.TestCase):
17
18 def run_pdb(self, script, commands):
19 """Run 'script' lines with pdb and the pdb 'commands'."""
20 filename = 'main.py'
21 with open(filename, 'w') as f:
22 f.write(textwrap.dedent(script))
Georg Brandl9f9970b2012-05-06 11:53:51 +020023 self.addCleanup(test_support.unlink, filename)
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +080024 cmd = [sys.executable, '-m', 'pdb', filename]
25 stdout = stderr = None
26 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
27 stdin=subprocess.PIPE,
28 stderr=subprocess.STDOUT,
29 )
30 stdout, stderr = proc.communicate(commands)
31 proc.stdout.close()
32 proc.stdin.close()
33 return stdout, stderr
34
35 def test_issue13183(self):
36 script = """
37 from bar import bar
38
39 def foo():
40 bar()
41
42 def nope():
43 pass
44
45 def foobar():
46 foo()
47 nope()
48
49 foobar()
50 """
51 commands = """
52 from bar import bar
53 break bar
54 continue
55 step
56 step
57 quit
58 """
59 bar = """
60 def bar():
Senthil Kumarana9e18cd2012-05-02 07:59:36 +080061 pass
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +080062 """
63 with open('bar.py', 'w') as f:
64 f.write(textwrap.dedent(bar))
Georg Brandl9f9970b2012-05-06 11:53:51 +020065 self.addCleanup(test_support.unlink, 'bar.py')
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +080066 stdout, stderr = self.run_pdb(script, commands)
Georg Brandl9f9970b2012-05-06 11:53:51 +020067 self.assertTrue(
68 any('main.py(5)foo()->None' in l for l in stdout.splitlines()),
69 'Fail to step into the caller after a return')
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +080070
71
Georg Brandl6c39f062009-09-16 16:22:12 +000072class PdbTestInput(object):
73 """Context manager that makes testing Pdb in doctests easier."""
74
75 def __init__(self, input):
76 self.input = input
77
78 def __enter__(self):
79 self.real_stdin = sys.stdin
80 sys.stdin = _FakeInput(self.input)
81
82 def __exit__(self, *exc):
83 sys.stdin = self.real_stdin
84
85
Georg Brandl69dfe8d2009-09-16 16:36:39 +000086def write(x):
87 print x
88
89def test_pdb_displayhook():
90 """This tests the custom displayhook for pdb.
91
92 >>> def test_function(foo, bar):
93 ... import pdb; pdb.Pdb().set_trace()
94 ... pass
95
96 >>> with PdbTestInput([
97 ... 'foo',
98 ... 'bar',
99 ... 'for i in range(5): write(i)',
100 ... 'continue',
101 ... ]):
102 ... test_function(1, None)
103 > <doctest test.test_pdb.test_pdb_displayhook[0]>(3)test_function()
104 -> pass
105 (Pdb) foo
106 1
107 (Pdb) bar
108 (Pdb) for i in range(5): write(i)
109 0
110 1
111 2
112 3
113 4
114 (Pdb) continue
115 """
116
Senthil Kumaran9a5897b2010-11-29 12:41:03 +0000117def test_pdb_breakpoint_commands():
118 """Test basic commands related to breakpoints.
119
120 >>> def test_function():
121 ... import pdb; pdb.Pdb().set_trace()
122 ... print(1)
123 ... print(2)
124 ... print(3)
125 ... print(4)
126
127 First, need to clear bdb state that might be left over from previous tests.
128 Otherwise, the new breakpoints might get assigned different numbers.
129
130 >>> from bdb import Breakpoint
131 >>> Breakpoint.next = 1
132 >>> Breakpoint.bplist = {}
133 >>> Breakpoint.bpbynumber = [None]
134
135 Now test the breakpoint commands. NORMALIZE_WHITESPACE is needed because
136 the breakpoint list outputs a tab for the "stop only" and "ignore next"
137 lines, which we don't want to put in here.
138
139 >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE
140 ... 'break 3',
141 ... 'disable 1',
142 ... 'ignore 1 10',
143 ... 'condition 1 1 < 2',
144 ... 'break 4',
145 ... 'break 4',
146 ... 'break',
147 ... 'clear 3',
148 ... 'break',
149 ... 'condition 1',
150 ... 'enable 1',
151 ... 'clear 1',
152 ... 'commands 2',
153 ... 'print 42',
154 ... 'end',
155 ... 'continue', # will stop at breakpoint 2 (line 4)
156 ... 'clear', # clear all!
157 ... 'y',
158 ... 'tbreak 5',
159 ... 'continue', # will stop at temporary breakpoint
160 ... 'break', # make sure breakpoint is gone
161 ... 'continue',
162 ... ]):
163 ... test_function()
164 > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(3)test_function()
165 -> print(1)
166 (Pdb) break 3
167 Breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
168 (Pdb) disable 1
169 (Pdb) ignore 1 10
170 Will ignore next 10 crossings of breakpoint 1.
171 (Pdb) condition 1 1 < 2
172 (Pdb) break 4
173 Breakpoint 2 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
174 (Pdb) break 4
175 Breakpoint 3 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
176 (Pdb) break
177 Num Type Disp Enb Where
178 1 breakpoint keep no at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
179 stop only if 1 < 2
180 ignore next 10 hits
181 2 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
182 3 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
183 (Pdb) clear 3
184 Deleted breakpoint 3
185 (Pdb) break
186 Num Type Disp Enb Where
187 1 breakpoint keep no at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3
188 stop only if 1 < 2
189 ignore next 10 hits
190 2 breakpoint keep yes at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4
191 (Pdb) condition 1
192 Breakpoint 1 is now unconditional.
193 (Pdb) enable 1
194 (Pdb) clear 1
195 Deleted breakpoint 1
196 (Pdb) commands 2
197 (com) print 42
198 (com) end
199 (Pdb) continue
200 1
201 42
202 > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(4)test_function()
203 -> print(2)
204 (Pdb) clear
205 Clear all breaks? y
206 (Pdb) tbreak 5
207 Breakpoint 4 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:5
208 (Pdb) continue
209 2
210 Deleted breakpoint 4
211 > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(5)test_function()
212 -> print(3)
213 (Pdb) break
214 (Pdb) continue
215 3
216 4
217 """
218
Georg Brandl69dfe8d2009-09-16 16:36:39 +0000219
Georg Brandl4d4313d2009-05-05 08:54:11 +0000220def test_pdb_skip_modules():
221 """This illustrates the simple case of module skipping.
222
223 >>> def skip_module():
224 ... import string
Georg Brandl6c39f062009-09-16 16:22:12 +0000225 ... import pdb; pdb.Pdb(skip=['string*']).set_trace()
Georg Brandl4d4313d2009-05-05 08:54:11 +0000226 ... string.lower('FOO')
Georg Brandl4d4313d2009-05-05 08:54:11 +0000227
Georg Brandl6c39f062009-09-16 16:22:12 +0000228 >>> with PdbTestInput([
229 ... 'step',
Georg Brandl69dfe8d2009-09-16 16:36:39 +0000230 ... 'continue',
Georg Brandl6c39f062009-09-16 16:22:12 +0000231 ... ]):
Georg Brandl4d4313d2009-05-05 08:54:11 +0000232 ... skip_module()
Georg Brandl4d4313d2009-05-05 08:54:11 +0000233 > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()
234 -> string.lower('FOO')
235 (Pdb) step
236 --Return--
237 > <doctest test.test_pdb.test_pdb_skip_modules[0]>(4)skip_module()->None
238 -> string.lower('FOO')
239 (Pdb) continue
Georg Brandl6c39f062009-09-16 16:22:12 +0000240 """
Georg Brandl4d4313d2009-05-05 08:54:11 +0000241
242
243# Module for testing skipping of module that makes a callback
244mod = imp.new_module('module_to_skip')
245exec 'def foo_pony(callback): x = 1; callback(); return None' in mod.__dict__
246
247
248def test_pdb_skip_modules_with_callback():
249 """This illustrates skipping of modules that call into other code.
250
251 >>> def skip_module():
252 ... def callback():
253 ... return None
Georg Brandl6c39f062009-09-16 16:22:12 +0000254 ... import pdb; pdb.Pdb(skip=['module_to_skip*']).set_trace()
Georg Brandl4d4313d2009-05-05 08:54:11 +0000255 ... mod.foo_pony(callback)
Georg Brandl4d4313d2009-05-05 08:54:11 +0000256
Georg Brandl6c39f062009-09-16 16:22:12 +0000257 >>> with PdbTestInput([
258 ... 'step',
259 ... 'step',
260 ... 'step',
261 ... 'step',
262 ... 'step',
263 ... 'continue',
264 ... ]):
Georg Brandl4d4313d2009-05-05 08:54:11 +0000265 ... skip_module()
Georg Brandl6c39f062009-09-16 16:22:12 +0000266 ... pass # provides something to "step" to
Georg Brandl4d4313d2009-05-05 08:54:11 +0000267 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()
268 -> mod.foo_pony(callback)
269 (Pdb) step
270 --Call--
271 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(2)callback()
272 -> def callback():
273 (Pdb) step
274 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()
275 -> return None
276 (Pdb) step
277 --Return--
278 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(3)callback()->None
279 -> return None
280 (Pdb) step
281 --Return--
282 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[0]>(5)skip_module()->None
283 -> mod.foo_pony(callback)
284 (Pdb) step
Georg Brandl6c39f062009-09-16 16:22:12 +0000285 > <doctest test.test_pdb.test_pdb_skip_modules_with_callback[1]>(10)<module>()
286 -> pass # provides something to "step" to
Georg Brandl4d4313d2009-05-05 08:54:11 +0000287 (Pdb) continue
Georg Brandl6c39f062009-09-16 16:22:12 +0000288 """
Georg Brandl4d4313d2009-05-05 08:54:11 +0000289
290
Georg Brandl50775992010-08-01 19:33:15 +0000291def test_pdb_continue_in_bottomframe():
292 """Test that "continue" and "next" work properly in bottom frame (issue #5294).
293
294 >>> def test_function():
295 ... import pdb, sys; inst = pdb.Pdb()
296 ... inst.set_trace()
297 ... inst.botframe = sys._getframe() # hackery to get the right botframe
298 ... print(1)
299 ... print(2)
300 ... print(3)
301 ... print(4)
302
Senthil Kumaran9a5897b2010-11-29 12:41:03 +0000303 First, need to clear bdb state that might be left over from previous tests.
304 Otherwise, the new breakpoints might get assigned different numbers.
305
306 >>> from bdb import Breakpoint
307 >>> Breakpoint.next = 1
308 >>> Breakpoint.bplist = {}
309 >>> Breakpoint.bpbynumber = [None]
310
Georg Brandl50775992010-08-01 19:33:15 +0000311 >>> with PdbTestInput([
312 ... 'next',
313 ... 'break 7',
314 ... 'continue',
315 ... 'next',
316 ... 'continue',
317 ... 'continue',
318 ... ]):
319 ... test_function()
320 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(4)test_function()
321 -> inst.botframe = sys._getframe() # hackery to get the right botframe
322 (Pdb) next
323 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(5)test_function()
324 -> print(1)
325 (Pdb) break 7
326 Breakpoint 1 at <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>:7
327 (Pdb) continue
328 1
329 2
330 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(7)test_function()
331 -> print(3)
332 (Pdb) next
333 3
334 > <doctest test.test_pdb.test_pdb_continue_in_bottomframe[0]>(8)test_function()
335 -> print(4)
336 (Pdb) continue
337 4
338 """
339
Jason R. Coombs77cd2582011-12-08 22:14:56 -0500340class ModuleInitTester(unittest.TestCase):
Jason R. Coombs5d032c02011-11-17 18:03:24 -0500341
Jason R. Coombs77cd2582011-12-08 22:14:56 -0500342 def test_filename_correct(self):
343 """
344 In issue 7750, it was found that if the filename has a sequence that
345 resolves to an escape character in a Python string (such as \t), it
346 will be treated as the escaped character.
347 """
348 # the test_fn must contain something like \t
349 # on Windows, this will create 'test_mod.py' in the current directory.
350 # on Unix, this will create '.\test_mod.py' in the current directory.
351 test_fn = '.\\test_mod.py'
352 code = 'print("testing pdb")'
353 with open(test_fn, 'w') as f:
354 f.write(code)
355 self.addCleanup(os.remove, test_fn)
356 cmd = [sys.executable, '-m', 'pdb', test_fn,]
Jason R. Coombs5d032c02011-11-17 18:03:24 -0500357 proc = subprocess.Popen(cmd,
358 stdout=subprocess.PIPE,
359 stdin=subprocess.PIPE,
360 stderr=subprocess.STDOUT,
361 )
362 stdout, stderr = proc.communicate('quit\n')
Jason R. Coombs77cd2582011-12-08 22:14:56 -0500363 self.assertIn(code, stdout, "pdb munged the filename")
Jason R. Coombs5d032c02011-11-17 18:03:24 -0500364
Georg Brandl50775992010-08-01 19:33:15 +0000365
Georg Brandl4d4313d2009-05-05 08:54:11 +0000366def test_main():
367 from test import test_pdb
368 test_support.run_doctest(test_pdb, verbosity=True)
Senthil Kumaran7f6d4e12012-05-01 10:36:28 +0800369 test_support.run_unittest(
370 PdbTestCase,
371 ModuleInitTester)
Georg Brandl4d4313d2009-05-05 08:54:11 +0000372
373if __name__ == '__main__':
374 test_main()