diff --git a/sdk-spring-boot-starter/src/test/java/dev/restate/sdk/springboot/SdkTestingIntegrationTest.java b/sdk-spring-boot-starter/src/test/java/dev/restate/sdk/springboot/SdkTestingIntegrationTest.java index b08c70ec..aa2ad3b9 100644 --- a/sdk-spring-boot-starter/src/test/java/dev/restate/sdk/springboot/SdkTestingIntegrationTest.java +++ b/sdk-spring-boot-starter/src/test/java/dev/restate/sdk/springboot/SdkTestingIntegrationTest.java @@ -20,7 +20,7 @@ @SpringBootTest( classes = Greeter.class, properties = {"greetingPrefix=Something something "}) -@RestateTest(restateContainerImage = "ghcr.io/restatedev/restate:main") +@RestateTest(containerImage = "ghcr.io/restatedev/restate:main") public class SdkTestingIntegrationTest { @Autowired @BindService private Greeter greeter; diff --git a/sdk-testing/src/main/java/dev/restate/sdk/testing/ManualRestateRunner.java b/sdk-testing/src/main/java/dev/restate/sdk/testing/ManualRestateRunner.java index 7b6194ac..60dfe37a 100644 --- a/sdk-testing/src/main/java/dev/restate/sdk/testing/ManualRestateRunner.java +++ b/sdk-testing/src/main/java/dev/restate/sdk/testing/ManualRestateRunner.java @@ -63,6 +63,9 @@ public class ManualRestateRunner this.runtimeContainer // We expose these ports only to enable port checks .withExposedPorts(RESTATE_INGRESS_ENDPOINT_PORT, RESTATE_ADMIN_ENDPOINT_PORT) + // Let's have a high logging level by default to avoid spamming too much, it can be + // overriden by the user + .withEnv("RUST_LOG", "warn") .withEnv(additionalEnv) // These envs should not be overriden by additionalEnv .withEnv("RESTATE_META__REST_ADDRESS", "0.0.0.0:" + RESTATE_ADMIN_ENDPOINT_PORT) @@ -70,11 +73,19 @@ public class ManualRestateRunner "RESTATE_WORKER__INGRESS__BIND_ADDRESS", "0.0.0.0:" + RESTATE_INGRESS_ENDPOINT_PORT) .withNetworkAliases(RESTATE_RUNTIME) // Configure wait strategy on health paths - .setWaitStrategy( + .waitingFor( new WaitAllStrategy() .withStrategy(Wait.forHttp("/health").forPort(RESTATE_ADMIN_ENDPOINT_PORT)) .withStrategy( - Wait.forHttp("/restate/health").forPort(RESTATE_INGRESS_ENDPOINT_PORT))); + Wait.forHttp("/restate/health").forPort(RESTATE_INGRESS_ENDPOINT_PORT))) + .withLogConsumer( + outputFrame -> { + switch (outputFrame.getType()) { + case STDOUT, STDERR -> + LOG.debug("[restate] {}", outputFrame.getUtf8StringWithoutLineEnding()); + case END -> LOG.debug("[restate] END"); + } + }); if (configFile != null) { this.runtimeContainer.withCopyToContainer(Transferable.of(configFile), "/config.yaml"); diff --git a/sdk-testing/src/main/java/dev/restate/sdk/testing/RestateExtension.java b/sdk-testing/src/main/java/dev/restate/sdk/testing/RestateExtension.java index e1a8a80a..13a7a66e 100644 --- a/sdk-testing/src/main/java/dev/restate/sdk/testing/RestateExtension.java +++ b/sdk-testing/src/main/java/dev/restate/sdk/testing/RestateExtension.java @@ -9,6 +9,7 @@ package dev.restate.sdk.testing; import java.util.List; +import java.util.regex.Pattern; import org.junit.jupiter.api.extension.*; import org.junit.platform.commons.support.AnnotationSupport; @@ -74,7 +75,19 @@ private RestateRunner initializeRestateRunner(ExtensionContext extensionContext) // Build runner discovering services to bind var runnerBuilder = RestateRunnerBuilder.create(); servicesToBind.forEach(runnerBuilder::bind); - runnerBuilder.withRestateContainerImage(testAnnotation.restateContainerImage()); + runnerBuilder.withRestateContainerImage(testAnnotation.containerImage()); + if (testAnnotation.environment() != null) { + for (String env : testAnnotation.environment()) { + String[] splitEnv = env.split(Pattern.quote("="), 2); + if (splitEnv.length != 2) { + throw new IllegalStateException( + "Environment variables should be passed in the form of NAME=VALUE. Found an invalid env: '" + + env + + "'"); + } + runnerBuilder.withAdditionalEnv(splitEnv[0], splitEnv[1]); + } + } return runnerBuilder.buildRunner(); } } diff --git a/sdk-testing/src/main/java/dev/restate/sdk/testing/RestateTest.java b/sdk-testing/src/main/java/dev/restate/sdk/testing/RestateTest.java index 0f13f761..667cf633 100644 --- a/sdk-testing/src/main/java/dev/restate/sdk/testing/RestateTest.java +++ b/sdk-testing/src/main/java/dev/restate/sdk/testing/RestateTest.java @@ -42,8 +42,8 @@ * href="https://java.testcontainers.org/">Testcontainers, and register the services. * *
This extension is scoped per test class, meaning that the restate runner will be shared among - * test methods. Because of the aforementioned issue, the extension sets the {@link TestInstance} - * {@link TestInstance.Lifecycle#PER_CLASS} automatically. + * test methods. Because of this behaviour, the extension sets the {@link TestInstance} as {@link + * TestInstance.Lifecycle#PER_CLASS} automatically. * *
Use the annotations {@link RestateClient}, {@link RestateURL} and {@link RestateAdminClient} * to interact with the deployed environment: @@ -66,6 +66,14 @@ @TestInstance(TestInstance.Lifecycle.PER_CLASS) public @interface RestateTest { + /** + * Environment variables in form {@literal key=value} that should be added to the deployed Restate + * container. + * + * @return the environment variables to add + */ + String[] environment() default {}; + /** Restate container image to use */ - String restateContainerImage() default "docker.io/restatedev/restate:latest"; + String containerImage() default "docker.io/restatedev/restate:latest"; } diff --git a/sdk-testing/src/test/java/dev/restate/sdk/testing/CounterTest.java b/sdk-testing/src/test/java/dev/restate/sdk/testing/CounterTest.java index d1d182b1..59016588 100644 --- a/sdk-testing/src/test/java/dev/restate/sdk/testing/CounterTest.java +++ b/sdk-testing/src/test/java/dev/restate/sdk/testing/CounterTest.java @@ -14,7 +14,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; -@RestateTest(restateContainerImage = "ghcr.io/restatedev/restate:main") +@RestateTest(containerImage = "ghcr.io/restatedev/restate:main") class CounterTest { @BindService private final Counter counter = new Counter();