Skip to content

Commit 58e6419

Browse files
committed
Stabilize actor IT runtime isolation and bootstrap waits
Signed-off-by: Artur Ciocanu <artur.ciocanu@gmail.com>
1 parent 6f3790b commit 58e6419

13 files changed

Lines changed: 114 additions & 31 deletions

File tree

sdk-tests/src/test/java/io/dapr/it/actors/ActivationDeactivationIT.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import io.dapr.testcontainers.internal.DaprContainerFactory;
2828
import io.dapr.testcontainers.internal.DaprSidecarContainer;
2929
import io.dapr.testcontainers.internal.spring.DaprSpringBootTest;
30-
import io.dapr.testcontainers.wait.strategy.DaprWait;
3130
import org.junit.jupiter.api.BeforeEach;
3231
import org.junit.jupiter.api.Test;
3332
import org.slf4j.Logger;
@@ -69,8 +68,7 @@ void setUp() {
6968
actorRuntime.getConfig().setDrainOngoingCallTimeout(Duration.ofSeconds(10));
7069
actorRuntime.getConfig().setDrainBalancedActors(true);
7170
actorRuntime.registerActor(DemoActorImpl.class);
72-
org.testcontainers.Testcontainers.exposeHostPorts(DAPR_CONTAINER.getAppPort());
73-
DaprWait.forActors().waitUntilReady(DAPR_CONTAINER);
71+
ActorTestBootstrap.exposeHostPortAndWaitForActorType(DAPR_CONTAINER, "DemoActorTest");
7472
}
7573

7674
@Test

sdk-tests/src/test/java/io/dapr/it/actors/ActorExceptionIT.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import io.dapr.testcontainers.internal.DaprContainerFactory;
2727
import io.dapr.testcontainers.internal.DaprSidecarContainer;
2828
import io.dapr.testcontainers.internal.spring.DaprSpringBootTest;
29-
import io.dapr.testcontainers.wait.strategy.DaprWait;
3029
import org.junit.jupiter.api.BeforeEach;
3130
import org.junit.jupiter.api.Test;
3231
import org.slf4j.Logger;
@@ -58,8 +57,7 @@ public class ActorExceptionIT {
5857

5958
@BeforeEach
6059
public void setUp() {
61-
org.testcontainers.Testcontainers.exposeHostPorts(DAPR_CONTAINER.getAppPort());
62-
DaprWait.forActors().waitUntilReady(DAPR_CONTAINER);
60+
ActorTestBootstrap.exposeHostPortAndWaitForActorType(DAPR_CONTAINER, "MyActorTest");
6361
}
6462

6563
private ActorClient newActorClient(Map<String, String> metadata) {

sdk-tests/src/test/java/io/dapr/it/actors/ActorMethodNameIT.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import io.dapr.testcontainers.internal.DaprContainerFactory;
2727
import io.dapr.testcontainers.internal.DaprSidecarContainer;
2828
import io.dapr.testcontainers.internal.spring.DaprSpringBootTest;
29-
import io.dapr.testcontainers.wait.strategy.DaprWait;
3029
import org.junit.jupiter.api.BeforeEach;
3130
import org.junit.jupiter.api.Test;
3231
import org.slf4j.Logger;
@@ -58,8 +57,7 @@ public class ActorMethodNameIT {
5857

5958
@BeforeEach
6059
void setUp() {
61-
org.testcontainers.Testcontainers.exposeHostPorts(DAPR_CONTAINER.getAppPort());
62-
DaprWait.forActors().waitUntilReady(DAPR_CONTAINER);
60+
ActorTestBootstrap.exposeHostPortAndWaitForActorType(DAPR_CONTAINER, "MyActorTest");
6361
}
6462

6563
@Test

sdk-tests/src/test/java/io/dapr/it/actors/ActorReminderRecoveryIT.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@
2727
import io.dapr.testcontainers.internal.DaprContainerFactory;
2828
import io.dapr.testcontainers.internal.DaprSidecarContainer;
2929
import io.dapr.testcontainers.internal.spring.DaprSpringBootTest;
30-
import io.dapr.testcontainers.wait.strategy.DaprWait;
3130
import org.junit.jupiter.api.AfterEach;
32-
import org.junit.jupiter.api.BeforeEach;
3331
import org.junit.jupiter.params.ParameterizedTest;
3432
import org.junit.jupiter.params.provider.Arguments;
3533
import org.junit.jupiter.params.provider.MethodSource;
@@ -106,13 +104,8 @@ public static Stream<Arguments> data() {
106104
);
107105
}
108106

109-
@BeforeEach
110-
public void setUp() {
111-
org.testcontainers.Testcontainers.exposeHostPorts(DAPR_CONTAINER.getAppPort());
112-
}
113-
114107
public void setup(String actorType) {
115-
DaprWait.forActorType(actorType).waitUntilReady(DAPR_CONTAINER);
108+
ActorTestBootstrap.exposeHostPortAndWaitForActorType(DAPR_CONTAINER, actorType);
116109

117110
this.actorType = actorType;
118111
this.actorId = new ActorId(UUID.randomUUID().toString());

sdk-tests/src/test/java/io/dapr/it/actors/ActorSdkResiliencyIT.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import io.dapr.testcontainers.internal.DaprContainerFactory;
3333
import io.dapr.testcontainers.internal.DaprSidecarContainer;
3434
import io.dapr.testcontainers.internal.spring.DaprSpringBootTest;
35-
import io.dapr.testcontainers.wait.strategy.DaprWait;
3635
import org.junit.jupiter.api.AfterAll;
3736
import org.junit.jupiter.api.BeforeAll;
3837
import org.junit.jupiter.api.BeforeEach;
@@ -117,8 +116,7 @@ public static void init() throws IOException {
117116

118117
@BeforeEach
119118
public void setUp() throws Exception {
120-
org.testcontainers.Testcontainers.exposeHostPorts(DAPR_CONTAINER.getAppPort());
121-
DaprWait.forActorType("DemoActorTest").waitUntilReady(DAPR_CONTAINER);
119+
ActorTestBootstrap.exposeHostPortAndWaitForActorType(DAPR_CONTAINER, "DemoActorTest");
122120

123121
removeToxics(grpcProxy);
124122
removeToxics(httpProxy);

sdk-tests/src/test/java/io/dapr/it/actors/ActorStateIT.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import io.dapr.testcontainers.internal.DaprContainerFactory;
2727
import io.dapr.testcontainers.internal.DaprSidecarContainer;
2828
import io.dapr.testcontainers.internal.spring.DaprSpringBootTest;
29-
import io.dapr.testcontainers.wait.strategy.DaprWait;
3029
import org.junit.jupiter.api.BeforeEach;
3130
import org.junit.jupiter.api.Test;
3231
import org.slf4j.Logger;
@@ -60,8 +59,7 @@ public class ActorStateIT {
6059

6160
@BeforeEach
6261
void setUp() {
63-
org.testcontainers.Testcontainers.exposeHostPorts(DAPR_CONTAINER.getAppPort());
64-
DaprWait.forActorType("StatefulActorTest").waitUntilReady(DAPR_CONTAINER);
62+
ActorTestBootstrap.exposeHostPortAndWaitForActorType(DAPR_CONTAINER, "StatefulActorTest");
6563
}
6664

6765
@Test
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2026 The Dapr Authors
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*/
13+
14+
package io.dapr.it.actors;
15+
16+
import io.dapr.testcontainers.DaprContainer;
17+
import io.dapr.testcontainers.wait.strategy.DaprWait;
18+
19+
import java.time.Duration;
20+
21+
/**
22+
* Shared bootstrap helpers for actor integration tests.
23+
*/
24+
public final class ActorTestBootstrap {
25+
26+
private static final Duration DEFAULT_ACTOR_WAIT_TIMEOUT = Duration.ofMinutes(2);
27+
28+
private ActorTestBootstrap() {
29+
}
30+
31+
/**
32+
* Expose host app port and wait for the given actor type to be registered in Dapr metadata.
33+
*
34+
* @param daprContainer sidecar container
35+
* @param actorType actor type name to wait for
36+
*/
37+
public static void exposeHostPortAndWaitForActorType(DaprContainer daprContainer, String actorType) {
38+
org.testcontainers.Testcontainers.exposeHostPorts(daprContainer.getAppPort());
39+
DaprWait.forActorType(actorType)
40+
.withStartupTimeout(DEFAULT_ACTOR_WAIT_TIMEOUT)
41+
.waitUntilReady(daprContainer);
42+
}
43+
44+
/**
45+
* Expose host app port and wait until at least one actor is registered.
46+
*
47+
* @param daprContainer sidecar container
48+
*/
49+
public static void exposeHostPortAndWaitForAnyActor(DaprContainer daprContainer) {
50+
org.testcontainers.Testcontainers.exposeHostPorts(daprContainer.getAppPort());
51+
DaprWait.forActors()
52+
.withStartupTimeout(DEFAULT_ACTOR_WAIT_TIMEOUT)
53+
.waitUntilReady(daprContainer);
54+
}
55+
}

sdk-tests/src/test/java/io/dapr/it/actors/ActorTimerRecoveryIT.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public class ActorTimerRecoveryIT {
7171
*/
7272
@Test
7373
public void timerRecoveryTest() throws Exception {
74-
org.testcontainers.Testcontainers.exposeHostPorts(DAPR_CONTAINER.getAppPort());
74+
ActorTestBootstrap.exposeHostPortAndWaitForActorType(DAPR_CONTAINER, ACTOR_TYPE);
7575

7676
ActorClient refreshedActorClient = actorClient;
7777
try {
@@ -100,6 +100,7 @@ public void timerRecoveryTest() throws Exception {
100100

101101
DAPR_CONTAINER.stop();
102102
DAPR_CONTAINER.start();
103+
ActorTestBootstrap.exposeHostPortAndWaitForActorType(DAPR_CONTAINER, ACTOR_TYPE);
103104
refreshedActorClient = new ActorClient(new Properties(Map.of(
104105
"dapr.http.endpoint", DAPR_CONTAINER.getHttpEndpoint(),
105106
"dapr.grpc.endpoint", DAPR_CONTAINER.getGrpcEndpoint()

sdk-tests/src/test/java/io/dapr/it/actors/ActorTurnBasedConcurrencyIT.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import io.dapr.testcontainers.internal.DaprContainerFactory;
2727
import io.dapr.testcontainers.internal.DaprSidecarContainer;
2828
import io.dapr.testcontainers.internal.spring.DaprSpringBootTest;
29-
import io.dapr.testcontainers.wait.strategy.DaprWait;
3029
import io.dapr.utils.Version;
3130
import io.grpc.ManagedChannel;
3231
import io.grpc.ManagedChannelBuilder;
@@ -81,8 +80,7 @@ public class ActorTurnBasedConcurrencyIT {
8180

8281
@BeforeEach
8382
public void setUp() {
84-
org.testcontainers.Testcontainers.exposeHostPorts(DAPR_CONTAINER.getAppPort());
85-
DaprWait.forActorType(ACTOR_TYPE).waitUntilReady(DAPR_CONTAINER);
83+
ActorTestBootstrap.exposeHostPortAndWaitForActorType(DAPR_CONTAINER, ACTOR_TYPE);
8684
}
8785

8886
@AfterEach

sdk-tests/src/test/java/io/dapr/it/testcontainers/actors/TestDaprActorsConfiguration.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313

1414
package io.dapr.it.testcontainers.actors;
1515

16-
import java.util.Map;
17-
1816
import io.dapr.actors.runtime.ActorRuntime;
1917
import org.springframework.beans.factory.annotation.Value;
2018
import org.springframework.context.annotation.Bean;
@@ -23,8 +21,13 @@
2321
import io.dapr.actors.client.ActorClient;
2422
import io.dapr.config.Properties;
2523

24+
import java.lang.reflect.Field;
25+
import java.util.Map;
26+
2627
@Configuration
2728
public class TestDaprActorsConfiguration {
29+
private static final Object ACTOR_RUNTIME_RESET_LOCK = new Object();
30+
2831
@Bean
2932
public ActorClient daprActorClient(
3033
@Value("${dapr.http.endpoint}") String daprHttpEndpoint,
@@ -43,11 +46,29 @@ public ActorRuntime daprActorRuntime(
4346
@Value("${dapr.http.endpoint}") String daprHttpEndpoint,
4447
@Value("${dapr.grpc.endpoint}") String daprGrpcEndpoint
4548
){
49+
resetActorRuntimeSingleton();
50+
4651
Map<String, String> overrides = Map.of(
4752
"dapr.http.endpoint", daprHttpEndpoint,
4853
"dapr.grpc.endpoint", daprGrpcEndpoint
4954
);
5055

5156
return ActorRuntime.getInstance(new Properties(overrides));
5257
}
58+
59+
private static void resetActorRuntimeSingleton() {
60+
synchronized (ACTOR_RUNTIME_RESET_LOCK) {
61+
try {
62+
Field instanceField = ActorRuntime.class.getDeclaredField("instance");
63+
instanceField.setAccessible(true);
64+
ActorRuntime instance = (ActorRuntime) instanceField.get(null);
65+
if (instance != null) {
66+
instance.close();
67+
instanceField.set(null, null);
68+
}
69+
} catch (ReflectiveOperationException e) {
70+
throw new IllegalStateException("Failed to reset ActorRuntime singleton for test isolation.", e);
71+
}
72+
}
73+
}
5374
}

0 commit comments

Comments
 (0)