55 lines
3.0 KiB
Python
55 lines
3.0 KiB
Python
import json
|
|
import unittest
|
|
import httpx
|
|
from services.background_tasks.opencode import OpenCodeExecutor
|
|
|
|
|
|
class OpenCodeTaskTest(unittest.IsolatedAsyncioTestCase):
|
|
async def test_correlated_completion_ignores_initial_idle_and_other_sessions(self):
|
|
handle = {"session_id": "ses_test", "message_id": "msg_test"}
|
|
submitted = False
|
|
snapshots = 0
|
|
updates = []
|
|
async def respond(request):
|
|
nonlocal submitted, snapshots
|
|
self.assertEqual(request.url.params["directory"], "/workspace/demo")
|
|
if request.url.path == "/event":
|
|
events = [
|
|
{"type": "session.idle", "properties": {"sessionID": "ses_other"}},
|
|
{"type": "session.idle", "properties": {"sessionID": "ses_test"}},
|
|
{"type": "message.updated", "properties": {"info": {"sessionID": "ses_test"}}},
|
|
]
|
|
return httpx.Response(200, text="".join("data: " + json.dumps(e) + "\n\n" for e in events))
|
|
if request.url.path.endswith("prompt_async"):
|
|
self.assertFalse(submitted)
|
|
self.assertEqual(json.loads(request.content)["messageID"], "msg_test")
|
|
submitted = True
|
|
return httpx.Response(204)
|
|
if request.url.path.endswith("/message"):
|
|
snapshots += 1
|
|
parent = "old_message" if snapshots == 1 else "msg_test"
|
|
return httpx.Response(200, json=[{"info": {"role": "assistant", "parentID": parent, "time": {"completed": 1}}, "parts": [{"type": "text", "text": "测试通过"}]}])
|
|
if request.url.path == "/session/status":
|
|
return httpx.Response(200, json={})
|
|
raise AssertionError(request.url)
|
|
executor = OpenCodeExecutor({"url": "https://remote.test", "directory": "/workspace/demo"}, {}, transport=httpx.MockTransport(respond))
|
|
async def emit(event):
|
|
updates.append(event)
|
|
result = await executor.run(handle, "修复测试", emit)
|
|
self.assertEqual(result["status"], "succeeded")
|
|
self.assertEqual(result["result"], "测试通过")
|
|
self.assertEqual(snapshots, 2)
|
|
self.assertEqual(updates[0]["status"], "submitted")
|
|
|
|
async def test_resume_reads_results_without_resubmitting(self):
|
|
async def respond(request):
|
|
self.assertEqual(request.method, "GET")
|
|
if request.url.path.endswith("/message"):
|
|
return httpx.Response(200, json=[{"info": {"role": "assistant", "parentID": "msg_test", "time": {"completed": 1}}, "parts": []}])
|
|
return httpx.Response(200, json={})
|
|
executor = OpenCodeExecutor({"url": "https://remote.test", "directory": "/demo"}, {}, transport=httpx.MockTransport(respond))
|
|
async def emit(event):
|
|
self.fail("completed task should not restart")
|
|
state = await executor.run({"session_id": "ses_test", "message_id": "msg_test"}, "ignored", emit, resume=True)
|
|
self.assertEqual(state["status"], "succeeded")
|