test: upgrade mcp-everything-server to v3 and fix resiliency test race condition (#536)

- Upgrade Docker test server image from v2 to v3 across all test files
- Updates all test files to use the latest version of the mcp-everything-server
Docker image (v3) for integration testing.
- Fix race condition in async client tests by not advertising roots capability during initialization
  - Prevents server from listing roots during init which could cause timing issues when disconnecting immediately after initialization
- Applied fix to AbstractMcpAsyncClientResiliencyTests (both mcp and mcp-test modules) and HttpSseMcpAsyncClientLostConnectionTests

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
Co-authored-by: Daniel Garnier-Moiroux <git@garnier.wf>
This commit is contained in:
Christian Tzolov 2025-09-04 14:46:08 +02:00 • committed by GitHub
commit ec4b329699
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 29 additions and 19 deletions

View file

@ -21,7 +21,7 @@ public class WebClientStreamableHttpAsyncClientTests extends AbstractMcpAsyncCli
// Uses the https://github.com/tzolov/mcp-everything-server-docker-image
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js streamableHttp")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withExposedPorts(3001)

View file

@ -21,7 +21,7 @@ public class WebClientStreamableHttpSyncClientTests extends AbstractMcpSyncClien
// Uses the https://github.com/tzolov/mcp-everything-server-docker-image
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js streamableHttp")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withExposedPorts(3001)

View file

@ -28,7 +28,7 @@ class WebFluxSseMcpAsyncClientTests extends AbstractMcpAsyncClientTests {
// Uses the https://github.com/tzolov/mcp-everything-server-docker-image
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js sse")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withExposedPorts(3001)

View file

@ -28,7 +28,7 @@ class WebFluxSseMcpSyncClientTests extends AbstractMcpSyncClientTests {
// Uses the https://github.com/tzolov/mcp-everything-server-docker-image
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js sse")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withExposedPorts(3001)

View file

@ -20,7 +20,6 @@ import java.util.function.Consumer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.springframework.web.reactive.function.client.WebClient;

View file

@ -44,7 +44,7 @@ class WebFluxSseClientTransportTests {
static String host = "http://localhost:3001";
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js sse")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withExposedPorts(3001)

View file

@ -10,6 +10,7 @@ import eu.rekawek.toxiproxy.model.ToxicDirection;
import io.modelcontextprotocol.spec.McpClientTransport;
import io.modelcontextprotocol.spec.McpSchema;
import io.modelcontextprotocol.spec.McpTransport;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -48,7 +49,7 @@ public abstract class AbstractMcpAsyncClientResiliencyTests {
// Uses the https://github.com/tzolov/mcp-everything-server-docker-image
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js streamableHttp")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withNetwork(network)
@ -134,10 +135,13 @@ public abstract class AbstractMcpAsyncClientResiliencyTests {
AtomicReference<McpAsyncClient> client = new AtomicReference<>();
assertThatCode(() -> {
// Do not advertise roots. Otherwise, the server will list roots during
// initialization. The client responds asynchronously, and there might be a
// rest condition in tests where we disconnect right after initialization.
McpClient.AsyncSpec builder = McpClient.async(transport)
.requestTimeout(getRequestTimeout())
.initializationTimeout(getInitializationTimeout())
.capabilities(McpSchema.ClientCapabilities.builder().roots(true).build());
.capabilities(McpSchema.ClientCapabilities.builder().build());
builder = customizer.apply(builder);
client.set(builder.build());
}).doesNotThrowAnyException();

View file

@ -10,6 +10,7 @@ import eu.rekawek.toxiproxy.model.ToxicDirection;
import io.modelcontextprotocol.spec.McpClientTransport;
import io.modelcontextprotocol.spec.McpSchema;
import io.modelcontextprotocol.spec.McpTransport;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -49,7 +50,7 @@ public abstract class AbstractMcpAsyncClientResiliencyTests {
// Uses the https://github.com/tzolov/mcp-everything-server-docker-image
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js streamableHttp")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withNetwork(network)
@ -135,10 +136,13 @@ public abstract class AbstractMcpAsyncClientResiliencyTests {
AtomicReference<McpAsyncClient> client = new AtomicReference<>();
assertThatCode(() -> {
// Do not advertise roots. Otherwise, the server will list roots during
// initialization. The client responds asynchronously, and there might be a
// rest condition in tests where we disconnect right after initialization.
McpClient.AsyncSpec builder = McpClient.async(transport)
.requestTimeout(getRequestTimeout())
.initializationTimeout(getInitializationTimeout())
.capabilities(McpSchema.ClientCapabilities.builder().roots(true).build());
.capabilities(McpSchema.ClientCapabilities.builder().build());
builder = customizer.apply(builder);
client.set(builder.build());
}).doesNotThrowAnyException();

View file

@ -20,7 +20,7 @@ public class HttpClientStreamableHttpAsyncClientTests extends AbstractMcpAsyncCl
// Uses the https://github.com/tzolov/mcp-everything-server-docker-image
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js streamableHttp")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withExposedPorts(3001)

View file

@ -32,7 +32,7 @@ public class HttpClientStreamableHttpSyncClientTests extends AbstractMcpSyncClie
// Uses the https://github.com/tzolov/mcp-everything-server-docker-image
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js streamableHttp")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withExposedPorts(3001)

View file

@ -28,7 +28,7 @@ import io.modelcontextprotocol.spec.McpClientTransport;
import io.modelcontextprotocol.spec.McpSchema;
import reactor.test.StepVerifier;
@Timeout(15)
@Timeout(20)
public class HttpSseMcpAsyncClientLostConnectionTests {
private static final Logger logger = LoggerFactory.getLogger(HttpSseMcpAsyncClientLostConnectionTests.class);
@ -38,7 +38,7 @@ public class HttpSseMcpAsyncClientLostConnectionTests {
// Uses the https://github.com/tzolov/mcp-everything-server-docker-image
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js sse")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withNetwork(network)
@ -98,10 +98,13 @@ public class HttpSseMcpAsyncClientLostConnectionTests {
AtomicReference<McpAsyncClient> client = new AtomicReference<>();
assertThatCode(() -> {
// Do not advertise roots. Otherwise, the server will list roots during
// initialization. The client responds asynchronously, and there might be a
// rest condition in tests where we disconnect right after initialization.
McpClient.AsyncSpec builder = McpClient.async(transport)
.requestTimeout(Duration.ofSeconds(14))
.initializationTimeout(Duration.ofSeconds(2))
.capabilities(McpSchema.ClientCapabilities.builder().roots(true).build());
.capabilities(McpSchema.ClientCapabilities.builder().build());
client.set(builder.build());
}).doesNotThrowAnyException();

View file

@ -25,7 +25,7 @@ class HttpSseMcpAsyncClientTests extends AbstractMcpAsyncClientTests {
// Uses the https://github.com/tzolov/mcp-everything-server-docker-image
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js sse")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withExposedPorts(3001)

View file

@ -38,7 +38,7 @@ class HttpSseMcpSyncClientTests extends AbstractMcpSyncClientTests {
// Uses the https://github.com/tzolov/mcp-everything-server-docker-image
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js sse")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withExposedPorts(3001)

View file

@ -59,7 +59,7 @@ class HttpClientSseClientTransportTests {
static String host = "http://localhost:3001";
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js sse")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withExposedPorts(3001)

View file

@ -41,7 +41,7 @@ class HttpClientStreamableHttpTransportTest {
.create(Map.of("test-transport-context-key", "some-value"));
@SuppressWarnings("resource")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v2")
static GenericContainer<?> container = new GenericContainer<>("docker.io/tzolov/mcp-everything-server:v3")
.withCommand("node dist/index.js streamableHttp")
.withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String()))
.withExposedPorts(3001)