Skip to content

Commit d712b03

Browse files
committed
test(mysql2): cover orphan-query no-span path and drop idempotency test
The subscriber now only creates a span inside an enclosing active span, so drive operations through an enclosing span in the test helper and add an explicit orphan-query case. Remove the idempotency test since the internal subscribe function no longer guards against double-subscription.
1 parent 40ecf31 commit d712b03

1 file changed

Lines changed: 44 additions & 23 deletions

File tree

packages/server-utils/test/mysql2/mysql2-dc-subscriber.test.ts

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -97,30 +97,39 @@ function installTestAsyncContextStrategy(): void {
9797
});
9898
}
9999

100-
/** Drives a channel's `tracePromise` and captures the span bound by the subscriber. */
100+
/**
101+
* Drives a channel's `tracePromise` inside an enclosing span and captures the span bound by the
102+
* subscriber. The subscriber only creates a span when there is an enclosing active span, so the
103+
* helper always establishes one and returns its id for parenting assertions.
104+
*/
101105
async function traceOperation(
102106
channelName: string,
103107
data: Record<string, unknown>,
104108
outcome: { result?: unknown; error?: Error },
105-
): Promise<{ span: Span | undefined; childParentSpanId: string | undefined }> {
109+
): Promise<{ span: Span | undefined; childParentSpanId: string | undefined; enclosingSpanId: string | undefined }> {
106110
const channel = tracingChannel(channelName);
107111
let span: Span | undefined;
108112
let childParentSpanId: string | undefined;
113+
let enclosingSpanId: string | undefined;
109114

110-
const run = channel.tracePromise(async () => {
111-
span = getActiveSpan();
112-
startSpan({ name: 'child' }, child => {
113-
childParentSpanId = spanToJSON(child).parent_span_id;
114-
});
115-
if (outcome.error) {
116-
throw outcome.error;
117-
}
118-
return outcome.result;
119-
}, data);
115+
await startSpan({ name: 'enclosing' }, async enclosing => {
116+
enclosingSpanId = enclosing.spanContext().spanId;
117+
118+
const run = channel.tracePromise(async () => {
119+
span = getActiveSpan();
120+
startSpan({ name: 'child' }, child => {
121+
childParentSpanId = spanToJSON(child).parent_span_id;
122+
});
123+
if (outcome.error) {
124+
throw outcome.error;
125+
}
126+
return outcome.result;
127+
}, data);
120128

121-
await run.catch(() => undefined);
129+
await run.catch(() => undefined);
130+
});
122131

123-
return { span, childParentSpanId };
132+
return { span, childParentSpanId, enclosingSpanId };
124133
}
125134

126135
const factory = tracingChannel as MySQL2TracingChannelFactory;
@@ -153,6 +162,20 @@ describe('subscribeMysql2DiagnosticChannels', () => {
153162
vi.clearAllMocks();
154163
});
155164

165+
it('does not create a span when there is no enclosing active span', async () => {
166+
const channel = tracingChannel(MYSQL2_DC_CHANNEL_QUERY);
167+
let span: Span | undefined;
168+
169+
await channel.tracePromise(
170+
async () => {
171+
span = getActiveSpan();
172+
},
173+
{ query: 'SELECT 1' },
174+
);
175+
176+
expect(span).toBeUndefined();
177+
});
178+
156179
describe('query channel', () => {
157180
it('creates a db span with stable semconv attributes', async () => {
158181
const { span } = await traceOperation(
@@ -219,16 +242,14 @@ describe('subscribeMysql2DiagnosticChannels', () => {
219242
});
220243

221244
it('parents the mysql2 span to the surrounding span and parents children to it', async () => {
222-
let outerSpanId: string | undefined;
223-
let result: Awaited<ReturnType<typeof traceOperation>> | undefined;
224-
225-
await startSpan({ name: 'outer' }, async outer => {
226-
outerSpanId = outer.spanContext().spanId;
227-
result = await traceOperation(MYSQL2_DC_CHANNEL_QUERY, { query: 'SELECT 1' }, { result: [] });
228-
});
245+
const { span, childParentSpanId, enclosingSpanId } = await traceOperation(
246+
MYSQL2_DC_CHANNEL_QUERY,
247+
{ query: 'SELECT 1' },
248+
{ result: [] },
249+
);
229250

230-
expect(spanToJSON(result!.span!).parent_span_id).toBe(outerSpanId);
231-
expect(result!.childParentSpanId).toBe(result!.span!.spanContext().spanId);
251+
expect(spanToJSON(span!).parent_span_id).toBe(enclosingSpanId);
252+
expect(childParentSpanId).toBe(span!.spanContext().spanId);
232253
});
233254
});
234255

0 commit comments

Comments
 (0)