Skip to content

Commit 15dd1d6

Browse files
committed
Add post_mortem unit tests.
1 parent c99aa15 commit 15dd1d6

1 file changed

Lines changed: 165 additions & 0 deletions

File tree

tests/debugpy/test_postmortem.py

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License. See LICENSE in the project root
3+
# for license information.
4+
import pytest
5+
6+
from tests import debug
7+
from tests.patterns import some
8+
from tests.timeline import Event
9+
10+
11+
def test_post_mortem_basic(pyfile, target, run):
12+
"""Calling post_mortem() inside an except block should stop the debugger."""
13+
14+
@pyfile
15+
def code_to_debug():
16+
import debuggee
17+
debuggee.setup()
18+
19+
import debugpy
20+
21+
def risky_operation():
22+
raise ValueError("something went wrong") # @raise
23+
24+
try:
25+
risky_operation()
26+
except ValueError:
27+
debugpy.post_mortem()
28+
29+
with debug.Session() as session:
30+
with run(session, target(code_to_debug)):
31+
session.request("setExceptionBreakpoints", {"filters": ["uncaught"]})
32+
33+
occ = session.wait_for_next(
34+
Event("stopped") | Event("terminated"),
35+
)
36+
37+
if occ.event == "terminated":
38+
pytest.fail("Debuggee exited without hitting breakpoint")
39+
40+
exc_info = session.request("exceptionInfo", {"threadId": occ.body['threadId']})
41+
assert exc_info == some.dict.containing(
42+
{
43+
"exceptionId": some.str.matching(r"(.+\.)?ValueError"),
44+
"description": "something went wrong",
45+
"breakMode": "unhandled",
46+
}
47+
)
48+
49+
session.request_continue()
50+
51+
def test_post_mortem_basic_no_uncaught_breakpoint(pyfile, target, run):
52+
"""We don't stop if the uncaught exception breakpoint isn't set."""
53+
54+
@pyfile
55+
def code_to_debug():
56+
import debuggee
57+
debuggee.setup()
58+
59+
import debugpy
60+
61+
def risky_operation():
62+
raise ValueError("something went wrong") # @raise
63+
64+
try:
65+
risky_operation()
66+
except ValueError:
67+
debugpy.post_mortem()
68+
69+
with debug.Session() as session:
70+
with run(session, target(code_to_debug)):
71+
session.request("setExceptionBreakpoints", {"filters": []})
72+
73+
occ = session.wait_for_next(
74+
Event("stopped") | Event("terminated"),
75+
)
76+
77+
assert occ.event == "terminated", "Expected debuggee to exit without hitting breakpoint"
78+
79+
def test_post_mortem_excinfo(pyfile, target, run):
80+
"""We can call post_mortem with an excinfo afterwards too."""
81+
82+
@pyfile
83+
def code_to_debug():
84+
import sys
85+
86+
import debuggee
87+
debuggee.setup()
88+
89+
import debugpy
90+
91+
def risky_operation():
92+
raise ValueError("something went wrong") # @raise
93+
94+
try:
95+
risky_operation()
96+
except ValueError:
97+
excinfo = sys.exc_info()
98+
99+
print("About to call post_mortem with excinfo")
100+
debugpy.post_mortem(excinfo)
101+
102+
103+
with debug.Session() as session:
104+
with run(session, target(code_to_debug)):
105+
session.request("setExceptionBreakpoints", {"filters": ["uncaught"]})
106+
107+
occ = session.wait_for_next(
108+
Event("stopped") | Event("terminated"),
109+
)
110+
111+
if occ.event == "terminated":
112+
pytest.fail("Debuggee exited without hitting breakpoint")
113+
114+
115+
exc_info = session.request("exceptionInfo", {"threadId": occ.body['threadId']})
116+
assert exc_info == some.dict.containing(
117+
{
118+
"exceptionId": some.str.matching(r"(.+\.)?ValueError"),
119+
"description": "something went wrong",
120+
"breakMode": "unhandled",
121+
}
122+
)
123+
124+
session.request_continue()
125+
126+
def test_post_mortem_not_as_uncaught(pyfile, target, run):
127+
"""Setting as_uncaught=False enters postmortem debugging even if the uncaught exception breakpoint isn't set."""
128+
129+
@pyfile
130+
def code_to_debug():
131+
import debuggee
132+
debuggee.setup()
133+
134+
import debugpy
135+
136+
def risky_operation():
137+
raise ValueError("something went wrong") # @raise
138+
139+
try:
140+
risky_operation()
141+
except ValueError:
142+
debugpy.post_mortem(as_uncaught=False)
143+
144+
145+
with debug.Session() as session:
146+
with run(session, target(code_to_debug)):
147+
session.request("setExceptionBreakpoints", {"filters": []})
148+
149+
occ = session.wait_for_next(
150+
Event("stopped") | Event("terminated"),
151+
)
152+
153+
if occ.event == "terminated":
154+
pytest.fail("Debuggee exited without hitting breakpoint")
155+
156+
exc_info = session.request("exceptionInfo", {"threadId": occ.body['threadId']})
157+
assert exc_info == some.dict.containing(
158+
{
159+
"exceptionId": some.str.matching(r"(.+\.)?ValueError"),
160+
"description": "something went wrong",
161+
"breakMode": "unhandled",
162+
}
163+
)
164+
165+
session.request_continue()

0 commit comments

Comments
 (0)