Change @ParameterizedTest -> @Test in HttpServletStatelessServerTransport

Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
This commit is contained in:
Daniel Garnier-Moiroux 2026-06-24 15:40:13 +02:00
commit f7d9a64b3c

View file

@ -7,7 +7,6 @@ package io.modelcontextprotocol.server;
import java.time.Duration; import java.time.Duration;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction; import java.util.function.BiFunction;
@ -42,8 +41,6 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
@ -69,7 +66,12 @@ class HttpServletStatelessIntegrationTests {
private HttpServletStatelessServerTransport mcpStatelessServerTransport; private HttpServletStatelessServerTransport mcpStatelessServerTransport;
ConcurrentHashMap<String, McpClient.SyncSpec> clientBuilders = new ConcurrentHashMap<>(); private final McpClient.SyncSpec clientBuilder = McpClient
.sync(HttpClientStreamableHttpTransport.builder("http://localhost:" + PORT)
.endpoint(CUSTOM_MESSAGE_ENDPOINT)
.build())
.initializationTimeout(Duration.ofHours(10))
.requestTimeout(Duration.ofHours(10));
private Tomcat tomcat; private Tomcat tomcat;
@ -87,12 +89,6 @@ class HttpServletStatelessIntegrationTests {
catch (Exception e) { catch (Exception e) {
throw new RuntimeException("Failed to start Tomcat", e); throw new RuntimeException("Failed to start Tomcat", e);
} }
clientBuilders
.put("httpclient",
McpClient.sync(HttpClientStreamableHttpTransport.builder("http://localhost:" + PORT)
.endpoint(CUSTOM_MESSAGE_ENDPOINT)
.build()).initializationTimeout(Duration.ofHours(10)).requestTimeout(Duration.ofHours(10)));
} }
@AfterEach @AfterEach
@ -114,12 +110,8 @@ class HttpServletStatelessIntegrationTests {
// --------------------------------------- // ---------------------------------------
// Tools Tests // Tools Tests
// --------------------------------------- // ---------------------------------------
@ParameterizedTest(name = "{0} : {displayName} ") @Test
@ValueSource(strings = { "httpclient" }) void testToolCallSuccess() {
void testToolCallSuccess(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
var callResponse = CallToolResult.builder() var callResponse = CallToolResult.builder()
.content(List.of(McpSchema.TextContent.builder("CALL RESPONSE").build())) .content(List.of(McpSchema.TextContent.builder("CALL RESPONSE").build()))
.isError(false) .isError(false)
@ -160,12 +152,8 @@ class HttpServletStatelessIntegrationTests {
} }
} }
@ParameterizedTest(name = "{0} : {displayName} ") @Test
@ValueSource(strings = { "httpclient" }) void testInitialize() {
void testInitialize(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
var mcpServer = McpServer.sync(mcpStatelessServerTransport).build(); var mcpServer = McpServer.sync(mcpStatelessServerTransport).build();
try (var mcpClient = clientBuilder.build()) { try (var mcpClient = clientBuilder.build()) {
@ -180,11 +168,8 @@ class HttpServletStatelessIntegrationTests {
// --------------------------------------- // ---------------------------------------
// Completion Tests // Completion Tests
// --------------------------------------- // ---------------------------------------
@ParameterizedTest(name = "{0} : Completion call") @Test
@ValueSource(strings = { "httpclient" }) void testCompletionShouldReturnExpectedSuggestions() {
void testCompletionShouldReturnExpectedSuggestions(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
var expectedValues = List.of("python", "pytorch", "pyside"); var expectedValues = List.of("python", "pytorch", "pyside");
var completionResponse = new CompleteResult(new CompleteResult.CompleteCompletion(expectedValues, 10, // total var completionResponse = new CompleteResult(new CompleteResult.CompleteCompletion(expectedValues, 10, // total
true // hasMore true // hasMore
@ -235,11 +220,8 @@ class HttpServletStatelessIntegrationTests {
} }
} }
@ParameterizedTest(name = "{0} : Completion call without matching handler") @Test
@ValueSource(strings = { "httpclient" }) void testCompletionWithoutMatchingHandlerReturnsEmptyResult() {
void testCompletionWithoutMatchingHandlerReturnsEmptyResult(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
BiFunction<McpTransportContext, CompleteRequest, CompleteResult> completionHandler = (transportContext, BiFunction<McpTransportContext, CompleteRequest, CompleteResult> completionHandler = (transportContext,
request) -> new CompleteResult(new CompleteResult.CompleteCompletion(List.of("java"), 1, false)); request) -> new CompleteResult(new CompleteResult.CompleteCompletion(List.of("java"), 1, false));
@ -288,11 +270,8 @@ class HttpServletStatelessIntegrationTests {
} }
} }
@ParameterizedTest(name = "{0} : Resource template completion call without matching handler") @Test
@ValueSource(strings = { "httpclient" }) void testResourceTemplateCompletionWithoutMatchingHandlerReturnsEmptyResult() {
void testResourceTemplateCompletionWithoutMatchingHandlerReturnsEmptyResult(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
BiFunction<McpTransportContext, CompleteRequest, CompleteResult> completionHandler = (transportContext, BiFunction<McpTransportContext, CompleteRequest, CompleteResult> completionHandler = (transportContext,
request) -> new CompleteResult(new CompleteResult.CompleteCompletion(List.of("java"), 1, false)); request) -> new CompleteResult(new CompleteResult.CompleteCompletion(List.of("java"), 1, false));
@ -339,11 +318,8 @@ class HttpServletStatelessIntegrationTests {
} }
} }
@ParameterizedTest(name = "{0} : Completion call for non-existent prompt") @Test
@ValueSource(strings = { "httpclient" }) void testCompletionForNonExistentPromptReturnsInvalidParams() {
void testCompletionForNonExistentPromptReturnsInvalidParams(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
var mcpServer = McpServer.sync(mcpStatelessServerTransport) var mcpServer = McpServer.sync(mcpStatelessServerTransport)
.capabilities(ServerCapabilities.builder().completions().build()) .capabilities(ServerCapabilities.builder().completions().build())
.build(); .build();
@ -360,18 +336,15 @@ class HttpServletStatelessIntegrationTests {
.asInstanceOf(type(McpError.class)) .asInstanceOf(type(McpError.class))
.extracting(McpError::getJsonRpcError) .extracting(McpError::getJsonRpcError)
.extracting(McpSchema.JSONRPCResponse.JSONRPCError::code) .extracting(McpSchema.JSONRPCResponse.JSONRPCError::code)
.isEqualTo(McpSchema.ErrorCodes.RESOURCE_NOT_FOUND); .isEqualTo(ErrorCodes.INVALID_PARAMS);
} }
finally { finally {
mcpServer.close(); mcpServer.close();
} }
} }
@ParameterizedTest(name = "{0} : Completion call for non-existent resource") @Test
@ValueSource(strings = { "httpclient" }) void testCompletionForNonExistentResourceReturnsResourceNotFound() {
void testCompletionForNonExistentResourceReturnsResourceNotFound(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
var mcpServer = McpServer.sync(mcpStatelessServerTransport) var mcpServer = McpServer.sync(mcpStatelessServerTransport)
.capabilities(ServerCapabilities.builder().completions().build()) .capabilities(ServerCapabilities.builder().completions().build())
.build(); .build();
@ -399,11 +372,8 @@ class HttpServletStatelessIntegrationTests {
// --------------------------------------- // ---------------------------------------
// Tool Structured Output Schema Tests // Tool Structured Output Schema Tests
// --------------------------------------- // ---------------------------------------
@ParameterizedTest(name = "{0} : {displayName} ") @Test
@ValueSource(strings = { "httpclient" }) void testStructuredOutputValidationSuccess() {
void testStructuredOutputValidationSuccess(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
// Create a tool with output schema // Create a tool with output schema
Map<String, Object> outputSchema = Map.of( Map<String, Object> outputSchema = Map.of(
"type", "object", "properties", Map.of("result", Map.of("type", "number"), "operation", "type", "object", "properties", Map.of("result", Map.of("type", "number"), "operation",
@ -468,11 +438,8 @@ class HttpServletStatelessIntegrationTests {
} }
} }
@ParameterizedTest(name = "{0} : {displayName} ") @Test
@ValueSource(strings = { "httpclient" }) void testStructuredOutputOfObjectArrayValidationSuccess() {
void testStructuredOutputOfObjectArrayValidationSuccess(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
// Create a tool with output schema that returns an array of objects // Create a tool with output schema that returns an array of objects
Map<String, Object> outputSchema = Map Map<String, Object> outputSchema = Map
.of( // @formatter:off .of( // @formatter:off
@ -529,11 +496,8 @@ class HttpServletStatelessIntegrationTests {
} }
} }
@ParameterizedTest(name = "{0} : {displayName} ") @Test
@ValueSource(strings = { "httpclient" }) void testStructuredOutputWithInHandlerError() {
void testStructuredOutputWithInHandlerError(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
// Create a tool with output schema // Create a tool with output schema
Map<String, Object> outputSchema = Map.of( Map<String, Object> outputSchema = Map.of(
"type", "object", "properties", Map.of("result", Map.of("type", "number"), "operation", "type", "object", "properties", Map.of("result", Map.of("type", "number"), "operation",
@ -587,11 +551,8 @@ class HttpServletStatelessIntegrationTests {
} }
} }
@ParameterizedTest(name = "{0} : {displayName} ") @Test
@ValueSource(strings = { "httpclient" }) void testStructuredOutputValidationFailure() {
void testStructuredOutputValidationFailure(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
// Create a tool with output schema // Create a tool with output schema
Map<String, Object> outputSchema = Map.of("type", "object", "properties", Map<String, Object> outputSchema = Map.of("type", "object", "properties",
Map.of("result", Map.of("type", "number"), "operation", Map.of("type", "string")), "required", Map.of("result", Map.of("type", "number"), "operation", Map.of("type", "string")), "required",
@ -639,11 +600,8 @@ class HttpServletStatelessIntegrationTests {
} }
} }
@ParameterizedTest(name = "{0} : {displayName} ") @Test
@ValueSource(strings = { "httpclient" }) void testStructuredOutputMissingStructuredContent() {
void testStructuredOutputMissingStructuredContent(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
// Create a tool with output schema // Create a tool with output schema
Map<String, Object> outputSchema = Map.of("type", "object", "properties", Map<String, Object> outputSchema = Map.of("type", "object", "properties",
Map.of("result", Map.of("type", "number")), "required", List.of("result")); Map.of("result", Map.of("type", "number")), "required", List.of("result"));
@ -688,11 +646,8 @@ class HttpServletStatelessIntegrationTests {
} }
} }
@ParameterizedTest(name = "{0} : {displayName} ") @Test
@ValueSource(strings = { "httpclient" }) void testStructuredOutputRuntimeToolAddition() {
void testStructuredOutputRuntimeToolAddition(String clientType) {
var clientBuilder = clientBuilders.get(clientType);
// Start server without tools // Start server without tools
var mcpServer = McpServer.sync(mcpStatelessServerTransport) var mcpServer = McpServer.sync(mcpStatelessServerTransport)
.serverInfo("test-server", "1.0.0") .serverInfo("test-server", "1.0.0")