mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
fix(LocalRunnerClient): harden doRun branches and add tests
This commit is contained in:
@@ -222,6 +222,10 @@ public class LocalRunnerClient extends RunnerClient {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
String[] commands = SystemExecHelper.buildCommands(ext, metaAction.getParams(), file.getAbsolutePath());
|
String[] commands = SystemExecHelper.buildCommands(ext, metaAction.getParams(), file.getAbsolutePath());
|
||||||
|
if (commands == null || commands.length == 0) {
|
||||||
|
response.setOk(false);
|
||||||
|
response.setData("不支持的文件类型: " + file.getName());
|
||||||
|
}
|
||||||
SystemExecHelper.Result execResult = SystemExecHelper.exec(commands);
|
SystemExecHelper.Result execResult = SystemExecHelper.exec(commands);
|
||||||
response.setOk(execResult.isOk());
|
response.setOk(execResult.isOk());
|
||||||
response.setData(execResult.getTotal());
|
response.setData(execResult.getTotal());
|
||||||
@@ -236,7 +240,12 @@ public class LocalRunnerClient extends RunnerClient {
|
|||||||
.arguments(metaAction.getParams())
|
.arguments(metaAction.getParams())
|
||||||
.build();
|
.build();
|
||||||
McpSchema.CallToolResult callToolResult = mcpClient.callTool(callToolRequest);
|
McpSchema.CallToolResult callToolResult = mcpClient.callTool(callToolRequest);
|
||||||
response.setOk(callToolResult.isError());
|
val callToolResultError = callToolResult.isError();
|
||||||
|
if (callToolResultError == null) {
|
||||||
|
response.setOk(false);
|
||||||
|
} else {
|
||||||
|
response.setOk(!callToolResultError);
|
||||||
|
}
|
||||||
response.setData(callToolResult.structuredContent().toString());
|
response.setData(callToolResult.structuredContent().toString());
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -1234,7 +1243,7 @@ public class LocalRunnerClient extends RunnerClient {
|
|||||||
val httpKeys = Set.of("uri", "endpoint", "headers");
|
val httpKeys = Set.of("uri", "endpoint", "headers");
|
||||||
val httpKey = Set.of("url");
|
val httpKey = Set.of("url");
|
||||||
val keys = mcp.keySet();
|
val keys = mcp.keySet();
|
||||||
val timeout = mcp.getInt("timeout", 10);
|
val timeout = mcp.getInt("timeout", 30);
|
||||||
|
|
||||||
if (keys.equals(stdioKeys)) {
|
if (keys.equals(stdioKeys)) {
|
||||||
val command = mcp.getStr("command");
|
val command = mcp.getStr("command");
|
||||||
|
|||||||
@@ -5,16 +5,15 @@ import org.junit.jupiter.api.Assertions;
|
|||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
import work.slhaf.partner.core.action.entity.MetaAction;
|
||||||
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
||||||
|
import work.slhaf.partner.core.action.entity.MetaActionType;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
@@ -177,6 +176,15 @@ public class LocalRunnerClientTest {
|
|||||||
+ " \"env\": {}\n"
|
+ " \"env\": {}\n"
|
||||||
+ " }";
|
+ " }";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaAction buildMetaAction(MetaActionType type, String location, String name, Map<String, Object> params) {
|
||||||
|
MetaAction metaAction = new MetaAction();
|
||||||
|
metaAction.setType(type);
|
||||||
|
metaAction.setLocation(location);
|
||||||
|
metaAction.setName(name);
|
||||||
|
metaAction.setParams(params);
|
||||||
|
return metaAction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@@ -762,4 +770,89 @@ public class LocalRunnerClientTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class DoRunTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDoRunWithOriginUnknownExt(@TempDir Path tempDir) throws IOException {
|
||||||
|
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
||||||
|
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
LocalRunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
|
||||||
|
|
||||||
|
try {
|
||||||
|
Path script = tempDir.resolve("run");
|
||||||
|
Files.writeString(script, "echo ok\n");
|
||||||
|
MetaAction metaAction = buildMetaAction(MetaActionType.ORIGIN, script.toString(), "run", Map.of());
|
||||||
|
RunnerClient.RunnerResponse response = client.doRun(metaAction);
|
||||||
|
Assertions.assertNotNull(response);
|
||||||
|
Assertions.assertFalse(response.isOk());
|
||||||
|
Assertions.assertEquals("未知文件类型", response.getData());
|
||||||
|
} finally {
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDoRunWithOriginScriptSuccess(@TempDir Path tempDir) throws IOException {
|
||||||
|
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
||||||
|
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
LocalRunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
|
||||||
|
|
||||||
|
try {
|
||||||
|
Path script = tempDir.resolve("run.sh");
|
||||||
|
Files.writeString(script, "echo ok\n");
|
||||||
|
MetaAction metaAction = buildMetaAction(MetaActionType.ORIGIN, script.toString(), "run", Map.of());
|
||||||
|
RunnerClient.RunnerResponse response = client.doRun(metaAction);
|
||||||
|
Assertions.assertNotNull(response);
|
||||||
|
Assertions.assertTrue(response.isOk());
|
||||||
|
Assertions.assertTrue(response.getData().contains("ok"));
|
||||||
|
} finally {
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDoRunWithMcpMissingClient(@TempDir Path tempDir) {
|
||||||
|
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
||||||
|
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
LocalRunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
|
||||||
|
|
||||||
|
try {
|
||||||
|
MetaAction metaAction = buildMetaAction(MetaActionType.MCP, "missing-client", "missing-tool", Map.of());
|
||||||
|
RunnerClient.RunnerResponse response = client.doRun(metaAction);
|
||||||
|
Assertions.assertNotNull(response);
|
||||||
|
Assertions.assertFalse(response.isOk());
|
||||||
|
} finally {
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDoRunWithMcpLoadedFromCommonConfig(@TempDir Path tempDir) throws IOException, InterruptedException {
|
||||||
|
ConcurrentHashMap<String, MetaActionInfo> existedMetaActions = new ConcurrentHashMap<>();
|
||||||
|
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||||
|
|
||||||
|
Path mcpDir = tempDir.resolve("action").resolve("mcp");
|
||||||
|
Files.createDirectories(mcpDir);
|
||||||
|
Path configFile = mcpDir.resolve("servers.json");
|
||||||
|
String config = buildCommonMcpConfig(
|
||||||
|
buildStdioServerEntry("playwright", "@playwright/mcp@latest")
|
||||||
|
);
|
||||||
|
writeCommonMcpConfig(configFile, config);
|
||||||
|
|
||||||
|
LocalRunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
|
||||||
|
|
||||||
|
try {
|
||||||
|
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000);
|
||||||
|
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")));
|
||||||
|
|
||||||
|
MetaAction metaAction = buildMetaAction(MetaActionType.MCP, "playwright", "browser_navigate", Map.of("url", "https://deepwiki.com/microsoft/vscode"));
|
||||||
|
client.run(metaAction);
|
||||||
|
Assertions.assertNotEquals(MetaAction.ResultStatus.WAITING, metaAction.getResult().getStatus());
|
||||||
|
} finally {
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user