27
27
import java .util .Map ;
28
28
import java .util .concurrent .ConcurrentHashMap ;
29
29
import org .junit .Assert ;
30
- import org .junit .Assume ;
31
30
import org .junit .Rule ;
32
31
import org .junit .Test ;
33
32
34
33
public class OperationFailMetricTest {
34
+ private static Map <String , Integer > invocationCount = new ConcurrentHashMap <>();
35
+
35
36
private final TestStatsReporter reporter = new TestStatsReporter ();
36
37
37
38
@ Rule
@@ -43,7 +44,6 @@ public class OperationFailMetricTest {
43
44
new RootScopeBuilder ()
44
45
.reporter (reporter )
45
46
.reportEvery (com .uber .m3 .util .Duration .ofMillis (10 )))
46
- .setUseExternalService (false )
47
47
.build ();
48
48
49
49
private ImmutableMap .Builder <String , String > getBaseTags () {
@@ -81,6 +81,7 @@ public void failOperationMetrics() {
81
81
82
82
WorkflowFailedException workflowException =
83
83
Assert .assertThrows (WorkflowFailedException .class , () -> workflowStub .execute ("fail" ));
84
+ assertNoRetries ("fail" );
84
85
ApplicationFailure applicationFailure =
85
86
assertNexusOperationFailure (ApplicationFailure .class , workflowException );
86
87
Assert .assertEquals ("intentional failure" , applicationFailure .getOriginalMessage ());
@@ -107,6 +108,7 @@ public void failOperationApplicationErrorMetrics() {
107
108
108
109
WorkflowFailedException workflowException =
109
110
Assert .assertThrows (WorkflowFailedException .class , () -> workflowStub .execute ("fail-app" ));
111
+ assertNoRetries ("fail-app" );
110
112
ApplicationFailure applicationFailure =
111
113
assertNexusOperationFailure (ApplicationFailure .class , workflowException );
112
114
Assert .assertEquals ("intentional failure" , applicationFailure .getOriginalMessage ());
@@ -135,8 +137,10 @@ public void failHandlerBadRequestMetrics() {
135
137
WorkflowFailedException workflowException =
136
138
Assert .assertThrows (
137
139
WorkflowFailedException .class , () -> workflowStub .execute ("handlererror" ));
140
+ assertNoRetries ("handlererror" );
138
141
HandlerException handlerException =
139
142
assertNexusOperationFailure (HandlerException .class , workflowException );
143
+ Assert .assertEquals (HandlerException .ErrorType .BAD_REQUEST , handlerException .getErrorType ());
140
144
Assert .assertTrue (handlerException .getCause () instanceof ApplicationFailure );
141
145
ApplicationFailure applicationFailure = (ApplicationFailure ) handlerException .getCause ();
142
146
Assert .assertEquals ("handlererror" , applicationFailure .getOriginalMessage ());
@@ -165,8 +169,10 @@ public void failHandlerAppBadRequestMetrics() {
165
169
WorkflowFailedException workflowException =
166
170
Assert .assertThrows (
167
171
WorkflowFailedException .class , () -> workflowStub .execute ("handlererror-app" ));
172
+ assertNoRetries ("handlererror-app" );
168
173
HandlerException handlerException =
169
174
assertNexusOperationFailure (HandlerException .class , workflowException );
175
+ Assert .assertEquals (HandlerException .ErrorType .BAD_REQUEST , handlerException .getErrorType ());
170
176
Assert .assertTrue (handlerException .getCause () instanceof ApplicationFailure );
171
177
ApplicationFailure applicationFailure = (ApplicationFailure ) handlerException .getCause ();
172
178
Assert .assertEquals ("intentional failure" , applicationFailure .getOriginalMessage ());
@@ -192,19 +198,24 @@ public void failHandlerAppBadRequestMetrics() {
192
198
193
199
@ Test
194
200
public void failHandlerAlreadyStartedMetrics () {
195
- Assume .assumeFalse ("skipping" , true );
196
201
TestWorkflow1 workflowStub =
197
202
testWorkflowRule .newWorkflowStubTimeoutOptions (TestWorkflow1 .class );
198
203
WorkflowFailedException workflowException =
199
204
Assert .assertThrows (
200
205
WorkflowFailedException .class , () -> workflowStub .execute ("already-started" ));
201
- ApplicationFailure applicationFailure =
202
- assertNexusOperationFailure (ApplicationFailure .class , workflowException );
206
+ assertNoRetries ("already-started" );
207
+ HandlerException handlerException =
208
+ assertNexusOperationFailure (HandlerException .class , workflowException );
209
+ Assert .assertEquals (HandlerException .ErrorType .BAD_REQUEST , handlerException .getErrorType ());
210
+ Assert .assertTrue (handlerException .getCause () instanceof ApplicationFailure );
211
+ ApplicationFailure applicationFailure = (ApplicationFailure ) handlerException .getCause ();
203
212
Assert .assertEquals (
204
213
"io.temporal.client.WorkflowExecutionAlreadyStarted" , applicationFailure .getType ());
205
214
206
215
Map <String , String > execFailedTags =
207
- getOperationTags ().put (MetricsTag .TASK_FAILURE_TYPE , "operation_failed" ).buildKeepingLast ();
216
+ getOperationTags ()
217
+ .put (MetricsTag .TASK_FAILURE_TYPE , "handler_error_BAD_REQUEST" )
218
+ .buildKeepingLast ();
208
219
Eventually .assertEventually (
209
220
Duration .ofSeconds (3 ),
210
221
() -> {
@@ -224,6 +235,7 @@ public void failHandlerRetryableApplicationFailureMetrics() {
224
235
testWorkflowRule .newWorkflowStubTimeoutOptions (TestWorkflow1 .class );
225
236
Assert .assertThrows (
226
237
WorkflowFailedException .class , () -> workflowStub .execute ("retryable-application-failure" ));
238
+ Assert .assertTrue (invocationCount .get ("retryable-application-failure" ) > 1 );
227
239
228
240
Map <String , String > execFailedTags =
229
241
getOperationTags ()
@@ -253,12 +265,16 @@ public void failHandlerNonRetryableApplicationFailureMetrics() {
253
265
() -> workflowStub .execute ("non-retryable-application-failure" ));
254
266
HandlerException handlerFailure =
255
267
assertNexusOperationFailure (HandlerException .class , workflowException );
268
+ assertNoRetries ("non-retryable-application-failure" );
269
+
256
270
Assert .assertTrue (handlerFailure .getMessage ().contains ("intentional failure" ));
257
- Assert .assertEquals (HandlerException .ErrorType .BAD_REQUEST , handlerFailure .getErrorType ());
271
+ Assert .assertEquals (HandlerException .ErrorType .INTERNAL , handlerFailure .getErrorType ());
272
+ Assert .assertEquals (
273
+ HandlerException .RetryBehavior .NON_RETRYABLE , handlerFailure .getRetryBehavior ());
258
274
259
275
Map <String , String > execFailedTags =
260
276
getOperationTags ()
261
- .put (MetricsTag .TASK_FAILURE_TYPE , "handler_error_BAD_REQUEST " )
277
+ .put (MetricsTag .TASK_FAILURE_TYPE , "handler_error_INTERNAL " )
262
278
.buildKeepingLast ();
263
279
Eventually .assertEventually (
264
280
Duration .ofSeconds (3 ),
@@ -298,6 +314,7 @@ public void failHandlerErrorMetrics() {
298
314
testWorkflowRule .newWorkflowStubTimeoutOptions (TestWorkflow1 .class );
299
315
WorkflowFailedException workflowException =
300
316
Assert .assertThrows (WorkflowFailedException .class , () -> workflowStub .execute ("error" ));
317
+ Assert .assertTrue (invocationCount .get ("error" ) > 1 );
301
318
302
319
Map <String , String > execFailedTags =
303
320
getOperationTags ()
@@ -324,6 +341,13 @@ public void handlerErrorNonRetryableMetrics() {
324
341
WorkflowFailedException workflowException =
325
342
Assert .assertThrows (
326
343
WorkflowFailedException .class , () -> workflowStub .execute ("handlererror-nonretryable" ));
344
+ assertNoRetries ("handlererror-nonretryable" );
345
+ HandlerException handlerFailure =
346
+ assertNexusOperationFailure (HandlerException .class , workflowException );
347
+ Assert .assertTrue (handlerFailure .getMessage ().contains ("intentional failure" ));
348
+ Assert .assertEquals (HandlerException .ErrorType .INTERNAL , handlerFailure .getErrorType ());
349
+ Assert .assertEquals (
350
+ HandlerException .RetryBehavior .NON_RETRYABLE , handlerFailure .getRetryBehavior ());
327
351
328
352
Map <String , String > execFailedTags =
329
353
getOperationTags ()
@@ -342,6 +366,10 @@ public void handlerErrorNonRetryableMetrics() {
342
366
});
343
367
}
344
368
369
+ private void assertNoRetries (String testCase ) {
370
+ Assert .assertEquals (new Integer (1 ), invocationCount .get (testCase ));
371
+ }
372
+
345
373
public static class TestNexus implements TestWorkflow1 {
346
374
@ Override
347
375
public String execute (String operation ) {
@@ -360,17 +388,13 @@ public String execute(String operation) {
360
388
361
389
@ ServiceImpl (service = TestNexusServices .TestNexusService1 .class )
362
390
public class TestNexusServiceImpl {
363
- Map <String , Integer > invocationCount = new ConcurrentHashMap <>();
364
-
365
391
@ OperationImpl
366
392
public OperationHandler <String , String > operation () {
367
393
// Implemented inline
368
394
return OperationHandler .sync (
369
395
(ctx , details , operation ) -> {
370
- invocationCount .put (
371
- details .getRequestId (),
372
- invocationCount .getOrDefault (details .getRequestId (), 0 ) + 1 );
373
- if (invocationCount .get (details .getRequestId ()) > 1 ) {
396
+ invocationCount .put (operation , invocationCount .getOrDefault (operation , 0 ) + 1 );
397
+ if (invocationCount .get (operation ) > 1 ) {
374
398
throw OperationException .failure (new RuntimeException ("exceeded invocation count" ));
375
399
}
376
400
switch (operation ) {
0 commit comments