test: wait for messages instead of sleeping in the client flow
test_alice_and_bob paused for fixed 0.1-0.5 s between wiring events and asserting on the replies. On a slow runner the replies were not there yet; on a fast one the next step ran before the previous event was stored. Both show up as spurious failures (CI on #45, 2026-09-13). Give the mock socket a wait_for_messages(count) helper and wait for the expected number of messages at each step instead. Exact-count assertions stay, so extra messages still fail. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013Tbyw6FwjhEJg3gHfPHxWt (cherry picked from commit deb6510193b68f343c2f7845c615634beb020911)
This commit is contained in:
parent
06eab1b007
commit
d2350f907d
1 changed files with 31 additions and 18 deletions
|
|
@ -37,6 +37,18 @@ class MockWebSocket(WebSocket):
|
||||||
async def send_text(self, data: str):
|
async def send_text(self, data: str):
|
||||||
self.sent_messages.append(data)
|
self.sent_messages.append(data)
|
||||||
|
|
||||||
|
async def wait_for_messages(self, count: int, timeout: float = 5.0):
|
||||||
|
"""Wait until at least `count` messages were sent to this socket."""
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
deadline = loop.time() + timeout
|
||||||
|
while len(self.sent_messages) < count:
|
||||||
|
if loop.time() > deadline:
|
||||||
|
raise AssertionError(
|
||||||
|
f"Expected {count} messages, got {len(self.sent_messages)} "
|
||||||
|
f"after {timeout}s: {self.sent_messages}"
|
||||||
|
)
|
||||||
|
await asyncio.sleep(0.01)
|
||||||
|
|
||||||
async def wire_mock_data(self, data: dict):
|
async def wire_mock_data(self, data: dict):
|
||||||
await self.fake_wire.put(dumps(data))
|
await self.fake_wire.put(dumps(data))
|
||||||
|
|
||||||
|
|
@ -98,7 +110,7 @@ async def alice_wires_meta_and_post01(ws_alice: MockWebSocket):
|
||||||
await ws_alice.wire_mock_data(alice["post01"])
|
await ws_alice.wire_mock_data(alice["post01"])
|
||||||
await ws_alice.wire_mock_data(alice["post01"])
|
await ws_alice.wire_mock_data(alice["post01"])
|
||||||
await ws_alice.wire_mock_data(alice["meta_update"])
|
await ws_alice.wire_mock_data(alice["meta_update"])
|
||||||
await asyncio.sleep(0.5)
|
await ws_alice.wait_for_messages(4)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
len(ws_alice.sent_messages) == 4
|
len(ws_alice.sent_messages) == 4
|
||||||
|
|
@ -113,8 +125,6 @@ async def alice_wires_meta_and_post01(ws_alice: MockWebSocket):
|
||||||
alice["meta_update_response"]
|
alice["meta_update_response"]
|
||||||
), "Alice: Expected confirmation for meta update"
|
), "Alice: Expected confirmation for meta update"
|
||||||
|
|
||||||
await asyncio.sleep(0.1)
|
|
||||||
|
|
||||||
|
|
||||||
async def bob_wires_meta_and_folows_alice(ws_bob: MockWebSocket):
|
async def bob_wires_meta_and_folows_alice(ws_bob: MockWebSocket):
|
||||||
ws_bob.sent_messages.clear()
|
ws_bob.sent_messages.clear()
|
||||||
|
|
@ -122,8 +132,7 @@ async def bob_wires_meta_and_folows_alice(ws_bob: MockWebSocket):
|
||||||
await ws_bob.wire_mock_data(bob["meta"])
|
await ws_bob.wire_mock_data(bob["meta"])
|
||||||
await ws_bob.wire_mock_data(bob["request_meta_alice"])
|
await ws_bob.wire_mock_data(bob["request_meta_alice"])
|
||||||
await ws_bob.wire_mock_data(bob["request_posts_alice"])
|
await ws_bob.wire_mock_data(bob["request_posts_alice"])
|
||||||
|
await ws_bob.wait_for_messages(5)
|
||||||
await asyncio.sleep(0.5)
|
|
||||||
|
|
||||||
assert len(ws_bob.sent_messages) == 5, "Bob: Expected 5 confirmations to be sent"
|
assert len(ws_bob.sent_messages) == 5, "Bob: Expected 5 confirmations to be sent"
|
||||||
assert ws_bob.sent_messages[0] == dumps(
|
assert ws_bob.sent_messages[0] == dumps(
|
||||||
|
|
@ -149,9 +158,9 @@ async def bob_wires_contact_list(ws_alice: MockWebSocket, ws_bob: MockWebSocket)
|
||||||
|
|
||||||
await ws_bob.wire_mock_data(bob["contact_list_create"])
|
await ws_bob.wire_mock_data(bob["contact_list_create"])
|
||||||
await ws_bob.wire_mock_data(bob["contact_list_update"])
|
await ws_bob.wire_mock_data(bob["contact_list_update"])
|
||||||
await asyncio.sleep(0.1)
|
await ws_bob.wait_for_messages(2)
|
||||||
await ws_alice.wire_mock_data(alice["subscribe_to_bob_contact_list"])
|
await ws_alice.wire_mock_data(alice["subscribe_to_bob_contact_list"])
|
||||||
await asyncio.sleep(0.1)
|
await ws_alice.wait_for_messages(2)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
len(ws_bob.sent_messages) == 2
|
len(ws_bob.sent_messages) == 2
|
||||||
|
|
@ -181,7 +190,8 @@ async def alice_wires_post02_____bob_is_notified(
|
||||||
ws_alice.sent_messages.clear()
|
ws_alice.sent_messages.clear()
|
||||||
|
|
||||||
await ws_alice.wire_mock_data(alice["post02"])
|
await ws_alice.wire_mock_data(alice["post02"])
|
||||||
await asyncio.sleep(0.1)
|
await ws_alice.wait_for_messages(1)
|
||||||
|
await ws_bob.wait_for_messages(1)
|
||||||
|
|
||||||
assert ws_alice.sent_messages[0] == dumps(
|
assert ws_alice.sent_messages[0] == dumps(
|
||||||
alice["post02_response_ok"]
|
alice["post02_response_ok"]
|
||||||
|
|
@ -198,9 +208,9 @@ async def bob_likes_post01_____alice_subscribes_and_receives_notifications(
|
||||||
ws_bob.sent_messages.clear()
|
ws_bob.sent_messages.clear()
|
||||||
|
|
||||||
await ws_bob.wire_mock_data(bob["like_post01"])
|
await ws_bob.wire_mock_data(bob["like_post01"])
|
||||||
await asyncio.sleep(0.1)
|
await ws_bob.wait_for_messages(1)
|
||||||
await ws_alice.wire_mock_data(alice["subscribe_reactions_to_me"])
|
await ws_alice.wire_mock_data(alice["subscribe_reactions_to_me"])
|
||||||
await asyncio.sleep(0.1)
|
await ws_alice.wait_for_messages(2)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
len(ws_alice.sent_messages) == 2
|
len(ws_alice.sent_messages) == 2
|
||||||
|
|
@ -227,7 +237,8 @@ async def bob_likes_and_comments_____alice_receives_notifications(
|
||||||
|
|
||||||
await ws_bob.wire_mock_data(bob["like_post02"])
|
await ws_bob.wire_mock_data(bob["like_post02"])
|
||||||
await ws_bob.wire_mock_data(bob["comment_on_alice_post01"])
|
await ws_bob.wire_mock_data(bob["comment_on_alice_post01"])
|
||||||
await asyncio.sleep(0.5)
|
await ws_bob.wait_for_messages(2)
|
||||||
|
await ws_alice.wait_for_messages(2)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
len(ws_bob.sent_messages) == 2
|
len(ws_bob.sent_messages) == 2
|
||||||
|
|
@ -262,7 +273,8 @@ async def bob_writes_to_alice(ws_alice: MockWebSocket, ws_bob: MockWebSocket):
|
||||||
ws_bob.sent_messages.clear()
|
ws_bob.sent_messages.clear()
|
||||||
|
|
||||||
await ws_bob.wire_mock_data(bob["direct_message01"])
|
await ws_bob.wire_mock_data(bob["direct_message01"])
|
||||||
await asyncio.sleep(0.1)
|
await ws_bob.wait_for_messages(1)
|
||||||
|
await ws_alice.wait_for_messages(1)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
len(ws_bob.sent_messages) == 1
|
len(ws_bob.sent_messages) == 1
|
||||||
|
|
@ -287,7 +299,7 @@ async def alice_writes_to_bob(ws_alice: MockWebSocket, ws_bob: MockWebSocket):
|
||||||
ws_bob.sent_messages.clear()
|
ws_bob.sent_messages.clear()
|
||||||
|
|
||||||
await ws_alice.wire_mock_data(alice["direct_message01"])
|
await ws_alice.wire_mock_data(alice["direct_message01"])
|
||||||
await asyncio.sleep(0.1)
|
await ws_alice.wait_for_messages(1)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
len(ws_alice.sent_messages) == 1
|
len(ws_alice.sent_messages) == 1
|
||||||
|
|
@ -298,7 +310,7 @@ async def alice_writes_to_bob(ws_alice: MockWebSocket, ws_bob: MockWebSocket):
|
||||||
assert len(ws_bob.sent_messages) == 0, "Bob: no subscription, no message"
|
assert len(ws_bob.sent_messages) == 0, "Bob: no subscription, no message"
|
||||||
|
|
||||||
await ws_bob.wire_mock_data(bob["subscribe_to_direct_messages"])
|
await ws_bob.wire_mock_data(bob["subscribe_to_direct_messages"])
|
||||||
await asyncio.sleep(0.5)
|
await ws_bob.wait_for_messages(2)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
len(ws_bob.sent_messages) == 2
|
len(ws_bob.sent_messages) == 2
|
||||||
|
|
@ -321,7 +333,7 @@ async def alice_deletes_post01__bob_is_notified(
|
||||||
):
|
):
|
||||||
ws_bob.sent_messages.clear()
|
ws_bob.sent_messages.clear()
|
||||||
await ws_bob.wire_mock_data(bob["request_posts_alice"])
|
await ws_bob.wire_mock_data(bob["request_posts_alice"])
|
||||||
await asyncio.sleep(0.1)
|
await ws_bob.wait_for_messages(3)
|
||||||
assert (
|
assert (
|
||||||
len(ws_bob.sent_messages) == 3
|
len(ws_bob.sent_messages) == 3
|
||||||
), "Bob: Expected two posts from Alice plus and EOSE"
|
), "Bob: Expected two posts from Alice plus and EOSE"
|
||||||
|
|
@ -330,9 +342,10 @@ async def alice_deletes_post01__bob_is_notified(
|
||||||
ws_bob.sent_messages.clear()
|
ws_bob.sent_messages.clear()
|
||||||
|
|
||||||
await ws_bob.wire_mock_data(bob["subscribe_to_delete_from_alice"])
|
await ws_bob.wire_mock_data(bob["subscribe_to_delete_from_alice"])
|
||||||
await asyncio.sleep(0.1)
|
await ws_bob.wait_for_messages(1)
|
||||||
await ws_alice.wire_mock_data(alice["delete_post01"])
|
await ws_alice.wire_mock_data(alice["delete_post01"])
|
||||||
await asyncio.sleep(0.1)
|
await ws_alice.wait_for_messages(1)
|
||||||
|
await ws_bob.wait_for_messages(2)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
len(ws_alice.sent_messages) == 1
|
len(ws_alice.sent_messages) == 1
|
||||||
|
|
@ -353,7 +366,7 @@ async def alice_deletes_post01__bob_is_notified(
|
||||||
|
|
||||||
ws_bob.sent_messages.clear()
|
ws_bob.sent_messages.clear()
|
||||||
await ws_bob.wire_mock_data(bob["request_posts_alice"])
|
await ws_bob.wire_mock_data(bob["request_posts_alice"])
|
||||||
await asyncio.sleep(0.1)
|
await ws_bob.wait_for_messages(2)
|
||||||
assert (
|
assert (
|
||||||
len(ws_bob.sent_messages) == 2
|
len(ws_bob.sent_messages) == 2
|
||||||
), "Bob: Expected one posts from Alice plus and EOSE"
|
), "Bob: Expected one posts from Alice plus and EOSE"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue