Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

package io.modelcontextprotocol.server;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -45,6 +48,7 @@
import io.modelcontextprotocol.spec.McpSchema.Tool;
import io.modelcontextprotocol.util.Utils;
import net.javacrumbs.jsonunit.core.Option;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
Expand All @@ -58,18 +62,30 @@
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertWith;
import static org.awaitility.Awaitility.await;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public abstract class AbstractMcpClientServerIntegrationTests {

protected ConcurrentHashMap<String, McpClient.SyncSpec> clientBuilders = new ConcurrentHashMap<>();

protected static HttpClient mockClient = mock(HttpClient.class);

abstract protected void prepareClients(int port, String mcpEndpoint);

abstract protected McpServer.AsyncSpecification<?> prepareAsyncServerBuilder();

abstract protected McpServer.SyncSpecification<?> prepareSyncServerBuilder();

@BeforeAll
protected static void initMockClient() throws IOException, InterruptedException {
HttpResponse<String> mockResponse = mock(HttpResponse.class);
when(mockResponse.body()).thenReturn(Files.readString(Path.of("pom.xml").toAbsolutePath()));
when(mockResponse.statusCode()).thenReturn(200);
when(mockClient.send(any(HttpRequest.class), any(HttpResponse.BodyHandler.class))).thenReturn(mockResponse);
}

@ParameterizedTest(name = "{0} : {displayName} ")
@MethodSource("clientsForTesting")
void simple(String clientType) {
Expand Down Expand Up @@ -774,12 +790,11 @@ void testToolCallSuccess(String clientType) {
.callHandler((exchange, request) -> {

try {
HttpResponse<String> response = HttpClient.newHttpClient()
.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = mockClient.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
responseBodyIsNullOrBlank.set(!Utils.hasText(responseBody));
}
Expand Down Expand Up @@ -923,12 +938,11 @@ void testToolListChangeHandlingSuccess(String clientType) {
.callHandler((exchange, request) -> {
// perform a blocking call to a remote service
try {
HttpResponse<String> response = HttpClient.newHttpClient()
.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = mockClient.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
assertThat(responseBody).isNotBlank();
}
Expand All @@ -948,12 +962,11 @@ void testToolListChangeHandlingSuccess(String clientType) {
try (var mcpClient = clientBuilder.toolsChangeConsumer(toolsUpdate -> {
// perform a blocking call to a remote service
try {
HttpResponse<String> response = HttpClient.newHttpClient()
.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = mockClient.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
assertThat(responseBody).isNotBlank();
toolsRef.set(toolsUpdate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@

import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.client.RestClient;

import static io.modelcontextprotocol.server.transport.HttpServletStatelessServerTransport.APPLICATION_JSON;
import static io.modelcontextprotocol.server.transport.HttpServletStatelessServerTransport.TEXT_EVENT_STREAM;
Expand Down Expand Up @@ -122,12 +121,14 @@ void testToolCallSuccess(String clientType) {
Tool.builder().name("tool1").title("tool1 description").inputSchema(EMPTY_JSON_SCHEMA).build(),
(transportContext, request) -> {
// perform a blocking call to a remote service
String response = RestClient.create()
.get()
.uri("https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md")
.retrieve()
.body(String.class);
String response = "{\"result\":\"test result\"}";
assertThat(response).isNotBlank();
try {
Thread.sleep(1000L);
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
return callResponse;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

package io.modelcontextprotocol;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -49,6 +52,7 @@
import io.modelcontextprotocol.spec.McpSchema.Tool;
import io.modelcontextprotocol.util.Utils;
import net.javacrumbs.jsonunit.core.Option;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
Expand All @@ -62,18 +66,30 @@
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertWith;
import static org.awaitility.Awaitility.await;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public abstract class AbstractMcpClientServerIntegrationTests {

protected ConcurrentHashMap<String, McpClient.SyncSpec> clientBuilders = new ConcurrentHashMap<>();

protected static HttpClient mockClient = mock(HttpClient.class);

abstract protected void prepareClients(int port, String mcpEndpoint);

abstract protected McpServer.AsyncSpecification<?> prepareAsyncServerBuilder();

abstract protected McpServer.SyncSpecification<?> prepareSyncServerBuilder();

@BeforeAll
protected static void initMockClient() throws IOException, InterruptedException {
HttpResponse<String> mockResponse = mock(HttpResponse.class);
when(mockResponse.body()).thenReturn(Files.readString(Path.of("pom.xml").toAbsolutePath()));
when(mockResponse.statusCode()).thenReturn(200);
when(mockClient.send(any(HttpRequest.class), any(HttpResponse.BodyHandler.class))).thenReturn(mockResponse);
}

@ParameterizedTest(name = "{0} : {displayName} ")
@MethodSource("clientsForTesting")
void simple(String clientType) {
Expand Down Expand Up @@ -778,12 +794,11 @@ void testToolCallSuccess(String clientType) {
.callHandler((exchange, request) -> {

try {
HttpResponse<String> response = HttpClient.newHttpClient()
.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = mockClient.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
responseBodyIsNullOrBlank.set(!Utils.hasText(responseBody));
}
Expand Down Expand Up @@ -927,12 +942,11 @@ void testToolListChangeHandlingSuccess(String clientType) {
.callHandler((exchange, request) -> {
// perform a blocking call to a remote service
try {
HttpResponse<String> response = HttpClient.newHttpClient()
.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = mockClient.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
assertThat(responseBody).isNotBlank();
}
Expand All @@ -952,12 +966,11 @@ void testToolListChangeHandlingSuccess(String clientType) {
try (var mcpClient = clientBuilder.toolsChangeConsumer(toolsUpdate -> {
// perform a blocking call to a remote service
try {
HttpResponse<String> response = HttpClient.newHttpClient()
.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = mockClient.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
assertThat(responseBody).isNotBlank();
toolsRef.set(toolsUpdate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

package io.modelcontextprotocol;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.List;
import java.util.Map;
Expand All @@ -27,9 +30,9 @@
import io.modelcontextprotocol.spec.McpSchema.TextContent;
import io.modelcontextprotocol.spec.McpSchema.Tool;
import net.javacrumbs.jsonunit.core.Option;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import reactor.core.publisher.Mono;

import static io.modelcontextprotocol.util.ToolsUtils.EMPTY_JSON_SCHEMA;
Expand All @@ -38,17 +41,30 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.awaitility.Awaitility.await;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public abstract class AbstractStatelessIntegrationTests {

protected ConcurrentHashMap<String, McpClient.SyncSpec> clientBuilders = new ConcurrentHashMap<>();

protected static HttpClient mockClient = mock(HttpClient.class);

abstract protected void prepareClients(int port, String mcpEndpoint);

abstract protected StatelessAsyncSpecification prepareAsyncServerBuilder();

abstract protected StatelessSyncSpecification prepareSyncServerBuilder();

@BeforeAll
protected static void initMockClient() throws IOException, InterruptedException {
HttpResponse<String> mockResponse = mock(HttpResponse.class);
when(mockResponse.body()).thenReturn(Files.readString(Path.of("pom.xml").toAbsolutePath()));
when(mockResponse.statusCode()).thenReturn(200);
when(mockClient.send(any(HttpRequest.class), any(HttpResponse.BodyHandler.class))).thenReturn(mockResponse);
}

@ParameterizedTest(name = "{0} : {displayName} ")
@MethodSource("clientsForTesting")
void simple(String clientType) {
Expand Down Expand Up @@ -89,12 +105,11 @@ void testToolCallSuccess(String clientType) {
.callHandler((ctx, request) -> {

try {
HttpResponse<String> response = HttpClient.newHttpClient()
.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = mockClient.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
assertThat(responseBody).isNotBlank();
}
Expand Down Expand Up @@ -177,12 +192,11 @@ void testToolListChangeHandlingSuccess(String clientType) {
.callHandler((ctx, request) -> {
// perform a blocking call to a remote service
try {
HttpResponse<String> response = HttpClient.newHttpClient()
.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = mockClient.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
assertThat(responseBody).isNotBlank();
}
Expand All @@ -202,12 +216,11 @@ void testToolListChangeHandlingSuccess(String clientType) {
try (var mcpClient = clientBuilder.toolsChangeConsumer(toolsUpdate -> {
// perform a blocking call to a remote service
try {
HttpResponse<String> response = HttpClient.newHttpClient()
.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
HttpResponse<String> response = mockClient.send(HttpRequest.newBuilder()
.uri(URI.create(
"https://raw.githubusercontent.com/modelcontextprotocol/java-sdk/refs/heads/main/README.md"))
.GET()
.build(), HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
assertThat(responseBody).isNotBlank();
}
Expand Down