test: ensure proper resource cleanup in integration tests (#537)

- Add try-finally blocks to guarantee server cleanup on test completion
- Call closeGracefully().block() to ensure synchronous shutdown
- Use try-with-resources for client lifecycle management where applicable
- Prevent resource leaks and potential test flakiness

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
Christian Tzolov 2025-09-04 16:52:21 +02:00 • committed by GitHub
commit 681fe7f90b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 317 additions and 238 deletions

View file

@ -91,7 +91,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(client.initialize()).isNotNull();
}
server.closeGracefully();
finally {
server.closeGracefully().block();
}
}
// ---------------------------------------
@ -128,7 +130,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.hasMessage("Client must be configured with sampling capabilities");
}
}
server.closeGracefully();
finally {
server.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -195,7 +199,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(result.stopReason()).isEqualTo(CreateMessageResult.StopReason.STOP_SEQUENCE);
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -219,11 +225,6 @@ public abstract class AbstractMcpClientServerIntegrationTests {
CreateMessageResult.StopReason.STOP_SEQUENCE);
};
var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().sampling().build())
.sampling(samplingHandler)
.build();
// Server
CallToolResult callResponse = new McpSchema.CallToolResult(List.of(new McpSchema.TextContent("CALL RESPONSE")),
@ -256,26 +257,31 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.requestTimeout(Duration.ofSeconds(4))
.tools(tool)
.build();
try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().sampling().build())
.sampling(samplingHandler)
.build()) {
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
CallToolResult response = mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
CallToolResult response = mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
assertThat(response).isNotNull();
assertThat(response).isEqualTo(callResponse);
assertThat(response).isNotNull();
assertThat(response).isEqualTo(callResponse);
assertWith(samplingResult.get(), result -> {
assertThat(result).isNotNull();
assertThat(result.role()).isEqualTo(Role.USER);
assertThat(result.content()).isInstanceOf(McpSchema.TextContent.class);
assertThat(((McpSchema.TextContent) result.content()).text()).isEqualTo("Test message");
assertThat(result.model()).isEqualTo("MockModelName");
assertThat(result.stopReason()).isEqualTo(CreateMessageResult.StopReason.STOP_SEQUENCE);
});
mcpClient.close();
mcpServer.close();
assertWith(samplingResult.get(), result -> {
assertThat(result).isNotNull();
assertThat(result.role()).isEqualTo(Role.USER);
assertThat(result.content()).isInstanceOf(McpSchema.TextContent.class);
assertThat(((McpSchema.TextContent) result.content()).text()).isEqualTo("Test message");
assertThat(result.model()).isEqualTo("MockModelName");
assertThat(result.stopReason()).isEqualTo(CreateMessageResult.StopReason.STOP_SEQUENCE);
});
}
finally {
mcpServer.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -297,11 +303,6 @@ public abstract class AbstractMcpClientServerIntegrationTests {
CreateMessageResult.StopReason.STOP_SEQUENCE);
};
var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().sampling().build())
.sampling(samplingHandler)
.build();
CallToolResult callResponse = new McpSchema.CallToolResult(List.of(new McpSchema.TextContent("CALL RESPONSE")),
null);
@ -329,15 +330,21 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.tools(tool)
.build();
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().sampling().build())
.sampling(samplingHandler)
.build()) {
assertThatExceptionOfType(McpError.class).isThrownBy(() -> {
mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
}).withMessageContaining("1000ms");
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
mcpClient.close();
mcpServer.close();
assertThatExceptionOfType(McpError.class).isThrownBy(() -> {
mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
}).withMessageContaining("1000ms");
}
finally {
mcpServer.closeGracefully().block();
}
}
// ---------------------------------------
@ -370,7 +377,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.hasMessage("Client must be configured with elicitation capabilities");
}
}
server.closeGracefully().block();
finally {
server.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -425,7 +434,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(response).isNotNull();
assertThat(response).isEqualTo(callResponse);
}
mcpServer.closeGracefully().block();
finally {
mcpServer.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -440,11 +451,6 @@ public abstract class AbstractMcpClientServerIntegrationTests {
return new ElicitResult(ElicitResult.Action.ACCEPT, Map.of("message", request.message()));
};
var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().elicitation().build())
.elicitation(elicitationHandler)
.build();
CallToolResult callResponse = new McpSchema.CallToolResult(List.of(new McpSchema.TextContent("CALL RESPONSE")),
null);
@ -471,21 +477,27 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.tools(tool)
.build();
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().elicitation().build())
.elicitation(elicitationHandler)
.build()) {
CallToolResult response = mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
assertThat(response).isNotNull();
assertThat(response).isEqualTo(callResponse);
assertWith(resultRef.get(), result -> {
assertThat(result).isNotNull();
assertThat(result.action()).isEqualTo(McpSchema.ElicitResult.Action.ACCEPT);
assertThat(result.content().get("message")).isEqualTo("Test message");
});
CallToolResult response = mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
mcpClient.closeGracefully();
mcpServer.closeGracefully().block();
assertThat(response).isNotNull();
assertThat(response).isEqualTo(callResponse);
assertWith(resultRef.get(), result -> {
assertThat(result).isNotNull();
assertThat(result.action()).isEqualTo(McpSchema.ElicitResult.Action.ACCEPT);
assertThat(result.content().get("message")).isEqualTo("Test message");
});
}
finally {
mcpServer.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -511,11 +523,6 @@ public abstract class AbstractMcpClientServerIntegrationTests {
return new ElicitResult(ElicitResult.Action.ACCEPT, Map.of("message", request.message()));
};
var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().elicitation().build())
.elicitation(elicitationHandler)
.build();
CallToolResult callResponse = new CallToolResult(List.of(new McpSchema.TextContent("CALL RESPONSE")), null);
AtomicReference<ElicitResult> resultRef = new AtomicReference<>();
@ -541,18 +548,24 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.tools(tool)
.build();
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().elicitation().build())
.elicitation(elicitationHandler)
.build()) {
assertThatExceptionOfType(McpError.class).isThrownBy(() -> {
mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
}).withMessageContaining("within 1000ms");
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
ElicitResult elicitResult = resultRef.get();
assertThat(elicitResult).isNull();
assertThatExceptionOfType(McpError.class).isThrownBy(() -> {
mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
}).withMessageContaining("within 1000ms");
mcpClient.closeGracefully();
mcpServer.closeGracefully().block();
ElicitResult elicitResult = resultRef.get();
assertThat(elicitResult).isNull();
}
finally {
mcpServer.closeGracefully().block();
}
}
// ---------------------------------------
@ -601,8 +614,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(rootsRef.get()).containsAll(List.of(roots.get(1), root3));
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -639,8 +653,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(e).isInstanceOf(McpError.class).hasMessage("Roots not supported");
}
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -668,8 +683,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(rootsRef.get()).isEmpty();
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -701,8 +717,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(rootsRef2.get()).containsAll(roots);
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -732,8 +749,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(rootsRef.get()).containsAll(roots);
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
// ---------------------------------------
@ -793,8 +811,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(responseBodyIsNullOrBlank.get()).isFalse();
assertThat(response).isNotNull().isEqualTo(callResponse);
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -830,8 +849,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.isThrownBy(() -> mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of())))
.withMessageContaining("Timeout on blocking read");
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -886,8 +906,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(responseBodyIsNullOrBlank.get()).isFalse();
assertThat(response).isNotNull().isEqualTo(expectedCallResponse);
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -978,8 +999,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(toolsRef.get()).containsAll(List.of(tool2.tool()));
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -995,8 +1017,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
// ---------------------------------------
@ -1107,7 +1130,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(notificationMap.get("Another error message").logger()).isEqualTo("test-logger");
assertThat(notificationMap.get("Another error message").data()).isEqualTo("Another error message");
}
mcpServer.close();
finally {
mcpServer.closeGracefully().block();
}
}
// ---------------------------------------
@ -1212,7 +1237,7 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(notificationMap.get("Processing completed").message()).isEqualTo("Processing completed");
}
finally {
mcpServer.close();
mcpServer.closeGracefully().block();
}
}
@ -1262,8 +1287,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(samplingRequest.get().argument().value()).isEqualTo("py");
assertThat(samplingRequest.get().ref().type()).isEqualTo("ref/prompt");
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
// ---------------------------------------
@ -1324,8 +1350,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
// Verify execution order
assertThat(executionOrder.get()).isEqualTo("123");
}
mcpServer.close();
finally {
mcpServer.closeGracefully().block();
}
}
// ---------------------------------------
@ -1400,8 +1427,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.isEqualTo(json("""
{"result":5.0,"operation":"2 + 3","timestamp":"2024-01-01T10:00:00Z"}"""));
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -1454,8 +1482,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
String errorMessage = ((McpSchema.TextContent) response.content().get(0)).text();
assertThat(errorMessage).contains("Validation failed");
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -1504,8 +1533,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(errorMessage).isEqualTo(
"Response missing structured content which is expected when calling tool with non-empty outputSchema");
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -1581,8 +1611,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.isEqualTo(json("""
{"count":3,"message":"Dynamic execution"}"""));
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
private double evaluateExpression(String expression) {

View file

@ -66,7 +66,9 @@ public abstract class AbstractStatelessIntegrationTests {
assertThat(client.initialize()).isNotNull();
}
server.closeGracefully();
finally {
server.closeGracefully().block();
}
}
// ---------------------------------------
@ -126,8 +128,9 @@ public abstract class AbstractStatelessIntegrationTests {
assertThat(response).isNotNull().isEqualTo(callResponse);
}
mcpServer.close();
finally {
mcpServer.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -163,8 +166,9 @@ public abstract class AbstractStatelessIntegrationTests {
.isThrownBy(() -> mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of())))
.withMessageContaining("Timeout on blocking read");
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -244,8 +248,9 @@ public abstract class AbstractStatelessIntegrationTests {
mcpServer.addTool(tool2);
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -261,8 +266,9 @@ public abstract class AbstractStatelessIntegrationTests {
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
// ---------------------------------------
@ -339,8 +345,9 @@ public abstract class AbstractStatelessIntegrationTests {
.isEqualTo(json("""
{"result":5.0,"operation":"2 + 3","timestamp":"2024-01-01T10:00:00Z"}"""));
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -394,8 +401,9 @@ public abstract class AbstractStatelessIntegrationTests {
String errorMessage = ((McpSchema.TextContent) response.content().get(0)).text();
assertThat(errorMessage).contains("Validation failed");
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -444,8 +452,9 @@ public abstract class AbstractStatelessIntegrationTests {
assertThat(errorMessage).isEqualTo(
"Response missing structured content which is expected when calling tool with non-empty outputSchema");
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -521,8 +530,9 @@ public abstract class AbstractStatelessIntegrationTests {
.isEqualTo(json("""
{"count":3,"message":"Dynamic execution"}"""));
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
private double evaluateExpression(String expression) {

View file

@ -87,7 +87,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(client.initialize()).isNotNull();
}
server.closeGracefully();
finally {
server.closeGracefully().block();
}
}
// ---------------------------------------
@ -124,7 +126,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.hasMessage("Client must be configured with sampling capabilities");
}
}
server.closeGracefully();
finally {
server.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -191,7 +195,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(result.stopReason()).isEqualTo(CreateMessageResult.StopReason.STOP_SEQUENCE);
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -215,11 +221,6 @@ public abstract class AbstractMcpClientServerIntegrationTests {
CreateMessageResult.StopReason.STOP_SEQUENCE);
};
var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().sampling().build())
.sampling(samplingHandler)
.build();
// Server
CallToolResult callResponse = new McpSchema.CallToolResult(List.of(new McpSchema.TextContent("CALL RESPONSE")),
@ -252,26 +253,31 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.requestTimeout(Duration.ofSeconds(4))
.tools(tool)
.build();
try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().sampling().build())
.sampling(samplingHandler)
.build()) {
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
CallToolResult response = mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
CallToolResult response = mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
assertThat(response).isNotNull();
assertThat(response).isEqualTo(callResponse);
assertThat(response).isNotNull();
assertThat(response).isEqualTo(callResponse);
assertWith(samplingResult.get(), result -> {
assertThat(result).isNotNull();
assertThat(result.role()).isEqualTo(Role.USER);
assertThat(result.content()).isInstanceOf(McpSchema.TextContent.class);
assertThat(((McpSchema.TextContent) result.content()).text()).isEqualTo("Test message");
assertThat(result.model()).isEqualTo("MockModelName");
assertThat(result.stopReason()).isEqualTo(CreateMessageResult.StopReason.STOP_SEQUENCE);
});
mcpClient.close();
mcpServer.close();
assertWith(samplingResult.get(), result -> {
assertThat(result).isNotNull();
assertThat(result.role()).isEqualTo(Role.USER);
assertThat(result.content()).isInstanceOf(McpSchema.TextContent.class);
assertThat(((McpSchema.TextContent) result.content()).text()).isEqualTo("Test message");
assertThat(result.model()).isEqualTo("MockModelName");
assertThat(result.stopReason()).isEqualTo(CreateMessageResult.StopReason.STOP_SEQUENCE);
});
}
finally {
mcpServer.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -293,11 +299,6 @@ public abstract class AbstractMcpClientServerIntegrationTests {
CreateMessageResult.StopReason.STOP_SEQUENCE);
};
var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().sampling().build())
.sampling(samplingHandler)
.build();
CallToolResult callResponse = new McpSchema.CallToolResult(List.of(new McpSchema.TextContent("CALL RESPONSE")),
null);
@ -325,15 +326,21 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.tools(tool)
.build();
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().sampling().build())
.sampling(samplingHandler)
.build()) {
assertThatExceptionOfType(McpError.class).isThrownBy(() -> {
mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
}).withMessageContaining("1000ms");
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
mcpClient.close();
mcpServer.close();
assertThatExceptionOfType(McpError.class).isThrownBy(() -> {
mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
}).withMessageContaining("1000ms");
}
finally {
mcpServer.closeGracefully().block();
}
}
// ---------------------------------------
@ -366,7 +373,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.hasMessage("Client must be configured with elicitation capabilities");
}
}
server.closeGracefully().block();
finally {
server.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -421,7 +430,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(response).isNotNull();
assertThat(response).isEqualTo(callResponse);
}
mcpServer.closeGracefully().block();
finally {
mcpServer.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -436,11 +447,6 @@ public abstract class AbstractMcpClientServerIntegrationTests {
return new ElicitResult(ElicitResult.Action.ACCEPT, Map.of("message", request.message()));
};
var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().elicitation().build())
.elicitation(elicitationHandler)
.build();
CallToolResult callResponse = new McpSchema.CallToolResult(List.of(new McpSchema.TextContent("CALL RESPONSE")),
null);
@ -467,21 +473,27 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.tools(tool)
.build();
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().elicitation().build())
.elicitation(elicitationHandler)
.build()) {
CallToolResult response = mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
assertThat(response).isNotNull();
assertThat(response).isEqualTo(callResponse);
assertWith(resultRef.get(), result -> {
assertThat(result).isNotNull();
assertThat(result.action()).isEqualTo(McpSchema.ElicitResult.Action.ACCEPT);
assertThat(result.content().get("message")).isEqualTo("Test message");
});
CallToolResult response = mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
mcpClient.closeGracefully();
mcpServer.closeGracefully().block();
assertThat(response).isNotNull();
assertThat(response).isEqualTo(callResponse);
assertWith(resultRef.get(), result -> {
assertThat(result).isNotNull();
assertThat(result.action()).isEqualTo(McpSchema.ElicitResult.Action.ACCEPT);
assertThat(result.content().get("message")).isEqualTo("Test message");
});
}
finally {
mcpServer.closeGracefully().block();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -507,11 +519,6 @@ public abstract class AbstractMcpClientServerIntegrationTests {
return new ElicitResult(ElicitResult.Action.ACCEPT, Map.of("message", request.message()));
};
var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().elicitation().build())
.elicitation(elicitationHandler)
.build();
CallToolResult callResponse = new CallToolResult(List.of(new McpSchema.TextContent("CALL RESPONSE")), null);
AtomicReference<ElicitResult> resultRef = new AtomicReference<>();
@ -537,18 +544,24 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.tools(tool)
.build();
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample client", "0.0.0"))
.capabilities(ClientCapabilities.builder().elicitation().build())
.elicitation(elicitationHandler)
.build()) {
assertThatExceptionOfType(McpError.class).isThrownBy(() -> {
mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
}).withMessageContaining("within 1000ms");
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
ElicitResult elicitResult = resultRef.get();
assertThat(elicitResult).isNull();
assertThatExceptionOfType(McpError.class).isThrownBy(() -> {
mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of()));
}).withMessageContaining("within 1000ms");
mcpClient.closeGracefully();
mcpServer.closeGracefully().block();
ElicitResult elicitResult = resultRef.get();
assertThat(elicitResult).isNull();
}
finally {
mcpServer.closeGracefully().block();
}
}
// ---------------------------------------
@ -597,8 +610,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(rootsRef.get()).containsAll(List.of(roots.get(1), root3));
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -635,8 +649,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(e).isInstanceOf(McpError.class).hasMessage("Roots not supported");
}
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -664,8 +679,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(rootsRef.get()).isEmpty();
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -697,8 +713,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(rootsRef2.get()).containsAll(roots);
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -728,8 +745,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(rootsRef.get()).containsAll(roots);
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
// ---------------------------------------
@ -789,8 +807,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(responseBodyIsNullOrBlank.get()).isFalse();
assertThat(response).isNotNull().isEqualTo(callResponse);
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -826,8 +845,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.isThrownBy(() -> mcpClient.callTool(new McpSchema.CallToolRequest("tool1", Map.of())))
.withMessageContaining("Timeout on blocking read");
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -882,8 +902,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(responseBodyIsNullOrBlank.get()).isFalse();
assertThat(response).isNotNull().isEqualTo(expectedCallResponse);
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -974,8 +995,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(toolsRef.get()).containsAll(List.of(tool2.tool()));
});
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -991,8 +1013,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
// ---------------------------------------
@ -1056,7 +1079,7 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.build();
var mcpServer = prepareAsyncServerBuilder().serverInfo("test-server", "1.0.0")
.capabilities(ServerCapabilities.builder().logging().tools(true).build())
.capabilities(ServerCapabilities.builder().tools(true).build())
.tools(tool)
.build();
@ -1103,7 +1126,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(notificationMap.get("Another error message").logger()).isEqualTo("test-logger");
assertThat(notificationMap.get("Another error message").data()).isEqualTo("Another error message");
}
mcpServer.close();
finally {
mcpServer.closeGracefully().block();
}
}
// ---------------------------------------
@ -1208,7 +1233,7 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(notificationMap.get("Processing completed").message()).isEqualTo("Processing completed");
}
finally {
mcpServer.close();
mcpServer.closeGracefully().block();
}
}
@ -1258,8 +1283,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(samplingRequest.get().argument().value()).isEqualTo("py");
assertThat(samplingRequest.get().ref().type()).isEqualTo("ref/prompt");
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
// ---------------------------------------
@ -1320,8 +1346,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
// Verify execution order
assertThat(executionOrder.get()).isEqualTo("123");
}
mcpServer.close();
finally {
mcpServer.closeGracefully().block();
}
}
// ---------------------------------------
@ -1396,8 +1423,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.isEqualTo(json("""
{"result":5.0,"operation":"2 + 3","timestamp":"2024-01-01T10:00:00Z"}"""));
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -1450,8 +1478,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
String errorMessage = ((McpSchema.TextContent) response.content().get(0)).text();
assertThat(errorMessage).contains("Validation failed");
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -1500,8 +1529,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
assertThat(errorMessage).isEqualTo(
"Response missing structured content which is expected when calling tool with non-empty outputSchema");
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -1577,8 +1607,9 @@ public abstract class AbstractMcpClientServerIntegrationTests {
.isEqualTo(json("""
{"count":3,"message":"Dynamic execution"}"""));
}
mcpServer.close();
finally {
mcpServer.closeGracefully();
}
}
private double evaluateExpression(String expression) {

View file

@ -151,8 +151,9 @@ class HttpServletStatelessIntegrationTests {
assertThat(response).isNotNull();
assertThat(response).isEqualTo(callResponse);
}
mcpServer.close();
finally {
mcpServer.close();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -167,8 +168,9 @@ class HttpServletStatelessIntegrationTests {
InitializeResult initResult = mcpClient.initialize();
assertThat(initResult).isNotNull();
}
mcpServer.close();
finally {
mcpServer.close();
}
}
// ---------------------------------------
@ -218,8 +220,9 @@ class HttpServletStatelessIntegrationTests {
assertThat(samplingRequest.get().argument().value()).isEqualTo("py");
assertThat(samplingRequest.get().ref().type()).isEqualTo("ref/prompt");
}
mcpServer.close();
finally {
mcpServer.close();
}
}
// ---------------------------------------
@ -290,8 +293,9 @@ class HttpServletStatelessIntegrationTests {
.isEqualTo(json("""
{"result":5.0,"operation":"2 + 3","timestamp":"2024-01-01T10:00:00Z"}"""));
}
mcpServer.close();
finally {
mcpServer.close();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -342,8 +346,9 @@ class HttpServletStatelessIntegrationTests {
String errorMessage = ((McpSchema.TextContent) response.content().get(0)).text();
assertThat(errorMessage).contains("Validation failed");
}
mcpServer.close();
finally {
mcpServer.close();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -391,8 +396,9 @@ class HttpServletStatelessIntegrationTests {
assertThat(errorMessage).isEqualTo(
"Response missing structured content which is expected when calling tool with non-empty outputSchema");
}
mcpServer.close();
finally {
mcpServer.close();
}
}
@ParameterizedTest(name = "{0} : {displayName} ")
@ -465,8 +471,9 @@ class HttpServletStatelessIntegrationTests {
.isEqualTo(json("""
{"count":3,"message":"Dynamic execution"}"""));
}
mcpServer.close();
finally {
mcpServer.close();
}
}
@Test