From 22d9874ae05c2adaf1eea9fe45e1e6f40c30fb04 Mon Sep 17 00:00:00 2001 From: artur-ciocanu Date: Mon, 10 Feb 2025 02:02:43 +0200 Subject: [PATCH] Add app health check support to Dapr Testcontainer (#1213) * Add app health check support to Dapr Testcontainer Signed-off-by: Artur Ciocanu * Some minor cleanup Signed-off-by: Artur Ciocanu * Move waiting to beforeEach, it looks more natural Signed-off-by: Artur Ciocanu --------- Signed-off-by: Artur Ciocanu Co-authored-by: Artur Ciocanu --- .../messaging/DaprSpringMessagingIT.java | 18 +++++++++--------- .../spring/messaging/TestRestController.java | 2 +- .../io/dapr/testcontainers/DaprContainer.java | 18 +++++++++++++++--- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/sdk-tests/src/test/java/io/dapr/it/spring/messaging/DaprSpringMessagingIT.java b/sdk-tests/src/test/java/io/dapr/it/spring/messaging/DaprSpringMessagingIT.java index fc03f4412a..1e41186df4 100644 --- a/sdk-tests/src/test/java/io/dapr/it/spring/messaging/DaprSpringMessagingIT.java +++ b/sdk-tests/src/test/java/io/dapr/it/spring/messaging/DaprSpringMessagingIT.java @@ -23,16 +23,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Disabled; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; import org.testcontainers.containers.Network; +import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -56,8 +54,9 @@ public class DaprSpringMessagingIT { private static final Logger logger = LoggerFactory.getLogger(DaprSpringMessagingIT.class); private static final String TOPIC = "mockTopic"; - private static final Network DAPR_NETWORK = Network.newNetwork(); + private static final int APP_PORT = 8080; + private static final String SUBSCRIPTION_MESSAGE_PATTERN = ".*app is subscribed to the following topics.*"; @Container @ServiceConnection @@ -65,7 +64,8 @@ public class DaprSpringMessagingIT { .withAppName("messaging-dapr-app") .withNetwork(DAPR_NETWORK) .withComponent(new Component("pubsub", "pubsub.in-memory", "v1", Collections.emptyMap())) - .withAppPort(8080) + .withAppPort(APP_PORT) + .withAppHealthCheckPath("/ready") .withDaprLogLevel(DaprLogLevel.DEBUG) .withLogConsumer(outputFrame -> System.out.println(outputFrame.getUtf8String())) .withAppChannelAddress("host.testcontainers.internal"); @@ -78,16 +78,16 @@ public class DaprSpringMessagingIT { @BeforeAll public static void beforeAll(){ - org.testcontainers.Testcontainers.exposeHostPorts(8080); + org.testcontainers.Testcontainers.exposeHostPorts(APP_PORT); } @BeforeEach - public void beforeEach() throws InterruptedException { - Thread.sleep(1000); + public void beforeEach() { + // Ensure the subscriptions are registered + Wait.forLogMessage(SUBSCRIPTION_MESSAGE_PATTERN, 1).waitUntilReady(DAPR_CONTAINER); } @Test - @Disabled("Test is flaky due to global state in the spring test application.") public void testDaprMessagingTemplate() throws InterruptedException { for (int i = 0; i < 10; i++) { var msg = "ProduceAndReadWithPrimitiveMessageType:" + i; diff --git a/sdk-tests/src/test/java/io/dapr/it/spring/messaging/TestRestController.java b/sdk-tests/src/test/java/io/dapr/it/spring/messaging/TestRestController.java index a5d12093c0..963cf6b3f6 100644 --- a/sdk-tests/src/test/java/io/dapr/it/spring/messaging/TestRestController.java +++ b/sdk-tests/src/test/java/io/dapr/it/spring/messaging/TestRestController.java @@ -33,7 +33,7 @@ public class TestRestController { private static final Logger LOG = LoggerFactory.getLogger(TestRestController.class); private final List> events = new ArrayList<>(); - @GetMapping("/") + @GetMapping("/ready") public String ok() { return "OK"; } diff --git a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java index 9a9ef49870..145f61deaa 100644 --- a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java +++ b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/DaprContainer.java @@ -68,6 +68,7 @@ public class DaprContainer extends GenericContainer { private DaprPlacementContainer placementContainer; private String appName; private Integer appPort; + private String appHealthCheckPath; private boolean shouldReusePlacement; /** @@ -116,6 +117,11 @@ public DaprContainer withAppChannelAddress(String appChannelAddress) { return this; } + public DaprContainer withAppHealthCheckPath(String appHealthCheckPath) { + this.appHealthCheckPath = appHealthCheckPath; + return this; + } + public DaprContainer withConfiguration(Configuration configuration) { this.configuration = configuration; return this; @@ -173,7 +179,7 @@ public DaprContainer withComponent(Component component) { */ public DaprContainer withComponent(Path path) { try { - Map component = this.YAML_MAPPER.loadAs(Files.newInputStream(path), Map.class); + Map component = YAML_MAPPER.loadAs(Files.newInputStream(path), Map.class); String type = (String) component.get("type"); Map metadata = (Map) component.get("metadata"); @@ -233,12 +239,12 @@ protected void configure() { List cmds = new ArrayList<>(); cmds.add("./daprd"); - cmds.add("-app-id"); + cmds.add("--app-id"); cmds.add(appName); cmds.add("--dapr-listen-addresses=0.0.0.0"); cmds.add("--app-protocol"); cmds.add(DAPR_PROTOCOL.getName()); - cmds.add("-placement-host-address"); + cmds.add("--placement-host-address"); cmds.add(placementService + ":50005"); if (appChannelAddress != null && !appChannelAddress.isEmpty()) { @@ -251,6 +257,12 @@ protected void configure() { cmds.add(Integer.toString(appPort)); } + if (appHealthCheckPath != null && !appHealthCheckPath.isEmpty()) { + cmds.add("--enable-app-health-check"); + cmds.add("--app-health-check-path"); + cmds.add(appHealthCheckPath); + } + if (configuration != null) { cmds.add("--config"); cmds.add("/dapr-resources/" + configuration.getName() + ".yaml");