Initial library commit

This commit was merged in pull request #2.
This commit is contained in:
shahondin1624
2026-02-07 08:58:54 +01:00
committed by shahondin1624
parent 92adbc9515
commit 3da5013cbc
8 changed files with 668 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
package mcp.server;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import mcp.registry.ToolRegistry;
import mcp.tools.McpTool;
import mcp.util.Err;
import mcp.util.Ok;
import mcp.util.Result;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.*;
public class ToolRegistrationServletTest {
private ToolRegistry toolRegistry;
private HttpServletRequest request;
private HttpServletResponse response;
private StringWriter responseWriter;
@BeforeEach
void setUp() throws IOException {
toolRegistry = new ToolRegistry(java.util.Set.of());
request = mock(HttpServletRequest.class);
response = mock(HttpServletResponse.class);
responseWriter = new StringWriter();
when(response.getWriter()).thenReturn(new PrintWriter(responseWriter));
}
@Test
void testDoPostSuccess() throws Exception {
McpTool mockTool = mock(McpTool.class);
when(mockTool.name()).thenReturn("EchoTool");
// Use anonymous subclass instead of spy to avoid instrumentation issues on Java 25
ToolRegistrationServlet servlet = new ToolRegistrationServlet(toolRegistry) {
@Override
public Result<McpTool, Exception> registerTool(String jarPath, String className) {
toolRegistry.register(mockTool);
return new Ok<McpTool, Exception>(mockTool);
}
};
String json = "{\"jarPath\": \"/tmp/test.jar\", \"className\": \"com.example.EchoTool\"}";
mockRequestInput(json);
servlet.doPost(request, response);
verify(response).setStatus(HttpServletResponse.SC_OK);
assertTrue(responseWriter.toString().contains("Tool registered successfully: EchoTool"));
assertTrue(toolRegistry.get("EchoTool") != null);
}
@Test
void testDoPostMissingParams() throws Exception {
ToolRegistrationServlet servlet = new ToolRegistrationServlet(toolRegistry);
String json = "{\"jarPath\": \"/tmp/test.jar\"}"; // missing className
mockRequestInput(json);
servlet.doPost(request, response);
verify(response).setStatus(HttpServletResponse.SC_BAD_REQUEST);
assertTrue(responseWriter.toString().contains("Missing jarPath or className"));
}
@Test
void testDoPostRegistrationError() throws Exception {
ToolRegistrationServlet servlet = new ToolRegistrationServlet(toolRegistry) {
@Override
public Result<McpTool, Exception> registerTool(String jarPath, String className) {
return new Err<McpTool, Exception>(new Exception("Loading failed"));
}
};
String json = "{\"jarPath\": \"/tmp/test.jar\", \"className\": \"com.example.FailTool\"}";
mockRequestInput(json);
servlet.doPost(request, response);
verify(response).setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
assertTrue(responseWriter.toString().contains("Error registering tool: Loading failed"));
}
private void mockRequestInput(String json) throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(json.getBytes());
ServletInputStream sis = new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public boolean isFinished() {
return bais.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
when(request.getInputStream()).thenReturn(sis);
}
}