Skip to content

Commit b534db4

Browse files
authored
test: Introduce .unordered in node-integration-tests (#21697)
closes #21626 Inspired by the Cloudflare and Bun integration tests runner: `.unordered()`
1 parent 9af2819 commit b534db4

2 files changed

Lines changed: 71 additions & 44 deletions

File tree

dev-packages/node-integration-tests/suites/tracing/apollo-graphql/test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ describe('GraphQL/Apollo Tests', () => {
3737
await createTestRunner()
3838
.expect({ transaction: EXPECTED_START_SERVER_TRANSACTION })
3939
.expect({ transaction: EXPECTED_TRANSACTION })
40+
.unordered()
4041
.start()
4142
.completed();
4243
});
@@ -72,6 +73,7 @@ describe('GraphQL/Apollo Tests', () => {
7273
await createTestRunner()
7374
.expect({ transaction: EXPECTED_START_SERVER_TRANSACTION })
7475
.expect({ transaction: EXPECTED_TRANSACTION })
76+
.unordered()
7577
.start()
7678
.completed();
7779
});
@@ -107,6 +109,7 @@ describe('GraphQL/Apollo Tests', () => {
107109
await createTestRunner()
108110
.expect({ transaction: EXPECTED_START_SERVER_TRANSACTION })
109111
.expect({ transaction: EXPECTED_TRANSACTION })
112+
.unordered()
110113
.start()
111114
.completed();
112115
});
@@ -142,6 +145,7 @@ describe('GraphQL/Apollo Tests', () => {
142145
await createTestRunner()
143146
.expect({ transaction: EXPECTED_START_SERVER_TRANSACTION })
144147
.expect({ transaction: EXPECTED_TRANSACTION })
148+
.unordered()
145149
.start()
146150
.completed();
147151
});

dev-packages/node-integration-tests/utils/runner/createRunner.ts

Lines changed: 67 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ export function createRunner(...paths: string[]) {
131131
const flags: string[] = [];
132132
// By default, we ignore session & sessions
133133
const ignored: Set<EnvelopeItemType> = new Set(['session', 'sessions', 'client_report']);
134+
let unordered = false;
134135
let withEnv: Record<string, string> = {};
135136
let withSentryServer = false;
136137
let dockerOptions: DockerOptions | undefined;
@@ -211,6 +212,10 @@ export function createRunner(...paths: string[]) {
211212
}
212213
return this;
213214
},
215+
unordered: function () {
216+
unordered = true;
217+
return this;
218+
},
214219
withDockerCompose: function (options: DockerOptions) {
215220
dockerOptions = options;
216221
return this;
@@ -284,58 +289,50 @@ export function createRunner(...paths: string[]) {
284289
return;
285290
}
286291

287-
const expected = expectedEnvelopes.shift();
292+
if (unordered) {
293+
const matchIndex = expectedEnvelopes.findIndex(candidate => {
294+
const candidateType = Object.keys(candidate)[0];
295+
if (candidateType !== envelopeItemType) {
296+
return false;
297+
}
298+
try {
299+
assertExpectedEnvelope(candidate, item);
300+
return true;
301+
} catch {
302+
return false;
303+
}
304+
});
288305

289-
// Catch any error or failed assertions and pass them to done to end the test quickly
290-
try {
291-
if (!expected) {
306+
if (matchIndex < 0) {
292307
return;
293308
}
294309

295-
const expectedType = Object.keys(expected)[0];
310+
expectedEnvelopes.splice(matchIndex, 1);
311+
expectCallbackCalled();
312+
} else {
313+
const expected = expectedEnvelopes.shift();
296314

297-
if (expectedType !== envelopeItemType) {
298-
throw new Error(
299-
`Expected envelope item type '${expectedType}' but got '${envelopeItemType}'. \nItem: ${JSON.stringify(
300-
item,
301-
)}`,
302-
);
303-
}
315+
// Catch any error or failed assertions and pass them to done to end the test quickly
316+
try {
317+
if (!expected) {
318+
return;
319+
}
304320

305-
if ('event' in expected) {
306-
expectErrorEvent(item[1] as Event, expected.event);
307-
expectCallbackCalled();
308-
} else if ('transaction' in expected) {
309-
expectTransactionEvent(item[1] as TransactionEvent, expected.transaction);
310-
expectCallbackCalled();
311-
} else if ('session' in expected) {
312-
expectSessionEvent(item[1] as SerializedSession, expected.session);
313-
expectCallbackCalled();
314-
} else if ('sessions' in expected) {
315-
expectSessionsEvent(item[1] as SessionAggregates, expected.sessions);
316-
expectCallbackCalled();
317-
} else if ('check_in' in expected) {
318-
expectCheckInEvent(item[1] as SerializedCheckIn, expected.check_in);
319-
expectCallbackCalled();
320-
} else if ('client_report' in expected) {
321-
expectClientReport(item[1] as ClientReport, expected.client_report);
322-
expectCallbackCalled();
323-
} else if ('log' in expected) {
324-
expectLog(item[1] as SerializedLogContainer, expected.log);
325-
expectCallbackCalled();
326-
} else if ('trace_metric' in expected) {
327-
expectMetric(item[1] as SerializedMetricContainer, expected.trace_metric);
328-
expectCallbackCalled();
329-
} else if ('span' in expected) {
330-
expectSpanContainer(item[1] as SerializedStreamedSpanContainer, expected.span);
321+
const expectedType = Object.keys(expected)[0];
322+
323+
if (expectedType !== envelopeItemType) {
324+
throw new Error(
325+
`Expected envelope item type '${expectedType}' but got '${envelopeItemType}'. \nItem: ${JSON.stringify(
326+
item,
327+
)}`,
328+
);
329+
}
330+
331+
assertExpectedEnvelope(expected, item);
331332
expectCallbackCalled();
332-
} else {
333-
throw new Error(
334-
`Unhandled expected envelope item type: ${JSON.stringify(expected)}\nItem: ${JSON.stringify(item)}`,
335-
);
333+
} catch (e) {
334+
complete(e as Error);
336335
}
337-
} catch (e) {
338-
complete(e as Error);
339336
}
340337
}
341338
}
@@ -641,6 +638,32 @@ function expectErrorEvent(item: Event, expected: ExpectedEvent): void {
641638
}
642639
}
643640

641+
function assertExpectedEnvelope(expected: Expected, item: Envelope[1][number]): void {
642+
if ('event' in expected) {
643+
expectErrorEvent(item[1] as Event, expected.event);
644+
} else if ('transaction' in expected) {
645+
expectTransactionEvent(item[1] as TransactionEvent, expected.transaction);
646+
} else if ('session' in expected) {
647+
expectSessionEvent(item[1] as SerializedSession, expected.session);
648+
} else if ('sessions' in expected) {
649+
expectSessionsEvent(item[1] as SessionAggregates, expected.sessions);
650+
} else if ('check_in' in expected) {
651+
expectCheckInEvent(item[1] as SerializedCheckIn, expected.check_in);
652+
} else if ('client_report' in expected) {
653+
expectClientReport(item[1] as ClientReport, expected.client_report);
654+
} else if ('log' in expected) {
655+
expectLog(item[1] as SerializedLogContainer, expected.log);
656+
} else if ('trace_metric' in expected) {
657+
expectMetric(item[1] as SerializedMetricContainer, expected.trace_metric);
658+
} else if ('span' in expected) {
659+
expectSpanContainer(item[1] as SerializedStreamedSpanContainer, expected.span);
660+
} else {
661+
throw new Error(
662+
`Unhandled expected envelope item type: ${JSON.stringify(expected)}\nItem: ${JSON.stringify(item)}`,
663+
);
664+
}
665+
}
666+
644667
function expectTransactionEvent(item: TransactionEvent, expected: ExpectedTransaction): void {
645668
if (typeof expected === 'function') {
646669
expected(item);

0 commit comments

Comments
 (0)