Skip to content

Commit 814a1e3

Browse files
committed
better tests
1 parent 1427b8b commit 814a1e3

File tree

2 files changed

+92
-58
lines changed

2 files changed

+92
-58
lines changed

packages/deno/src/sdk.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,8 @@ export function init(options: DenoOptions = {}): Client {
100100

101101
const client = initAndBind(DenoClient, clientOptions);
102102

103-
/**
104-
* The Deno SDK is not OpenTelemetry native, however, we set up some OpenTelemetry compatibility
105-
* via a custom trace provider.
106-
* This ensures that any spans emitted via `@opentelemetry/api` will be captured by Sentry.
107-
* HOWEVER, big caveat: This does not handle custom context handling, it will always work off the current scope.
108-
* This should be good enough for many, but not all integrations.
109-
*/
103+
// Set up OpenTelemetry compatibility to capture spans from libraries using @opentelemetry/api
104+
// Note: This is separate from Deno's native OTEL support and doesn't capture auto-instrumented spans
110105
if (!options.skipOpenTelemetrySetup) {
111106
setupOpenTelemetryTracer();
112107
}
Lines changed: 90 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,7 @@
11
import { assertEquals } from 'https://deno.land/[email protected]/assert/mod.ts';
22
import { context, propagation, trace } from 'npm:@opentelemetry/api@1';
33
import type { DenoClient } from '../build/esm/index.js';
4-
import {
5-
flush,
6-
getCurrentScope,
7-
getGlobalScope,
8-
getIsolationScope,
9-
init,
10-
vercelAIIntegration,
11-
} from '../build/esm/index.js';
12-
13-
function delay(time: number): Promise<void> {
14-
return new Promise(resolve => {
15-
setTimeout(resolve, time);
16-
});
17-
}
4+
import { getCurrentScope, getGlobalScope, getIsolationScope, init, startSpan } from '../build/esm/index.js';
185

196
function resetGlobals(): void {
207
getCurrentScope().clear();
@@ -35,72 +22,124 @@ function resetSdk(): void {
3522
cleanupOtel();
3623
}
3724

38-
Deno.test('opentelemetry: should capture spans emitted via @opentelemetry/api', async _t => {
25+
Deno.test('should not capture spans emitted via @opentelemetry/api when skipOpenTelemetrySetup is true', async () => {
3926
resetSdk();
40-
const events: any[] = [];
27+
const transactionEvents: any[] = [];
4128

42-
init({
29+
const client = init({
4330
dsn: 'https://username@domain/123',
44-
debug: true,
4531
tracesSampleRate: 1,
46-
skipOpenTelemetrySetup: false,
47-
beforeSendTransaction(event) {
48-
events.push(event);
32+
skipOpenTelemetrySetup: true,
33+
beforeSendTransaction: event => {
34+
transactionEvents.push(event);
4935
return null;
5036
},
51-
});
37+
}) as DenoClient;
5238

53-
const tracer = trace.getTracer('test-tracer');
54-
const span = tracer.startSpan('test span');
55-
span.setAttribute('test.attribute', 'test value');
39+
const tracer = trace.getTracer('test');
40+
const span = tracer.startSpan('test');
5641
span.end();
5742

58-
await delay(200);
59-
await flush(1000);
43+
await client.flush();
44+
45+
tracer.startActiveSpan('test 2', { attributes: { 'test.attribute': 'test' } }, span2 => {
46+
const span = tracer.startSpan('test 3', { attributes: { 'test.attribute': 'test2' } });
47+
span.end();
48+
span2.end();
49+
});
6050

61-
assertEquals(events.length, 1);
62-
const transactionEvent = events[0];
51+
await client.flush();
6352

64-
assertEquals(transactionEvent?.transaction, 'test span');
65-
assertEquals(transactionEvent?.contexts?.trace?.data?.['sentry.deno_tracer'], true);
66-
assertEquals(transactionEvent?.contexts?.trace?.data?.['test.attribute'], 'test value');
53+
assertEquals(transactionEvents.length, 0);
6754
});
6855

69-
Deno.test('opentelemetry: should not capture spans when skipOpenTelemetrySetup is true', async () => {
56+
Deno.test('should capture spans emitted via @opentelemetry/api', async () => {
7057
resetSdk();
71-
const events: any[] = [];
58+
const transactionEvents: any[] = [];
7259

73-
init({
60+
const client = init({
7461
dsn: 'https://username@domain/123',
75-
debug: true,
7662
tracesSampleRate: 1,
77-
skipOpenTelemetrySetup: true,
78-
beforeSendTransaction(event) {
79-
events.push(event);
63+
beforeSendTransaction: event => {
64+
transactionEvents.push(event);
8065
return null;
8166
},
82-
});
67+
}) as DenoClient;
8368

84-
const tracer = trace.getTracer('test-tracer');
85-
const span = tracer.startSpan('test span');
69+
const tracer = trace.getTracer('test');
70+
const span = tracer.startSpan('test');
8671
span.end();
8772

88-
await delay(200);
89-
await flush(1000);
73+
await client.flush();
9074

91-
assertEquals(events.length, 0);
75+
tracer.startActiveSpan('test 2', { attributes: { 'test.attribute': 'test' } }, span2 => {
76+
const span = tracer.startSpan('test 3', { attributes: { 'test.attribute': 'test2' } });
77+
span.end();
78+
span2.end();
79+
});
80+
81+
await client.flush();
82+
83+
assertEquals(transactionEvents.length, 2);
84+
const [transactionEvent, transactionEvent2] = transactionEvents;
85+
86+
assertEquals(transactionEvent?.spans?.length, 0);
87+
assertEquals(transactionEvent?.transaction, 'test');
88+
assertEquals(transactionEvent?.contexts?.trace?.data?.['sentry.deno_tracer'], true);
89+
assertEquals(transactionEvent?.contexts?.trace?.data?.['sentry.origin'], 'manual');
90+
assertEquals(transactionEvent?.contexts?.trace?.data?.['sentry.sample_rate'], 1);
91+
assertEquals(transactionEvent?.contexts?.trace?.data?.['sentry.source'], 'custom');
92+
93+
assertEquals(transactionEvent2?.spans?.length, 1);
94+
assertEquals(transactionEvent2?.transaction, 'test 2');
95+
assertEquals(transactionEvent2?.contexts?.trace?.data?.['sentry.deno_tracer'], true);
96+
assertEquals(transactionEvent2?.contexts?.trace?.data?.['sentry.origin'], 'manual');
97+
assertEquals(transactionEvent2?.contexts?.trace?.data?.['sentry.sample_rate'], 1);
98+
assertEquals(transactionEvent2?.contexts?.trace?.data?.['sentry.source'], 'custom');
99+
assertEquals(transactionEvent2?.contexts?.trace?.data?.['test.attribute'], 'test');
100+
101+
const childSpan = transactionEvent2?.spans?.[0];
102+
assertEquals(childSpan?.description, 'test 3');
103+
assertEquals(childSpan?.data?.['sentry.deno_tracer'], true);
104+
assertEquals(childSpan?.data?.['sentry.origin'], 'manual');
105+
assertEquals(childSpan?.data?.['test.attribute'], 'test2');
92106
});
93107

94-
Deno.test('opentelemetry: vercelAI integration can be added', () => {
108+
Deno.test('opentelemetry spans should interop with Sentry spans', async () => {
95109
resetSdk();
110+
const transactionEvents: any[] = [];
111+
96112
const client = init({
97113
dsn: 'https://username@domain/123',
98-
debug: true,
99114
tracesSampleRate: 1,
100-
integrations: [vercelAIIntegration()],
115+
beforeSendTransaction: event => {
116+
transactionEvents.push(event);
117+
return null;
118+
},
101119
}) as DenoClient;
102120

103-
// Just verify the integration can be added without errors
104-
const integration = client.getIntegrationByName('VercelAI');
105-
assertEquals(integration?.name, 'VercelAI');
121+
const tracer = trace.getTracer('test');
122+
123+
startSpan({ name: 'sentry span' }, () => {
124+
const span = tracer.startSpan('otel span');
125+
span.end();
126+
});
127+
128+
await client.flush();
129+
130+
assertEquals(transactionEvents.length, 1);
131+
const [transactionEvent] = transactionEvents;
132+
133+
assertEquals(transactionEvent?.spans?.length, 1);
134+
assertEquals(transactionEvent?.transaction, 'sentry span');
135+
assertEquals(transactionEvent?.contexts?.trace?.data?.['sentry.origin'], 'manual');
136+
assertEquals(transactionEvent?.contexts?.trace?.data?.['sentry.sample_rate'], 1);
137+
assertEquals(transactionEvent?.contexts?.trace?.data?.['sentry.source'], 'custom');
138+
// Note: Sentry-created spans don't have the deno_tracer marker
139+
assertEquals(transactionEvent?.contexts?.trace?.data?.['sentry.deno_tracer'], undefined);
140+
141+
const otelSpan = transactionEvent?.spans?.[0];
142+
assertEquals(otelSpan?.description, 'otel span');
143+
assertEquals(otelSpan?.data?.['sentry.deno_tracer'], true);
144+
assertEquals(otelSpan?.data?.['sentry.origin'], 'manual');
106145
});

0 commit comments

Comments
 (0)