From 9aba371660a3905625836cdc3dbd5a3349ebae65 Mon Sep 17 00:00:00 2001 From: Christian Tzolov Date: Mon, 13 Jan 2025 11:12:56 +0100 Subject: [PATCH] feat: Add SSE transport tests for MCP client and server - Add tests for HttpServletSseServerTransport implementation - Add tests for HttpClientSseClientTransport implementation - Rename STDIO transport test classes for clarity --- .../client/ServletSseMcpAsyncClientTests.java | 60 +++++++++++++++++++ .../client/ServletSseMcpSyncClientTests.java | 60 +++++++++++++++++++ ...sts.java => StdioMcpAsyncClientTests.java} | 2 +- ...ests.java => StdioMcpSyncClientTests.java} | 2 +- .../server/ServletSseMcpAsyncServerTests.java | 38 ++++++++++++ .../server/ServletSseMcpSyncServerTests.java | 38 ++++++++++++ 6 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 mcp/src/test/java/org/springframework/ai/mcp/client/ServletSseMcpAsyncClientTests.java create mode 100644 mcp/src/test/java/org/springframework/ai/mcp/client/ServletSseMcpSyncClientTests.java rename mcp/src/test/java/org/springframework/ai/mcp/client/{McpAsyncClientTests.java => StdioMcpAsyncClientTests.java} (95%) rename mcp/src/test/java/org/springframework/ai/mcp/client/{McpSyncClientTests.java => StdioMcpSyncClientTests.java} (96%) create mode 100644 mcp/src/test/java/org/springframework/ai/mcp/server/ServletSseMcpAsyncServerTests.java create mode 100644 mcp/src/test/java/org/springframework/ai/mcp/server/ServletSseMcpSyncServerTests.java diff --git a/mcp/src/test/java/org/springframework/ai/mcp/client/ServletSseMcpAsyncClientTests.java b/mcp/src/test/java/org/springframework/ai/mcp/client/ServletSseMcpAsyncClientTests.java new file mode 100644 index 0000000..86e6976 --- /dev/null +++ b/mcp/src/test/java/org/springframework/ai/mcp/client/ServletSseMcpAsyncClientTests.java @@ -0,0 +1,60 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.mcp.client; + +import org.junit.jupiter.api.Timeout; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +import org.springframework.ai.mcp.client.transport.HttpClientSseClientTransport; +import org.springframework.ai.mcp.spec.ClientMcpTransport; + +/** + * Tests for the {@link McpSyncClient} with {@link HttpClientSseClientTransport}. + * + * @author Christian Tzolov + */ +@Timeout(15) // Giving extra time beyond the client timeout +class ServletSseMcpAsyncClientTests extends AbstractMcpAsyncClientTests { + + String host = "http://localhost:3004"; + + // Uses the https://github.com/tzolov/mcp-everything-server-docker-image + @SuppressWarnings("resource") + GenericContainer container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v1") + .withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String())) + .withExposedPorts(3001) + .waitingFor(Wait.forHttp("/").forStatusCode(404)); + + @Override + protected ClientMcpTransport createMcpTransport() { + return new HttpClientSseClientTransport(host); + } + + @Override + protected void onStart() { + container.start(); + int port = container.getMappedPort(3001); + host = "http://" + container.getHost() + ":" + port; + } + + @Override + protected void onClose() { + container.stop(); + } + +} diff --git a/mcp/src/test/java/org/springframework/ai/mcp/client/ServletSseMcpSyncClientTests.java b/mcp/src/test/java/org/springframework/ai/mcp/client/ServletSseMcpSyncClientTests.java new file mode 100644 index 0000000..f33bc97 --- /dev/null +++ b/mcp/src/test/java/org/springframework/ai/mcp/client/ServletSseMcpSyncClientTests.java @@ -0,0 +1,60 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.mcp.client; + +import org.junit.jupiter.api.Timeout; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; + +import org.springframework.ai.mcp.client.transport.HttpClientSseClientTransport; +import org.springframework.ai.mcp.spec.ClientMcpTransport; + +/** + * Tests for the {@link McpSyncClient} with {@link HttpClientSseClientTransport}. + * + * @author Christian Tzolov + */ +@Timeout(15) // Giving extra time beyond the client timeout +class ServletSseMcpSyncClientTests extends AbstractMcpSyncClientTests { + + String host = "http://localhost:3003"; + + // Uses the https://github.com/tzolov/mcp-everything-server-docker-image + @SuppressWarnings("resource") + GenericContainer container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v1") + .withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String())) + .withExposedPorts(3001) + .waitingFor(Wait.forHttp("/").forStatusCode(404)); + + @Override + protected ClientMcpTransport createMcpTransport() { + return new HttpClientSseClientTransport(host); + } + + @Override + protected void onStart() { + container.start(); + int port = container.getMappedPort(3001); + host = "http://" + container.getHost() + ":" + port; + } + + @Override + protected void onClose() { + container.stop(); + } + +} diff --git a/mcp/src/test/java/org/springframework/ai/mcp/client/McpAsyncClientTests.java b/mcp/src/test/java/org/springframework/ai/mcp/client/StdioMcpAsyncClientTests.java similarity index 95% rename from mcp/src/test/java/org/springframework/ai/mcp/client/McpAsyncClientTests.java rename to mcp/src/test/java/org/springframework/ai/mcp/client/StdioMcpAsyncClientTests.java index ca37d72..94c9b41 100644 --- a/mcp/src/test/java/org/springframework/ai/mcp/client/McpAsyncClientTests.java +++ b/mcp/src/test/java/org/springframework/ai/mcp/client/StdioMcpAsyncClientTests.java @@ -29,7 +29,7 @@ import org.springframework.ai.mcp.spec.ClientMcpTransport; * @author Dariusz Jędrzejczyk */ @Timeout(15) // Giving extra time beyond the client timeout -class McpAsyncClientTests extends AbstractMcpAsyncClientTests { +class StdioMcpAsyncClientTests extends AbstractMcpAsyncClientTests { @Override protected ClientMcpTransport createMcpTransport() { diff --git a/mcp/src/test/java/org/springframework/ai/mcp/client/McpSyncClientTests.java b/mcp/src/test/java/org/springframework/ai/mcp/client/StdioMcpSyncClientTests.java similarity index 96% rename from mcp/src/test/java/org/springframework/ai/mcp/client/McpSyncClientTests.java rename to mcp/src/test/java/org/springframework/ai/mcp/client/StdioMcpSyncClientTests.java index 3b881d0..962bc2a 100644 --- a/mcp/src/test/java/org/springframework/ai/mcp/client/McpSyncClientTests.java +++ b/mcp/src/test/java/org/springframework/ai/mcp/client/StdioMcpSyncClientTests.java @@ -34,7 +34,7 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Dariusz Jędrzejczyk */ @Timeout(15) // Giving extra time beyond the client timeout -class McpSyncClientTests extends AbstractMcpSyncClientTests { +class StdioMcpSyncClientTests extends AbstractMcpSyncClientTests { @Override protected ClientMcpTransport createMcpTransport() { diff --git a/mcp/src/test/java/org/springframework/ai/mcp/server/ServletSseMcpAsyncServerTests.java b/mcp/src/test/java/org/springframework/ai/mcp/server/ServletSseMcpAsyncServerTests.java new file mode 100644 index 0000000..584938b --- /dev/null +++ b/mcp/src/test/java/org/springframework/ai/mcp/server/ServletSseMcpAsyncServerTests.java @@ -0,0 +1,38 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.mcp.server; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Timeout; + +import org.springframework.ai.mcp.server.transport.HttpServletSseServerTransport; +import org.springframework.ai.mcp.spec.ServerMcpTransport; + +/** + * Tests for {@link McpAsyncServer} using {@link HttpServletSseServerTransport}. + * + * @author Christian Tzolov + */ +@Timeout(15) // Giving extra time beyond the client timeout +class ServletSseMcpAsyncServerTests extends AbstractMcpAsyncServerTests { + + @Override + protected ServerMcpTransport createMcpTransport() { + return new HttpServletSseServerTransport(new ObjectMapper(), "/mcp/message"); + } + +} diff --git a/mcp/src/test/java/org/springframework/ai/mcp/server/ServletSseMcpSyncServerTests.java b/mcp/src/test/java/org/springframework/ai/mcp/server/ServletSseMcpSyncServerTests.java new file mode 100644 index 0000000..2d3390d --- /dev/null +++ b/mcp/src/test/java/org/springframework/ai/mcp/server/ServletSseMcpSyncServerTests.java @@ -0,0 +1,38 @@ +/* + * Copyright 2024-2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.mcp.server; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Timeout; + +import org.springframework.ai.mcp.server.transport.HttpServletSseServerTransport; +import org.springframework.ai.mcp.spec.ServerMcpTransport; + +/** + * Tests for {@link McpSyncServer} using {@link HttpServletSseServerTransport}. + * + * @author Christian Tzolov + */ +@Timeout(15) // Giving extra time beyond the client timeout +class ServletSseMcpSyncServerTests extends AbstractMcpSyncServerTests { + + @Override + protected ServerMcpTransport createMcpTransport() { + return new HttpServletSseServerTransport(new ObjectMapper(), "/mcp/message"); + } + +}