mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
feat(runner): implement builtin command session actions with start/inspect/read/cancel/overview
This commit is contained in:
@@ -90,4 +90,31 @@ class CommandExecutionServiceTest {
|
||||
Assertions.assertEquals(List.of("out"), result.getResultList());
|
||||
Assertions.assertEquals("out", result.getTotal());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateSessionTaskCollectsStdoutAndStderr() throws Exception {
|
||||
CommandExecutionService.CommandSession session = service.createSessionTask(
|
||||
"sh", "-lc", "printf 'hello\\nworld\\n'; printf 'oops\\n' >&2"
|
||||
);
|
||||
|
||||
session.getProcess().waitFor();
|
||||
waitForBufferContains(session.getStdoutBuffer(), "world");
|
||||
waitForBufferContains(session.getStderrBuffer(), "oops");
|
||||
|
||||
Assertions.assertEquals("hello\nworld", session.getStdoutBuffer().toString());
|
||||
Assertions.assertEquals("oops", session.getStderrBuffer().toString());
|
||||
}
|
||||
|
||||
private void waitForBufferContains(StringBuilder buffer, String expected) throws InterruptedException {
|
||||
long deadline = System.currentTimeMillis() + 2000;
|
||||
while (System.currentTimeMillis() < deadline) {
|
||||
synchronized (buffer) {
|
||||
if (buffer.toString().contains(expected)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Thread.sleep(20);
|
||||
}
|
||||
Assertions.fail("buffer did not contain expected text: " + expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package work.slhaf.partner.module.modules.action.builtin;
|
||||
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
class BuiltinCommandActionManagerTest {
|
||||
|
||||
@Test
|
||||
void testStartInspectReadAndOverview() throws Exception {
|
||||
BuiltinCommandActionManager manager = new BuiltinCommandActionManager();
|
||||
|
||||
String startResult = manager.buildCommandStartDefinition().invoker().apply(Map.of(
|
||||
"desc", "demo-session",
|
||||
"arg", "sh",
|
||||
"arg1", "-lc",
|
||||
"arg2", "printf 'hello\\nworld\\n'; printf 'oops\\n' >&2"
|
||||
));
|
||||
String executionId = JSONObject.parseObject(startResult).getString("executionId");
|
||||
Assertions.assertNotNull(executionId);
|
||||
|
||||
JSONObject inspect = waitForInspectExit(manager, executionId);
|
||||
Assertions.assertEquals("demo-session", inspect.getString("desc"));
|
||||
Assertions.assertEquals(0, inspect.getInteger("exitCode"));
|
||||
Assertions.assertTrue(inspect.getInteger("stdoutSize") > 0);
|
||||
Assertions.assertTrue(inspect.getInteger("stderrSize") > 0);
|
||||
Assertions.assertTrue(inspect.getString("stdoutSummary").contains("hello"));
|
||||
Assertions.assertTrue(inspect.getString("stderrSummary").contains("oops"));
|
||||
|
||||
JSONObject read = JSONObject.parseObject(manager.buildCommandReadDefinition().invoker().apply(Map.of(
|
||||
"id", executionId,
|
||||
"limit", 5
|
||||
)));
|
||||
Assertions.assertEquals("stdout", read.getString("stream"));
|
||||
Assertions.assertEquals(0, read.getIntValue("offset"));
|
||||
Assertions.assertEquals(5, read.getIntValue("nextOffset"));
|
||||
Assertions.assertTrue(read.getBooleanValue("contentTruncated"));
|
||||
Assertions.assertEquals("hello", read.getString("content"));
|
||||
|
||||
JSONObject overview = JSONObject.parseObject(manager.buildCommandOverviewDefinition().invoker().apply(Map.of()));
|
||||
JSONArray result = overview.getJSONArray("result");
|
||||
Assertions.assertTrue(result.stream().map(item -> (JSONObject) item)
|
||||
.anyMatch(item -> executionId.equals(item.getString("executionId"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCancelStopsBackgroundCommand() throws Exception {
|
||||
BuiltinCommandActionManager manager = new BuiltinCommandActionManager();
|
||||
|
||||
String startResult = manager.buildCommandStartDefinition().invoker().apply(Map.of(
|
||||
"desc", "sleep-session",
|
||||
"arg", "sh",
|
||||
"arg1", "-lc",
|
||||
"arg2", "sleep 5"
|
||||
));
|
||||
String executionId = JSONObject.parseObject(startResult).getString("executionId");
|
||||
|
||||
JSONObject cancel = JSONObject.parseObject(manager.buildCommandCancelDefinition().invoker().apply(Map.of(
|
||||
"id", executionId
|
||||
)));
|
||||
Assertions.assertEquals(executionId, cancel.getString("executionId"));
|
||||
Assertions.assertTrue(cancel.getBooleanValue("ok"));
|
||||
|
||||
JSONObject inspect = waitForInspectExit(manager, executionId);
|
||||
Assertions.assertNotNull(inspect.get("endAt"));
|
||||
}
|
||||
|
||||
private JSONObject waitForInspectExit(BuiltinCommandActionManager manager, String executionId) throws Exception {
|
||||
long deadline = System.currentTimeMillis() + 3000;
|
||||
while (System.currentTimeMillis() < deadline) {
|
||||
JSONObject inspect = JSONObject.parseObject(manager.buildCommandInspectDefinition().invoker().apply(Map.of(
|
||||
"id", executionId
|
||||
)));
|
||||
if (inspect.get("exitCode") != null) {
|
||||
return inspect;
|
||||
}
|
||||
Thread.sleep(20);
|
||||
}
|
||||
throw new AssertionError("command session did not exit in time");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user