Skip to content

Commit 8172e1c

Browse files
Add RunRetry test (#10)
Rename SideEffect test to RunFlush
1 parent f812dc0 commit 8172e1c

File tree

4 files changed

+88
-48
lines changed

4 files changed

+88
-48
lines changed

src/main/kotlin/dev/restate/sdktesting/contracts/Failing.kt

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,30 @@ interface Failing {
2121

2222
@Handler suspend fun failingCallWithEventualSuccess(context: ObjectContext): Int
2323

24-
@Handler suspend fun failingSideEffectWithEventualSuccess(context: ObjectContext): Int
25-
2624
@Handler suspend fun terminallyFailingSideEffect(context: ObjectContext, errorMessage: String)
25+
26+
/**
27+
* `minimumAttempts` should be used to check when to succeed. The retry policy should be
28+
* configured to be infinite.
29+
*
30+
* @return the number of executed attempts. In order to implement this count, an atomic counter in
31+
* the service should be used.
32+
*/
33+
@Handler
34+
suspend fun sideEffectSucceedsAfterGivenAttempts(
35+
context: ObjectContext,
36+
minimumAttempts: Int
37+
): Int
38+
39+
/**
40+
* `retryPolicyMaxRetryCount` should be used to configure the retry policy.
41+
*
42+
* @return the number of executed attempts. In order to implement this count, an atomic counter in
43+
* the service should be used.
44+
*/
45+
@Handler
46+
suspend fun sideEffectFailsAfterGivenAttempts(
47+
context: ObjectContext,
48+
retryPolicyMaxRetryCount: Int
49+
): Int
2750
}

src/main/kotlin/dev/restate/sdktesting/tests/SideEffect.kt renamed to src/main/kotlin/dev/restate/sdktesting/tests/RunFlush.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import dev.restate.sdktesting.contracts.TestUtilsServiceDefinitions
1414
import dev.restate.sdktesting.infra.InjectClient
1515
import dev.restate.sdktesting.infra.RestateDeployerExtension
1616
import dev.restate.sdktesting.infra.ServiceSpec
17+
import java.util.*
1718
import kotlinx.coroutines.test.runTest
1819
import org.assertj.core.api.Assertions.assertThat
1920
import org.junit.jupiter.api.DisplayName
@@ -24,7 +25,7 @@ import org.junit.jupiter.api.parallel.Execution
2425
import org.junit.jupiter.api.parallel.ExecutionMode
2526

2627
@Tag("only-always-suspending")
27-
class SideEffect {
28+
class RunFlush {
2829
companion object {
2930
@RegisterExtension
3031
val deployerExt: RestateDeployerExtension = RestateDeployerExtension {
@@ -33,10 +34,10 @@ class SideEffect {
3334
}
3435
}
3536

36-
@DisplayName("Side effect should wait on acknowledgements")
37+
@DisplayName("Run should wait on acknowledgements")
3738
@Test
3839
@Execution(ExecutionMode.CONCURRENT)
39-
fun sideEffectFlush(@InjectClient ingressClient: Client) = runTest {
40+
fun flush(@InjectClient ingressClient: Client) = runTest {
4041
assertThat(TestUtilsServiceClient.fromClient(ingressClient).countExecutedSideEffects(3))
4142
.isEqualTo(0)
4243
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) 2023 - Restate Software, Inc., Restate GmbH
2+
//
3+
// This file is part of the Restate SDK Test suite tool,
4+
// which is released under the MIT license.
5+
//
6+
// You can find a copy of the license in file LICENSE in the root
7+
// directory of this repository or package, or at
8+
// https://github.com/restatedev/sdk-test-suite/blob/main/LICENSE
9+
package dev.restate.sdktesting.tests
10+
11+
import dev.restate.sdk.client.Client
12+
import dev.restate.sdktesting.contracts.FailingClient
13+
import dev.restate.sdktesting.contracts.FailingDefinitions
14+
import dev.restate.sdktesting.infra.InjectClient
15+
import dev.restate.sdktesting.infra.RestateDeployerExtension
16+
import dev.restate.sdktesting.infra.ServiceSpec
17+
import java.util.*
18+
import kotlinx.coroutines.test.runTest
19+
import org.assertj.core.api.Assertions.assertThat
20+
import org.junit.jupiter.api.DisplayName
21+
import org.junit.jupiter.api.Tag
22+
import org.junit.jupiter.api.Test
23+
import org.junit.jupiter.api.extension.RegisterExtension
24+
import org.junit.jupiter.api.parallel.Execution
25+
import org.junit.jupiter.api.parallel.ExecutionMode
26+
27+
@Tag("always-suspending")
28+
class RunRetry {
29+
companion object {
30+
@RegisterExtension
31+
val deployerExt: RestateDeployerExtension = RestateDeployerExtension {
32+
withServiceSpec(ServiceSpec.defaultBuilder().withServices(FailingDefinitions.SERVICE_NAME))
33+
}
34+
}
35+
36+
@DisplayName("Run is retried until it succeeds")
37+
@Test
38+
@Execution(ExecutionMode.CONCURRENT)
39+
fun withSuccess(@InjectClient ingressClient: Client) = runTest {
40+
val attempts = 3
41+
42+
assertThat(
43+
FailingClient.fromClient(ingressClient, UUID.randomUUID().toString())
44+
.sideEffectSucceedsAfterGivenAttempts(attempts))
45+
.isGreaterThanOrEqualTo(attempts)
46+
}
47+
48+
@DisplayName("Run is retried until it exhausts the retry attempts")
49+
@Test
50+
@Execution(ExecutionMode.CONCURRENT)
51+
fun withExhaustedAttempts(@InjectClient ingressClient: Client) = runTest {
52+
val attempts = 3
53+
54+
assertThat(
55+
FailingClient.fromClient(ingressClient, UUID.randomUUID().toString())
56+
.sideEffectFailsAfterGivenAttempts(attempts))
57+
.isGreaterThanOrEqualTo(attempts)
58+
}
59+
}

src/main/kotlin/dev/restate/sdktesting/tests/UserErrors.kt

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -40,39 +40,6 @@ class UserErrors {
4040
}
4141
}
4242

43-
// @DisplayName("Test terminal error of failing side effect with finite retry policy is
44-
// propagated")
45-
// @Test
46-
// @Execution(ExecutionMode.CONCURRENT)
47-
// fun failingSideEffectWithFiniteRetryPolicy(@InjectBlockingStub stub:
48-
// FailingServiceBlockingStub) {
49-
// val errorMessage = "some error message"
50-
//
51-
// assertThatThrownBy {
52-
// stub.failingSideEffectWithFiniteRetryPolicy(
53-
// ErrorMessage.newBuilder()
54-
// .setKey(UUID.randomUUID().toString())
55-
// .setErrorMessage(errorMessage)
56-
// .build())
57-
// }
58-
// .asInstanceOf(type(StatusRuntimeException::class.java))
59-
// .extracting(StatusRuntimeException::getStatus)
60-
// .extracting(Status::getDescription, InstanceOfAssertFactories.STRING)
61-
// .contains("failing side effect action")
62-
// }
63-
64-
// @DisplayName("Test propagate failure from sideEffect and internal invoke")
65-
// @Test
66-
// @Execution(ExecutionMode.CONCURRENT)
67-
// fun sideEffectFailurePropagation(@InjectClient ingressClient: Client) {
68-
// assertThat(
69-
// FailingClient.fromClient(ingressClient, UUID.randomUUID().toString())
70-
// .invokeExternalAndHandleFailure())
71-
// // We match on this regex because there might be additional parts of the string injected
72-
// // by runtime/sdk in the error message strings
73-
// .matches("begin.*external_call.*internal_call")
74-
// }
75-
7643
@DisplayName("Test calling method that fails terminally")
7744
@Test
7845
@Execution(ExecutionMode.CONCURRENT)
@@ -122,16 +89,6 @@ class UserErrors {
12289
.hasMessageContaining(errorMessage)
12390
}
12491

125-
@DisplayName("Test side effects are retried until they succeed")
126-
@Test
127-
@Execution(ExecutionMode.CONCURRENT)
128-
fun sideEffectWithEventualSuccess(@InjectClient ingressClient: Client) = runTest {
129-
assertThat(
130-
FailingClient.fromClient(ingressClient, UUID.randomUUID().toString())
131-
.failingCallWithEventualSuccess())
132-
.isEqualTo(SUCCESS_ATTEMPT)
133-
}
134-
13592
@DisplayName("Test invocations are retried until they succeed")
13693
@Test
13794
@Execution(ExecutionMode.CONCURRENT)

0 commit comments

Comments
 (0)