refactor: extract common integration test logic into abstract base classes (#473)
refactor: extract common integration test logic into abstract base classes - Move duplicated test methods from WebFlux and WebMvc integration test classes to abstract base classes - WebFluxSseIntegrationTests, WebFluxStreamableIntegrationTests now extend AbstractMcpClientServerIntegrationTests - WebFluxStatelessIntegrationTests, WebMvcStatelessIntegrationTests now extend AbstractStatelessIntegrationTests - Each concrete test class now only implements transport-specific setup methods (prepareClients, prepareAsyncServerBuilder, prepareSyncServerBuilder) - Eliminates ~1300+ lines of duplicated test code across multiple files - Improves maintainability by centralizing test logic in reusable base classes - Updates WebMvcSseServerTransportProvider to use builder pattern - Adds new HttpServletSseIntegrationTests extending AbstractMcpClientServerIntegrationTests - Removes HttpServletSseServerTransportProviderIntegrationTests - Standardizes timeout configurations and client setup across all integration tests Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
parent
387998389e
commit
dee8411c8f
3 changed files with 792 additions and 4785 deletions
|
|
@ -42,11 +42,11 @@ class WebMvcSseIntegrationTests extends AbstractMcpClientServerIntegrationTests
|
|||
|
||||
clientBuilders.put("httpclient",
|
||||
McpClient.sync(HttpClientSseClientTransport.builder("http://localhost:" + port).build())
|
||||
.initializationTimeout(Duration.ofHours(10))
|
||||
.requestTimeout(Duration.ofHours(10)));
|
||||
|
||||
clientBuilders.put("webflux", McpClient
|
||||
.sync(WebFluxSseClientTransport.builder(WebClient.builder().baseUrl("http://localhost:" + port)).build()));
|
||||
.sync(WebFluxSseClientTransport.builder(WebClient.builder().baseUrl("http://localhost:" + port)).build())
|
||||
.requestTimeout(Duration.ofHours(10)));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
|
|
@ -55,7 +55,10 @@ class WebMvcSseIntegrationTests extends AbstractMcpClientServerIntegrationTests
|
|||
|
||||
@Bean
|
||||
public WebMvcSseServerTransportProvider webMvcSseServerTransportProvider() {
|
||||
return new WebMvcSseServerTransportProvider(new ObjectMapper(), MESSAGE_ENDPOINT);
|
||||
return WebMvcSseServerTransportProvider.builder()
|
||||
.objectMapper(new ObjectMapper())
|
||||
.messageEndpoint(MESSAGE_ENDPOINT)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ import org.apache.catalina.LifecycleException;
|
|||
import org.apache.catalina.LifecycleState;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
|
@ -29,7 +27,6 @@ import io.modelcontextprotocol.client.transport.WebClientStreamableHttpTransport
|
|||
import io.modelcontextprotocol.server.McpServer.StatelessAsyncSpecification;
|
||||
import io.modelcontextprotocol.server.McpServer.StatelessSyncSpecification;
|
||||
import io.modelcontextprotocol.server.transport.WebMvcStatelessServerTransport;
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
class WebMvcStatelessIntegrationTests extends AbstractStatelessIntegrationTests {
|
||||
|
|
@ -63,6 +60,32 @@ class WebMvcStatelessIntegrationTests extends AbstractStatelessIntegrationTests
|
|||
|
||||
private TomcatTestUtil.TomcatServer tomcatServer;
|
||||
|
||||
@Override
|
||||
protected StatelessAsyncSpecification prepareAsyncServerBuilder() {
|
||||
return McpServer.async(this.mcpServerTransport);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StatelessSyncSpecification prepareSyncServerBuilder() {
|
||||
return McpServer.sync(this.mcpServerTransport);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void prepareClients(int port, String mcpEndpoint) {
|
||||
|
||||
clientBuilders.put("httpclient", McpClient
|
||||
.sync(HttpClientStreamableHttpTransport.builder("http://localhost:" + port).endpoint(mcpEndpoint).build())
|
||||
.requestTimeout(Duration.ofHours(10)));
|
||||
|
||||
clientBuilders.put("webflux",
|
||||
McpClient
|
||||
.sync(WebClientStreamableHttpTransport
|
||||
.builder(WebClient.builder().baseUrl("http://localhost:" + port))
|
||||
.endpoint(mcpEndpoint)
|
||||
.build())
|
||||
.requestTimeout(Duration.ofHours(10)));
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
|
||||
|
|
@ -76,33 +99,13 @@ class WebMvcStatelessIntegrationTests extends AbstractStatelessIntegrationTests
|
|||
throw new RuntimeException("Failed to start Tomcat", e);
|
||||
}
|
||||
|
||||
clientBuilders
|
||||
.put("httpclient",
|
||||
McpClient.sync(HttpClientStreamableHttpTransport.builder("http://localhost:" + PORT)
|
||||
.endpoint(MESSAGE_ENDPOINT)
|
||||
.build()).initializationTimeout(Duration.ofHours(10)).requestTimeout(Duration.ofHours(10)));
|
||||
|
||||
clientBuilders.put("webflux",
|
||||
McpClient.sync(WebClientStreamableHttpTransport
|
||||
.builder(WebClient.builder().baseUrl("http://localhost:" + PORT))
|
||||
.endpoint(MESSAGE_ENDPOINT)
|
||||
.build()));
|
||||
prepareClients(PORT, MESSAGE_ENDPOINT);
|
||||
|
||||
// Get the transport from Spring context
|
||||
this.mcpServerTransport = tomcatServer.appContext().getBean(WebMvcStatelessServerTransport.class);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StatelessAsyncSpecification prepareAsyncServerBuilder() {
|
||||
return McpServer.async(this.mcpServerTransport);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StatelessSyncSpecification prepareSyncServerBuilder() {
|
||||
return McpServer.sync(this.mcpServerTransport);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void after() {
|
||||
reactor.netty.http.HttpResources.disposeLoopsAndConnections();
|
||||
|
|
@ -124,42 +127,4 @@ class WebMvcStatelessIntegrationTests extends AbstractStatelessIntegrationTests
|
|||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "{0} : {displayName} ")
|
||||
@ValueSource(strings = { "httpclient", "webflux" })
|
||||
void simple(String clientType) {
|
||||
|
||||
var clientBuilder = clientBuilders.get(clientType);
|
||||
|
||||
var server = McpServer.async(this.mcpServerTransport)
|
||||
.serverInfo("test-server", "1.0.0")
|
||||
.requestTimeout(Duration.ofSeconds(1000))
|
||||
.build();
|
||||
|
||||
try (
|
||||
// Create client without sampling capabilities
|
||||
var client = clientBuilder.clientInfo(new McpSchema.Implementation("Sample " + "client", "0.0.0"))
|
||||
.requestTimeout(Duration.ofSeconds(1000))
|
||||
.build()) {
|
||||
|
||||
assertThat(client.initialize()).isNotNull();
|
||||
|
||||
}
|
||||
server.closeGracefully();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void prepareClients(int port, String mcpEndpoint) {
|
||||
|
||||
clientBuilders.put("httpclient", McpClient
|
||||
.sync(HttpClientStreamableHttpTransport.builder("http://localhost:" + port).endpoint(mcpEndpoint).build())
|
||||
.initializationTimeout(Duration.ofHours(10))
|
||||
.requestTimeout(Duration.ofHours(10)));
|
||||
|
||||
clientBuilders.put("webflux",
|
||||
McpClient.sync(WebClientStreamableHttpTransport
|
||||
.builder(WebClient.builder().baseUrl("http://localhost:" + port))
|
||||
.endpoint(mcpEndpoint)
|
||||
.build()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,42 +124,20 @@ class WebMvcStreamableIntegrationTests extends AbstractMcpClientServerIntegratio
|
|||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "{0} : {displayName} ")
|
||||
@ValueSource(strings = { "httpclient", "webflux" })
|
||||
void simple(String clientType) {
|
||||
|
||||
var clientBuilder = clientBuilders.get(clientType);
|
||||
|
||||
var server = McpServer.async(mcpServerTransportProvider)
|
||||
.serverInfo("test-server", "1.0.0")
|
||||
.requestTimeout(Duration.ofSeconds(1000))
|
||||
.build();
|
||||
|
||||
try (
|
||||
// Create client without sampling capabilities
|
||||
var client = clientBuilder.clientInfo(new McpSchema.Implementation("Sample " + "client", "0.0.0"))
|
||||
.requestTimeout(Duration.ofSeconds(1000))
|
||||
.build()) {
|
||||
|
||||
assertThat(client.initialize()).isNotNull();
|
||||
|
||||
}
|
||||
server.closeGracefully();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void prepareClients(int port, String mcpEndpoint) {
|
||||
|
||||
clientBuilders.put("httpclient", McpClient
|
||||
.sync(HttpClientStreamableHttpTransport.builder("http://localhost:" + port).endpoint(mcpEndpoint).build())
|
||||
.initializationTimeout(Duration.ofHours(10))
|
||||
.requestTimeout(Duration.ofHours(10)));
|
||||
|
||||
clientBuilders.put("webflux",
|
||||
McpClient.sync(WebClientStreamableHttpTransport
|
||||
.builder(WebClient.builder().baseUrl("http://localhost:" + port))
|
||||
.endpoint(mcpEndpoint)
|
||||
.build()));
|
||||
McpClient
|
||||
.sync(WebClientStreamableHttpTransport
|
||||
.builder(WebClient.builder().baseUrl("http://localhost:" + port))
|
||||
.endpoint(mcpEndpoint)
|
||||
.build())
|
||||
.requestTimeout(Duration.ofHours(10)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue