feat(test): Use dynamic port allocation in integration tests (#133)

- Add TestUtil class with findAvailablePort() method to the mcp-test module
- Add findAvailablePort() method to TomcatTestUtil classes
- Replace hardcoded port numbers with dynamic port allocation

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
a.darafeyeu 2025-04-09 19:43:29 +02:00 • committed by Christian Tzolov
commit 263e3741b2
3 changed files with 87 additions and 29 deletions

View file

@ -4,6 +4,7 @@
package io.modelcontextprotocol.server.transport;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
import io.modelcontextprotocol.server.McpServer;
@ -17,9 +18,9 @@ import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class HttpServletSseServerCustomContextPathTests {
class HttpServletSseServerCustomContextPathTests {
private static final int PORT = 8195;
private static final int PORT = TomcatTestUtil.findAvailablePort();
private static final String CUSTOM_CONTEXT_PATH = "/api/v1";
@ -48,7 +49,7 @@ public class HttpServletSseServerCustomContextPathTests {
try {
tomcat.start();
assertThat(tomcat.getServer().getState() == LifecycleState.STARTED);
assertThat(tomcat.getServer().getState()).isEqualTo(LifecycleState.STARTED);
}
catch (Exception e) {
throw new RuntimeException("Failed to start Tomcat", e);

View file

@ -12,6 +12,7 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.client.McpClient;
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
import io.modelcontextprotocol.server.McpServer;
@ -44,9 +45,9 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import static org.mockito.Mockito.mock;
public class HttpServletSseServerTransportProviderIntegrationTests {
class HttpServletSseServerTransportProviderIntegrationTests {
private static final int PORT = 8189;
private static final int PORT = TomcatTestUtil.findAvailablePort();
private static final String CUSTOM_SSE_ENDPOINT = "/somePath/sse";
@ -70,7 +71,7 @@ public class HttpServletSseServerTransportProviderIntegrationTests {
tomcat = TomcatTestUtil.createTomcatServer("", PORT, mcpServerTransportProvider);
try {
tomcat.start();
assertThat(tomcat.getServer().getState() == LifecycleState.STARTED);
assertThat(tomcat.getServer().getState()).isEqualTo(LifecycleState.STARTED);
}
catch (Exception e) {
throw new RuntimeException("Failed to start Tomcat", e);
@ -133,7 +134,7 @@ public class HttpServletSseServerTransportProviderIntegrationTests {
}
@Test
void testCreateMessageSuccess() throws InterruptedException {
void testCreateMessageSuccess() {
Function<CreateMessageRequest, CreateMessageResult> samplingHandler = request -> {
assertThat(request.messages()).hasSize(1);

View file

@ -3,19 +3,23 @@
*/
package io.modelcontextprotocol.server.transport;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import jakarta.servlet.Servlet;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleState;
import org.apache.catalina.startup.Tomcat;
import static org.junit.Assert.assertThat;
/**
* @author Christian Tzolov
*/
public class TomcatTestUtil {
TomcatTestUtil() {
// Prevent instantiation
}
public static Tomcat createTomcatServer(String contextPath, int port, Servlet servlet) {
var tomcat = new Tomcat();
@ -24,7 +28,6 @@ public class TomcatTestUtil {
String baseDir = System.getProperty("java.io.tmpdir");
tomcat.setBaseDir(baseDir);
// Context context = tomcat.addContext("", baseDir);
Context context = tomcat.addContext(contextPath, baseDir);
// Add transport servlet to Tomcat
@ -42,4 +45,19 @@ public class TomcatTestUtil {
return tomcat;
}
/**
* Finds an available port on the local machine.
* @return an available port number
* @throws IllegalStateException if no available port can be found
*/
public static int findAvailablePort() {
try (final ServerSocket socket = new ServerSocket()) {
socket.bind(new InetSocketAddress(0));
return socket.getLocalPort();
}
catch (final IOException e) {
throw new IllegalStateException("Cannot bind to an available port!", e);
}
}
}