8000 gh-135371: Fix Raspbian external inspection · python/cpython@fce1ca4 · GitHub
[go: up one dir, main page]

Skip to content

Commit fce1ca4

Browse files
committed
gh-135371: Fix Raspbian external inspection
1 parent 2bd3895 commit fce1ca4

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

Lib/test/test_external_inspection.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,100 @@ def foo():
144144
else:
145145
self.fail("Main thread stack trace not found in result")
146146

147+
@skip_if_not_supported
148+
@unittest.skipIf(
149+
sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
150+
"Test only runs on Linux with process_vm_readv support",
151+
)
152+
def test_async_remote_stack_trace_all_tasks(self):
153+
port = find_unused_port()
154+
script = textwrap.dedent(
155+
f"""\
156+
import asyncio
157+
import time
158+
import sys
159+
import socket
160+
# Connect to the test process
161+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
162+
sock.connect(('localhost', {port}))
163+
164+
def c5():
165+
sock.sendall(b"ready"); time.sleep(10_000) # same line number
166+
167+
async def c4():
168+
await asyncio.sleep(0)
169+
c5()
170+
171+
async def c3():
172+
await c4()
173+
174+
async def c2():
175+
await c3()
176+
177+
async def c1(task):
178+
await task
179+
180+
async def main():
181+
async with asyncio.TaskGroup() as tg:
182+
task = tg.create_task(c2(), name="c2_root")
183+
tg.create_task(c1(task), name="sub_main_1")
184+
tg.create_task(c1(task), name="sub_main_2")
185+
186+
def new_eager_loop():
187+
loop = asyncio.new_event_loop()
188+
eager_task_factory = asyncio.create_eager_task_factory(
189+
asyncio.Task)
190+
loop.set_task_factory(eager_task_factory)
191+
return loop
192+
193+
asyncio.run(main(), loop_factory={{TASK_FACTORY}})
194+
"""
195+
)
196+
stack_trace = None
197+
for task_factory_variant in "asyncio.new_event_loop", "new_eager_loop":
198+
with (
199+
self.subTest(task_factory_variant=task_factory_variant),
200+
os_helper.temp_dir() as work_dir,
201+
):
202+
script_dir = os.path.join(work_dir, "script_pkg")
203+
os.mkdir(script_dir)
204+
server_socket = socket.socket(
205+
socket.AF_INET, socket.SOCK_STREAM
206+
)
207+
server_socket.setsockopt(
208+
socket.SOL_SOCKET, socket.SO_REUSEADDR, 1
209+
)
210+
server_socket.bind(("localhost", port))
211+
server_socket.settimeout(SHORT_TIMEOUT)
212+
server_socket.listen(1)
213+
script_name = _make_test_script(
214+
script_dir,
215+
"script",
216+
script.format(TASK_FACTORY=task_factory_variant),
217+
)
218+
client_socket = None
219+
try:
220+
p = subprocess.Popen([sys.executable, script_name])
221+
client_socket, _ = server_socket.accept()
222+
server_socket.close()
223+
response = client_socket.recv(1024)
224+
self.assertEqual(response, b"ready")
225+
stack_trace = get_all_awaited_by(p.pid)
226+
except PermissionError:
227+
self.skipTest(
228+
"Insufficient permissions to read the stack trace"
229+
)
230+
finally:
231+
if client_socket is not None:
232+
client_socket.close()
233+
p.kill()
234+
p.terminate()
235+
p.wait(timeout=SHORT_TIMEOUT)
236+
237+
self.assertGreater(len(stack_trace), 0)
238+
239+
240+
147241
@skip_if_not_supported
148242
@unittest.skipIf(
149243
sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,

0 commit comments

Comments
 (0)
0