Skip to content

Commit 6866729

Browse files
move stack trace comparison logic into compareCompletion
1 parent 4c24aa2 commit 6866729

File tree

1 file changed

+104
-68
lines changed

1 file changed

+104
-68
lines changed

packages/test/src/test-workflows.ts

Lines changed: 104 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,51 @@ function compareCompletion(
163163
req: coresdk.workflow_completion.IWorkflowActivationCompletion,
164164
expected: coresdk.workflow_completion.IWorkflowActivationCompletion
165165
) {
166+
const stackTraces = extractFailureStackTraces(req, expected);
166167
t.deepEqual(
167168
coresdk.workflow_completion.WorkflowActivationCompletion.create(req).toJSON(),
168169
coresdk.workflow_completion.WorkflowActivationCompletion.create({
169170
...expected,
170171
runId: t.context.runId,
171172
}).toJSON()
172173
);
174+
175+
if (stackTraces) {
176+
for (const { actual, expected } of stackTraces) {
177+
compareStackTrace(t, actual, expected);
178+
}
179+
}
180+
}
181+
182+
// Extracts failure stack traces from completions if structure matches, leaving them unchanged if structure differs.
183+
// We leave them unchanged on structure differences as ava's `deepEqual` provides a better failure message.
184+
function extractFailureStackTraces(
185+
req: coresdk.workflow_completion.IWorkflowActivationCompletion,
186+
expected: coresdk.workflow_completion.IWorkflowActivationCompletion
187+
): { actual: string; expected: string }[] | undefined {
188+
const reqCommands = req.successful?.commands;
189+
const expectedCommands = expected.successful?.commands;
190+
if (!reqCommands || !expectedCommands || reqCommands.length !== expectedCommands.length) {
191+
return;
192+
}
193+
for (let commandIndex = 0; commandIndex < reqCommands.length; commandIndex++) {
194+
const reqStack = reqCommands[commandIndex].failWorkflowExecution?.failure?.stackTrace;
195+
const expectedStack = expectedCommands[commandIndex].failWorkflowExecution?.failure?.stackTrace;
196+
if (typeof reqStack !== typeof expectedStack) {
197+
return;
198+
}
199+
}
200+
const stackTraces: { actual: string; expected: string }[] = [];
201+
for (let commandIndex = 0; commandIndex < reqCommands.length; commandIndex++) {
202+
const reqStack = reqCommands[commandIndex].failWorkflowExecution?.failure?.stackTrace;
203+
const expectedStack = expectedCommands[commandIndex].failWorkflowExecution?.failure?.stackTrace;
204+
if (reqStack && expectedStack) {
205+
stackTraces.push({ actual: reqStack, expected: expectedStack });
206+
delete reqCommands[commandIndex].failWorkflowExecution?.failure?.stackTrace;
207+
delete expectedCommands[commandIndex].failWorkflowExecution?.failure?.stackTrace;
208+
}
209+
}
210+
return stackTraces;
173211
}
174212

175213
function makeSuccess(
@@ -307,12 +345,13 @@ function makeCompleteWorkflowExecution(result?: Payload): coresdk.workflow_comma
307345

308346
function makeFailWorkflowExecution(
309347
message: string,
348+
stackTrace?: string,
310349
type = 'Error',
311350
nonRetryable = true
312351
): coresdk.workflow_commands.IWorkflowCommand {
313352
return {
314353
failWorkflowExecution: {
315-
failure: { message, applicationFailureInfo: { type, nonRetryable }, source: 'TypeScriptSDK' },
354+
failure: { message, stackTrace, applicationFailureInfo: { type, nonRetryable }, source: 'TypeScriptSDK' },
316355
},
317356
};
318357
}
@@ -452,28 +491,22 @@ function cleanWorkflowQueryFailureStackTrace(
452491
return req;
453492
}
454493

455-
function removeWorkflowFailureStackTrace(
456-
req: coresdk.workflow_completion.IWorkflowActivationCompletion,
457-
commandIndex = 0
458-
) {
459-
const stackTrace = req.successful!.commands![commandIndex].failWorkflowExecution!.failure!.stackTrace!;
460-
delete req.successful!.commands![commandIndex].failWorkflowExecution!.failure!.stackTrace;
461-
return stackTrace;
462-
}
463-
464494
test('throwAsync', async (t) => {
465495
const { workflowType } = t.context;
466496
const req = cleanWorkflowFailureStackTrace(await activate(t, makeStartWorkflow(workflowType)));
467-
const actualStackTrace = removeWorkflowFailureStackTrace(req);
468-
compareCompletion(t, req, makeSuccess([makeFailWorkflowExecution('failure')]));
469-
compareStackTrace(
497+
compareCompletion(
470498
t,
471-
actualStackTrace,
472-
dedent`
499+
req,
500+
makeSuccess([
501+
makeFailWorkflowExecution(
502+
'failure',
503+
dedent`
473504
ApplicationFailure: failure
474505
at $CLASS.nonRetryable (common/src/failure.ts)
475506
at throwAsync (test/src/workflows/throw-async.ts)
476507
`
508+
),
509+
])
477510
);
478511
});
479512

@@ -773,25 +806,26 @@ test('interruptableWorkflow', async (t) => {
773806
const req = cleanWorkflowFailureStackTrace(
774807
await activate(t, await makeSignalWorkflow('interrupt', ['just because']))
775808
);
776-
const stackTrace = removeWorkflowFailureStackTrace(req);
777809
compareCompletion(
778810
t,
779811
req,
780812
makeSuccess(
781-
[makeFailWorkflowExecution('just because', 'Error', false)],
782-
[SdkFlags.ProcessWorkflowActivationJobsAsSingleBatch]
783-
)
784-
);
785-
compareStackTrace(
786-
t,
787-
stackTrace,
788-
// The stack trace is weird here and might confuse users, it might be a JS limitation
789-
// since the Error stack trace is generated in the constructor.
790-
dedent`
813+
[
814+
makeFailWorkflowExecution(
815+
'just because',
816+
// The stack trace is weird here and might confuse users, it might be a JS limitation
817+
// since the Error stack trace is generated in the constructor.
818+
dedent`
791819
ApplicationFailure: just because
792820
at $CLASS.retryable (common/src/failure.ts)
793821
at test/src/workflows/interrupt-signal.ts
794-
`
822+
`,
823+
'Error',
824+
false
825+
),
826+
],
827+
[SdkFlags.ProcessWorkflowActivationJobsAsSingleBatch]
828+
)
795829
);
796830
}
797831
});
@@ -804,23 +838,23 @@ test('failSignalWorkflow', async (t) => {
804838
}
805839
{
806840
const req = cleanWorkflowFailureStackTrace(await activate(t, await makeSignalWorkflow('fail', [])));
807-
const stackTrace = removeWorkflowFailureStackTrace(req);
808841
compareCompletion(
809842
t,
810843
req,
811844
makeSuccess(
812-
[makeFailWorkflowExecution('Signal failed', 'Error')],
813-
[SdkFlags.ProcessWorkflowActivationJobsAsSingleBatch]
814-
)
815-
);
816-
compareStackTrace(
817-
t,
818-
stackTrace,
819-
dedent`
845+
[
846+
makeFailWorkflowExecution(
847+
'Signal failed',
848+
dedent`
820849
ApplicationFailure: Signal failed
821850
at $CLASS.nonRetryable (common/src/failure.ts)
822851
at test/src/workflows/fail-signal.ts
823-
`
852+
`,
853+
'Error'
854+
),
855+
],
856+
[SdkFlags.ProcessWorkflowActivationJobsAsSingleBatch]
857+
)
824858
);
825859
}
826860
});
@@ -844,22 +878,22 @@ test('asyncFailSignalWorkflow', async (t) => {
844878
}
845879
{
846880
const req = cleanWorkflowFailureStackTrace(await activate(t, makeFireTimer(2)));
847-
const stackTrace = removeWorkflowFailureStackTrace(req);
848881
compareCompletion(
849882
t,
850883
req,
851884
makeSuccess(
852-
[makeFailWorkflowExecution('Signal failed', 'Error')],
853-
[SdkFlags.ProcessWorkflowActivationJobsAsSingleBatch]
854-
)
855-
);
856-
compareStackTrace(
857-
t,
858-
stackTrace,
859-
dedent`
885+
[
886+
makeFailWorkflowExecution(
887+
'Signal failed',
888+
dedent`
860889
ApplicationFailure: Signal failed
861890
at $CLASS.nonRetryable (common/src/failure.ts)
862-
at test/src/workflows/async-fail-signal.ts`
891+
at test/src/workflows/async-fail-signal.ts`,
892+
'Error'
893+
),
894+
],
895+
[SdkFlags.ProcessWorkflowActivationJobsAsSingleBatch]
896+
)
863897
);
864898
}
865899
});
@@ -1449,7 +1483,6 @@ test('nonCancellableInNonCancellable', async (t) => {
14491483
test('cancellationErrorIsPropagated', async (t) => {
14501484
const { workflowType, logs } = t.context;
14511485
const req = cleanWorkflowFailureStackTrace(await activate(t, makeStartWorkflow(workflowType)), 2);
1452-
const stackTrace = removeWorkflowFailureStackTrace(req, 2);
14531486
compareCompletion(
14541487
t,
14551488
req,
@@ -1460,25 +1493,21 @@ test('cancellationErrorIsPropagated', async (t) => {
14601493
failWorkflowExecution: {
14611494
failure: {
14621495
message: 'Cancellation scope cancelled',
1463-
canceledFailureInfo: {},
1464-
source: 'TypeScriptSDK',
1465-
},
1466-
},
1467-
},
1468-
])
1469-
);
1470-
compareStackTrace(
1471-
t,
1472-
stackTrace,
1473-
dedent`
1496+
stackTrace: dedent`
14741497
CancelledFailure: Cancellation scope cancelled
14751498
at CancellationScope.cancel (workflow/src/cancellation-scope.ts)
14761499
at test/src/workflows/cancellation-error-is-propagated.ts
14771500
at CancellationScope.runInContext (workflow/src/cancellation-scope.ts)
14781501
at CancellationScope.run (workflow/src/cancellation-scope.ts)
14791502
at $CLASS.cancellable (workflow/src/cancellation-scope.ts)
14801503
at cancellationErrorIsPropagated (test/src/workflows/cancellation-error-is-propagated.ts)
1481-
`
1504+
`,
1505+
canceledFailureInfo: {},
1506+
source: 'TypeScriptSDK',
1507+
},
1508+
},
1509+
},
1510+
])
14821511
);
14831512
t.deepEqual(logs, []);
14841513
});
@@ -1664,9 +1693,13 @@ test('resolve activity with failure - http', async (t) => {
16641693
},
16651694
})
16661695
);
1667-
const stackTrace = removeWorkflowFailureStackTrace(completion);
1668-
compareCompletion(t, completion, makeSuccess([makeFailWorkflowExecution('Connection timeout', 'MockError')]));
1669-
compareStackTrace(t, stackTrace, 'ApplicationFailure: Connection timeout');
1696+
compareCompletion(
1697+
t,
1698+
completion,
1699+
makeSuccess([
1700+
makeFailWorkflowExecution('Connection timeout', 'ApplicationFailure: Connection timeout', 'MockError'),
1701+
])
1702+
);
16701703
}
16711704
});
16721705

@@ -1877,16 +1910,19 @@ test('tryToContinueAfterCompletion', async (t) => {
18771910
const { workflowType } = t.context;
18781911
{
18791912
const completion = cleanWorkflowFailureStackTrace(await activate(t, makeStartWorkflow(workflowType)));
1880-
const stackTrace = removeWorkflowFailureStackTrace(completion);
1881-
compareCompletion(t, completion, makeSuccess([makeFailWorkflowExecution('fail before continue')]));
1882-
compareStackTrace(
1913+
compareCompletion(
18831914
t,
1884-
stackTrace,
1885-
dedent`
1915+
completion,
1916+
makeSuccess([
1917+
makeFailWorkflowExecution(
1918+
'fail before continue',
1919+
dedent`
18861920
ApplicationFailure: fail before continue
18871921
at $CLASS.nonRetryable (common/src/failure.ts)
18881922
at tryToContinueAfterCompletion (test/src/workflows/try-to-continue-after-completion.ts)
18891923
`
1924+
),
1925+
])
18901926
);
18911927
}
18921928
});

0 commit comments

Comments
 (0)