Skip to content

Commit f2530ec

Browse files
committed
better test
1 parent 4fd4027 commit f2530ec

1 file changed

Lines changed: 43 additions & 28 deletions

File tree

Lib/test/test_external_inspection.py

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -423,10 +423,16 @@ def _get_task_id_map(self, stack_trace):
423423
def _get_awaited_by_relationships(self, stack_trace):
424424
"""Extract task name to awaited_by set mapping."""
425425
id_to_task = self._get_task_id_map(stack_trace)
426+
427+
def task_name(task_id):
428+
task = id_to_task.get(task_id)
429+
if task is None:
430+
return f"<unknown object at {task_id:#x}>"
431+
return task.task_name
432+
426433
return {
427434
task.task_name: set(
428-
id_to_task[awaited.task_name].task_name
429-
for awaited in task.awaited_by
435+
task_name(awaited.task_name) for awaited in task.awaited_by
430436
)
431437
for task in stack_trace[0].awaited_by
432438
}
@@ -1476,33 +1482,34 @@ def matches_awaited_by_pattern(task):
14761482
sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
14771483
"Test only runs on Linux with process_vm_readv support",
14781484
)
1479-
def test_async_global_awaited_by_skips_set_tombstones(self):
1485+
def test_async_awaited_by_skips_set_tombstones(self):
14801486
script_body = """\
14811487
import asyncio
14821488
1483-
class HashedTask(asyncio.Task):
1484-
def __init__(self, coro, task_hash, **kwargs):
1485-
self.task_hash = task_hash
1486-
super().__init__(coro, **kwargs)
1489+
class RemovedTask(asyncio.Task):
1490+
def __hash__(self):
1491+
return 0
14871492
1493+
class RemainingTask(asyncio.Task):
14881494
def __hash__(self):
1489-
return self.task_hash
1495+
return 1
14901496
14911497
async def main():
1492-
victim = asyncio.create_task(
1493-
asyncio.sleep(10_000), name="victim"
1498+
victim = asyncio.current_task()
1499+
victim.set_name("victim")
1500+
removed = RemovedTask(
1501+
asyncio.sleep(10_000), name="removed"
14941502
)
1495-
removed = HashedTask(
1496-
asyncio.sleep(10_000), 0, name="removed"
1497-
)
1498-
remaining = HashedTask(
1499-
asyncio.sleep(10_000), 1, name="remaining"
1503+
remaining = RemainingTask(
1504+
asyncio.sleep(10_000), name="remaining"
15001505
)
15011506
15021507
asyncio.future_add_to_awaited_by(victim, removed)
15031508
asyncio.future_add_to_awaited_by(victim, remaining)
15041509
1505-
# Removing hash 0 leaves a dummy before the live hash-1 entry.
1510+
# Removing hash 0 leaves a dummy in slot 0 before the only
1511+
# active entry in slot 1. It must not count toward the set's
1512+
# used entries.
15061513
asyncio.future_discard_from_awaited_by(victim, removed)
15071514
15081515
sock.sendall(b"ready")
@@ -1511,20 +1518,28 @@ async def main():
15111518
asyncio.run(main())
15121519
"""
15131520

1514-
with self._target_process(script_body) as (p, client_socket, _):
1521+
with self._target_process(script_body) as (
1522+
_,
1523+
client_socket,
1524+
make_unwinder,
1525+
):
15151526
_wait_for_signal(client_socket, b"ready")
15161527

1517-
all_awaited_by = get_all_awaited_by(p.pid)
1518-
tasks_by_name = {
1519-
task.task_name: task
1520-
for task in self._get_task_id_map(all_awaited_by).values()
1521-
}
1522-
victim = tasks_by_name["victim"]
1523-
remaining = tasks_by_name["remaining"]
1524-
self.assertEqual(
1525-
[waiter.task_name for waiter in victim.awaited_by],
1526-
[remaining.task_id],
1527-
)
1528+
for method_name in (
1529+
"get_async_stack_trace",
1530+
"get_all_awaited_by",
1531+
):
1532+
with self.subTest(method=method_name):
1533+
unwinder = make_unwinder(cache_frames=False)
1534+
stack_trace = getattr(unwinder, method_name)()
1535+
relationships = self._get_awaited_by_relationships(
1536+
stack_trace
1537+
)
1538+
self.assertEqual(
1539+
relationships["victim"],
1540+
{"remaining"},
1541+
)
1542+
15281543
client_socket.sendall(b"done")
15291544

15301545
@skip_if_not_supported

0 commit comments

Comments
 (0)