test: qualify keyed voice cancellation receipts
This commit is contained in:
1 parent
2ad9f36f4f
commit
0cb00e6095
1 file changed
+46
-2
@@ -116,7 +116,9 @@ class ConversationLLMTests(unittest.IsolatedAsyncioTestCase):
|
|||||||
await asyncio.gather(consumer, return_exceptions=True)
|
await asyncio.gather(consumer, return_exceptions=True)
|
||||||
self.assertEqual(len(payloads), 2)
|
self.assertEqual(len(payloads), 2)
|
||||||
self.assertEqual(payloads[0], payloads[1])
|
self.assertEqual(payloads[0], payloads[1])
|
||||||
self.assertEqual(cancelled_paths, ['/internal/chat/rooms/bound-room/runs/offline-recovered-id/cancel'])
|
self.assertEqual(cancelled_paths, [
|
||||||
|
'/internal/chat/rooms/bound-room/operations/' + context.items[-1].id + '/cancel',
|
||||||
|
'/internal/chat/rooms/bound-room/runs/offline-recovered-id/cancel'])
|
||||||
finally:
|
finally:
|
||||||
release.set()
|
release.set()
|
||||||
if not consumer.done(): consumer.cancel()
|
if not consumer.done(): consumer.cancel()
|
||||||
@@ -159,7 +161,9 @@ class ConversationLLMTests(unittest.IsolatedAsyncioTestCase):
|
|||||||
await asyncio.wait_for(asyncio.gather(closer, second_closer), 2)
|
await asyncio.wait_for(asyncio.gather(closer, second_closer), 2)
|
||||||
await asyncio.gather(consumer, return_exceptions=True)
|
await asyncio.gather(consumer, return_exceptions=True)
|
||||||
await asyncio.wait_for(cancelled.wait(), .3)
|
await asyncio.wait_for(cancelled.wait(), .3)
|
||||||
self.assertEqual(cancellations, ['/internal/chat/rooms/room/runs/offline-admitted-run/cancel'])
|
self.assertEqual(cancellations, [
|
||||||
|
'/internal/chat/rooms/room/operations/' + context.items[-1].id + '/cancel',
|
||||||
|
'/internal/chat/rooms/room/runs/offline-admitted-run/cancel'])
|
||||||
finally:
|
finally:
|
||||||
release_admission.set()
|
release_admission.set()
|
||||||
if closer and not closer.done():
|
if closer and not closer.done():
|
||||||
@@ -170,4 +174,44 @@ class ConversationLLMTests(unittest.IsolatedAsyncioTestCase):
|
|||||||
await asyncio.gather(consumer, return_exceptions=True)
|
await asyncio.gather(consumer, return_exceptions=True)
|
||||||
await bridge.aclose()
|
await bridge.aclose()
|
||||||
|
|
||||||
|
async def test_key_cancel_receipt_prevents_late_rejected_admission_action(self):
|
||||||
|
entered, release, tombstoned = asyncio.Event(), asyncio.Event(), asyncio.Event()
|
||||||
|
requests, progress_events = [], []
|
||||||
|
async def handler(request):
|
||||||
|
requests.append(request.url.path)
|
||||||
|
if request.url.path.endswith('/messages'):
|
||||||
|
entered.set()
|
||||||
|
await release.wait()
|
||||||
|
self.assertTrue(tombstoned.is_set(), 'Persist operation cancellation before admission settles')
|
||||||
|
return httpx.Response(409, json={'detail': 'Operation cancelled'})
|
||||||
|
if '/operations/' in request.url.path and request.url.path.endswith('/cancel'):
|
||||||
|
tombstoned.set()
|
||||||
|
return httpx.Response(200, json={'ok': True})
|
||||||
|
self.fail('A rejected cancelled operation must never stream or cancel an invented run')
|
||||||
|
async def progress(value): progress_events.append(value)
|
||||||
|
bridge = ConversationLLM(control_url='https://offline.test', secret='offline', room_id='bound-room', on_progress=progress)
|
||||||
|
await bridge.client.aclose()
|
||||||
|
bridge.client = httpx.AsyncClient(transport=httpx.MockTransport(handler))
|
||||||
|
context = llm.ChatContext([llm.ChatMessage(role='user', content=['Cancel before admission'])])
|
||||||
|
stream = bridge.chat(chat_ctx=context)
|
||||||
|
async def consume():
|
||||||
|
async with stream:
|
||||||
|
return [chunk async for chunk in stream]
|
||||||
|
consumer = asyncio.create_task(consume())
|
||||||
|
try:
|
||||||
|
await asyncio.wait_for(entered.wait(), 2)
|
||||||
|
closer = asyncio.create_task(stream.aclose())
|
||||||
|
await asyncio.wait_for(tombstoned.wait(), 2)
|
||||||
|
release.set()
|
||||||
|
await asyncio.wait_for(closer, 2)
|
||||||
|
await asyncio.gather(consumer, return_exceptions=True)
|
||||||
|
self.assertEqual(requests, ['/internal/chat/rooms/bound-room/messages',
|
||||||
|
'/internal/chat/rooms/bound-room/operations/' + context.items[-1].id + '/cancel'])
|
||||||
|
self.assertEqual(progress_events[-1]['status'], 'failed')
|
||||||
|
finally:
|
||||||
|
release.set()
|
||||||
|
if not consumer.done(): consumer.cancel()
|
||||||
|
await asyncio.gather(consumer, return_exceptions=True)
|
||||||
|
await bridge.aclose()
|
||||||
|
|
||||||
if __name__=='__main__': unittest.main()
|
if __name__=='__main__': unittest.main()
|
||||||
Reference in new issue
Block a user