From 9b62a7399917313d61de47514225f20c69c9f176 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 2 Nov 2022 12:42:10 +0100 Subject: [PATCH 1/3] feat(otel): Add inject functionality to SentryPropagator --- .../test/propagator.test.ts | 181 ++++++++++++++++++ 1 file changed, 181 insertions(+) diff --git a/packages/opentelemetry-node/test/propagator.test.ts b/packages/opentelemetry-node/test/propagator.test.ts index fd8369ea9fd0..a91f8e1982de 100644 --- a/packages/opentelemetry-node/test/propagator.test.ts +++ b/packages/opentelemetry-node/test/propagator.test.ts @@ -204,4 +204,185 @@ describe('SentryPropagator', () => { }); }); }); + + describe('inject', () => { + describe('sentry-trace', () => { + it.each([ + [ + 'should set sentry-trace header when sampled', + { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.SAMPLED, + }, + 'd4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1', + ], + [ + 'should set sentry-trace header when not sampled', + { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.NONE, + }, + 'd4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-0', + ], + [ + 'should NOT set sentry-trace header when traceId is empty', + { + traceId: '', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.SAMPLED, + }, + undefined, + ], + [ + 'should NOT set sentry-trace header when spanId is empty', + { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '', + traceFlags: TraceFlags.NONE, + }, + undefined, + ], + ])('%s', (_name, spanContext, expected) => { + const context = trace.setSpanContext(ROOT_CONTEXT, spanContext); + propagator.inject(context, carrier, defaultTextMapSetter); + expect(carrier[SENTRY_TRACE_HEADER]).toBe(expected); + }); + + it('should NOT set sentry-trace header if instrumentation is supressed', () => { + const spanContext = { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.SAMPLED, + }; + const context = suppressTracing(trace.setSpanContext(ROOT_CONTEXT, spanContext)); + propagator.inject(context, carrier, defaultTextMapSetter); + expect(carrier[SENTRY_TRACE_HEADER]).toBe(undefined); + }); + }); + + describe('baggage', () => { + const client = { + getOptions: () => ({ + environment: 'production', + release: '1.0.0', + }), + getDsn: () => ({ + publicKey: 'abc', + }), + }; + // @ts-ignore Use mock client for unit tests + const hub: Hub = new Hub(client); + makeMain(hub); + + afterEach(() => { + SENTRY_SPAN_PROCESSOR_MAP.clear(); + }); + + enum PerfType { + Transaction = 'transaction', + Span = 'span', + } + + function createTransactionAndMaybeSpan(type: PerfType, transactionContext: TransactionContext) { + const transaction = new Transaction(transactionContext, hub); + SENTRY_SPAN_PROCESSOR_MAP.set(transaction.spanId, transaction); + if (type === PerfType.Span) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { spanId, ...ctx } = transactionContext; + const span = transaction.startChild({ ...ctx, description: transaction.name }); + SENTRY_SPAN_PROCESSOR_MAP.set(span.spanId, span); + } + } + + describe.each([PerfType.Transaction, PerfType.Span])('with active %s', type => { + it.each([ + [ + 'should set baggage header when sampled', + { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.SAMPLED, + }, + { + name: 'sampled-transaction', + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + sampled: true, + }, + 'sentry-environment=production,sentry-release=1.0.0,sentry-transaction=sampled-transaction,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b', + ], + [ + 'should NOT set baggage header when not sampled', + { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.NONE, + }, + { + name: 'not-sampled-transaction', + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + sampled: false, + }, + 'sentry-environment=production,sentry-release=1.0.0,sentry-transaction=not-sampled-transaction,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b', + ], + [ + 'should NOT set baggage header when traceId is empty', + { + traceId: '', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.SAMPLED, + }, + { + name: 'empty-traceId-transaction', + traceId: '', + spanId: '6e0c63257de34c92', + sampled: true, + }, + undefined, + ], + [ + 'should NOT set baggage header when spanId is empty', + { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '', + traceFlags: TraceFlags.SAMPLED, + }, + { + name: 'empty-spanId-transaction', + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '', + sampled: true, + }, + undefined, + ], + ])('%s', (_name, spanContext, transactionContext, expected) => { + createTransactionAndMaybeSpan(type, transactionContext); + const context = trace.setSpanContext(ROOT_CONTEXT, spanContext); + propagator.inject(context, carrier, defaultTextMapSetter); + expect(carrier[SENTRY_BAGGAGE_HEADER]).toBe(expected); + }); + + it('should NOT set sentry-trace header if instrumentation is supressed', () => { + const spanContext = { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.SAMPLED, + }; + const transactionContext = { + name: 'sampled-transaction', + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + sampled: true, + }; + createTransactionAndMaybeSpan(type, transactionContext); + const context = suppressTracing(trace.setSpanContext(ROOT_CONTEXT, spanContext)); + propagator.inject(context, carrier, defaultTextMapSetter); + expect(carrier[SENTRY_TRACE_HEADER]).toBe(undefined); + }); + }); + }); + }); }); From 0d695fed4bf77cf2749d6955c386bb89a012edf5 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 2 Nov 2022 14:55:35 +0100 Subject: [PATCH 2/3] spelling mistake :sadcat: --- .../test/propagator.test.ts | 181 ------------------ 1 file changed, 181 deletions(-) diff --git a/packages/opentelemetry-node/test/propagator.test.ts b/packages/opentelemetry-node/test/propagator.test.ts index a91f8e1982de..fd8369ea9fd0 100644 --- a/packages/opentelemetry-node/test/propagator.test.ts +++ b/packages/opentelemetry-node/test/propagator.test.ts @@ -204,185 +204,4 @@ describe('SentryPropagator', () => { }); }); }); - - describe('inject', () => { - describe('sentry-trace', () => { - it.each([ - [ - 'should set sentry-trace header when sampled', - { - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '6e0c63257de34c92', - traceFlags: TraceFlags.SAMPLED, - }, - 'd4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1', - ], - [ - 'should set sentry-trace header when not sampled', - { - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '6e0c63257de34c92', - traceFlags: TraceFlags.NONE, - }, - 'd4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-0', - ], - [ - 'should NOT set sentry-trace header when traceId is empty', - { - traceId: '', - spanId: '6e0c63257de34c92', - traceFlags: TraceFlags.SAMPLED, - }, - undefined, - ], - [ - 'should NOT set sentry-trace header when spanId is empty', - { - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '', - traceFlags: TraceFlags.NONE, - }, - undefined, - ], - ])('%s', (_name, spanContext, expected) => { - const context = trace.setSpanContext(ROOT_CONTEXT, spanContext); - propagator.inject(context, carrier, defaultTextMapSetter); - expect(carrier[SENTRY_TRACE_HEADER]).toBe(expected); - }); - - it('should NOT set sentry-trace header if instrumentation is supressed', () => { - const spanContext = { - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '6e0c63257de34c92', - traceFlags: TraceFlags.SAMPLED, - }; - const context = suppressTracing(trace.setSpanContext(ROOT_CONTEXT, spanContext)); - propagator.inject(context, carrier, defaultTextMapSetter); - expect(carrier[SENTRY_TRACE_HEADER]).toBe(undefined); - }); - }); - - describe('baggage', () => { - const client = { - getOptions: () => ({ - environment: 'production', - release: '1.0.0', - }), - getDsn: () => ({ - publicKey: 'abc', - }), - }; - // @ts-ignore Use mock client for unit tests - const hub: Hub = new Hub(client); - makeMain(hub); - - afterEach(() => { - SENTRY_SPAN_PROCESSOR_MAP.clear(); - }); - - enum PerfType { - Transaction = 'transaction', - Span = 'span', - } - - function createTransactionAndMaybeSpan(type: PerfType, transactionContext: TransactionContext) { - const transaction = new Transaction(transactionContext, hub); - SENTRY_SPAN_PROCESSOR_MAP.set(transaction.spanId, transaction); - if (type === PerfType.Span) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { spanId, ...ctx } = transactionContext; - const span = transaction.startChild({ ...ctx, description: transaction.name }); - SENTRY_SPAN_PROCESSOR_MAP.set(span.spanId, span); - } - } - - describe.each([PerfType.Transaction, PerfType.Span])('with active %s', type => { - it.each([ - [ - 'should set baggage header when sampled', - { - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '6e0c63257de34c92', - traceFlags: TraceFlags.SAMPLED, - }, - { - name: 'sampled-transaction', - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '6e0c63257de34c92', - sampled: true, - }, - 'sentry-environment=production,sentry-release=1.0.0,sentry-transaction=sampled-transaction,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b', - ], - [ - 'should NOT set baggage header when not sampled', - { - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '6e0c63257de34c92', - traceFlags: TraceFlags.NONE, - }, - { - name: 'not-sampled-transaction', - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '6e0c63257de34c92', - sampled: false, - }, - 'sentry-environment=production,sentry-release=1.0.0,sentry-transaction=not-sampled-transaction,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b', - ], - [ - 'should NOT set baggage header when traceId is empty', - { - traceId: '', - spanId: '6e0c63257de34c92', - traceFlags: TraceFlags.SAMPLED, - }, - { - name: 'empty-traceId-transaction', - traceId: '', - spanId: '6e0c63257de34c92', - sampled: true, - }, - undefined, - ], - [ - 'should NOT set baggage header when spanId is empty', - { - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '', - traceFlags: TraceFlags.SAMPLED, - }, - { - name: 'empty-spanId-transaction', - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '', - sampled: true, - }, - undefined, - ], - ])('%s', (_name, spanContext, transactionContext, expected) => { - createTransactionAndMaybeSpan(type, transactionContext); - const context = trace.setSpanContext(ROOT_CONTEXT, spanContext); - propagator.inject(context, carrier, defaultTextMapSetter); - expect(carrier[SENTRY_BAGGAGE_HEADER]).toBe(expected); - }); - - it('should NOT set sentry-trace header if instrumentation is supressed', () => { - const spanContext = { - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '6e0c63257de34c92', - traceFlags: TraceFlags.SAMPLED, - }; - const transactionContext = { - name: 'sampled-transaction', - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '6e0c63257de34c92', - sampled: true, - }; - createTransactionAndMaybeSpan(type, transactionContext); - const context = suppressTracing(trace.setSpanContext(ROOT_CONTEXT, spanContext)); - propagator.inject(context, carrier, defaultTextMapSetter); - expect(carrier[SENTRY_TRACE_HEADER]).toBe(undefined); - }); - }); - }); - }); }); From d884c91cf4cd70f600294807d911b9c6b2b141bd Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 2 Nov 2022 13:49:57 +0100 Subject: [PATCH 3/3] feat(otel): Add extract functionality to SentryPropagator --- packages/opentelemetry-node/src/constants.ts | 6 ++ packages/opentelemetry-node/src/propagator.ts | 40 ++++++++++-- .../opentelemetry-node/src/spanprocessor.ts | 25 ++++++-- .../test/propagator.test.ts | 62 ++++++++++++++++++- 4 files changed, 122 insertions(+), 11 deletions(-) diff --git a/packages/opentelemetry-node/src/constants.ts b/packages/opentelemetry-node/src/constants.ts index 5c179dc5335b..55f386f2b39f 100644 --- a/packages/opentelemetry-node/src/constants.ts +++ b/packages/opentelemetry-node/src/constants.ts @@ -1,3 +1,9 @@ +import { createContextKey } from '@opentelemetry/api'; + export const SENTRY_TRACE_HEADER = 'sentry-trace'; export const SENTRY_BAGGAGE_HEADER = 'baggage'; + +export const SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY = createContextKey('SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY'); + +export const SENTRY_TRACE_PARENT_CONTEXT_KEY = createContextKey('SENTRY_TRACE_PARENT_CONTEXT_KEY'); diff --git a/packages/opentelemetry-node/src/propagator.ts b/packages/opentelemetry-node/src/propagator.ts index ab85a2f08d23..e028377a2dfa 100644 --- a/packages/opentelemetry-node/src/propagator.ts +++ b/packages/opentelemetry-node/src/propagator.ts @@ -8,9 +8,18 @@ import { TraceFlags, } from '@opentelemetry/api'; import { isTracingSuppressed } from '@opentelemetry/core'; -import { dynamicSamplingContextToSentryBaggageHeader } from '@sentry/utils'; +import { + baggageHeaderToDynamicSamplingContext, + dynamicSamplingContextToSentryBaggageHeader, + extractTraceparentData, +} from '@sentry/utils'; -import { SENTRY_BAGGAGE_HEADER, SENTRY_TRACE_HEADER } from './constants'; +import { + SENTRY_BAGGAGE_HEADER, + SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY, + SENTRY_TRACE_HEADER, + SENTRY_TRACE_PARENT_CONTEXT_KEY, +} from './constants'; import { SENTRY_SPAN_PROCESSOR_MAP } from './spanprocessor'; /** @@ -44,8 +53,31 @@ export class SentryPropagator implements TextMapPropagator { /** * @inheritDoc */ - public extract(context: Context, _carrier: unknown, _getter: TextMapGetter): Context { - return context; + public extract(context: Context, carrier: unknown, getter: TextMapGetter): Context { + let newContext = context; + + const maybeSentryTraceHeader: string | string[] | undefined = getter.get(carrier, SENTRY_TRACE_HEADER); + if (maybeSentryTraceHeader) { + const header = Array.isArray(maybeSentryTraceHeader) ? maybeSentryTraceHeader[0] : maybeSentryTraceHeader; + const traceparentData = extractTraceparentData(header); + newContext = newContext.setValue(SENTRY_TRACE_PARENT_CONTEXT_KEY, traceparentData); + if (traceparentData) { + const traceFlags = traceparentData.parentSampled ? TraceFlags.SAMPLED : TraceFlags.NONE; + const spanContext = { + traceId: traceparentData.traceId || '', + spanId: traceparentData.parentSpanId || '', + isRemote: true, + traceFlags, + }; + newContext = trace.setSpanContext(newContext, spanContext); + } + } + + const maybeBaggageHeader = getter.get(carrier, SENTRY_BAGGAGE_HEADER); + const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(maybeBaggageHeader); + newContext = newContext.setValue(SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY, dynamicSamplingContext); + + return newContext; } /** diff --git a/packages/opentelemetry-node/src/spanprocessor.ts b/packages/opentelemetry-node/src/spanprocessor.ts index de5f39b3a7fc..197a17587327 100644 --- a/packages/opentelemetry-node/src/spanprocessor.ts +++ b/packages/opentelemetry-node/src/spanprocessor.ts @@ -2,9 +2,10 @@ import { Context } from '@opentelemetry/api'; import { Span as OtelSpan, SpanProcessor as OtelSpanProcessor } from '@opentelemetry/sdk-trace-base'; import { getCurrentHub, withScope } from '@sentry/core'; import { Transaction } from '@sentry/tracing'; -import { Span as SentrySpan, TransactionContext } from '@sentry/types'; +import { DynamicSamplingContext, Span as SentrySpan, TraceparentData, TransactionContext } from '@sentry/types'; import { logger } from '@sentry/utils'; +import { SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY, SENTRY_TRACE_PARENT_CONTEXT_KEY } from './constants'; import { isSentryRequestSpan } from './utils/is-sentry-request'; import { mapOtelStatus } from './utils/map-otel-status'; import { parseSpanDescription } from './utils/parse-otel-span-description'; @@ -22,7 +23,7 @@ export class SentrySpanProcessor implements OtelSpanProcessor { /** * @inheritDoc */ - public onStart(otelSpan: OtelSpan, _parentContext: Context): void { + public onStart(otelSpan: OtelSpan, parentContext: Context): void { const hub = getCurrentHub(); if (!hub) { __DEBUG_BUILD__ && logger.error('SentrySpanProcessor has triggered onStart before a hub has been setup.'); @@ -51,7 +52,7 @@ export class SentrySpanProcessor implements OtelSpanProcessor { SENTRY_SPAN_PROCESSOR_MAP.set(otelSpanId, sentryChildSpan); } else { - const traceCtx = getTraceData(otelSpan); + const traceCtx = getTraceData(otelSpan, parentContext); const transaction = hub.startTransaction({ name: otelSpan.name, ...traceCtx, @@ -117,13 +118,27 @@ export class SentrySpanProcessor implements OtelSpanProcessor { } } -function getTraceData(otelSpan: OtelSpan): Partial { +function getTraceData(otelSpan: OtelSpan, parentContext: Context): Partial { const spanContext = otelSpan.spanContext(); const traceId = spanContext.traceId; const spanId = spanContext.spanId; const parentSpanId = otelSpan.parentSpanId; - return { spanId, traceId, parentSpanId }; + const traceparentData = parentContext.getValue(SENTRY_TRACE_PARENT_CONTEXT_KEY) as TraceparentData | undefined; + const dynamicSamplingContext = parentContext.getValue(SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY) as + | Partial + | undefined; + + return { + spanId, + traceId, + parentSpanId, + metadata: { + // only set dynamic sampling context if sentry-trace header was set + dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext, + source: 'custom', + }, + }; } function finishTransactionWithContextFromOtelData(transaction: Transaction, otelSpan: OtelSpan): void { diff --git a/packages/opentelemetry-node/test/propagator.test.ts b/packages/opentelemetry-node/test/propagator.test.ts index fd8369ea9fd0..3e85a76033cf 100644 --- a/packages/opentelemetry-node/test/propagator.test.ts +++ b/packages/opentelemetry-node/test/propagator.test.ts @@ -1,10 +1,15 @@ -import { defaultTextMapSetter, ROOT_CONTEXT, trace, TraceFlags } from '@opentelemetry/api'; +import { defaultTextMapGetter, defaultTextMapSetter, ROOT_CONTEXT, trace, TraceFlags } from '@opentelemetry/api'; import { suppressTracing } from '@opentelemetry/core'; import { Hub, makeMain } from '@sentry/core'; import { addExtensionMethods, Transaction } from '@sentry/tracing'; import { TransactionContext } from '@sentry/types'; -import { SENTRY_BAGGAGE_HEADER, SENTRY_TRACE_HEADER } from '../src/constants'; +import { + SENTRY_BAGGAGE_HEADER, + SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY, + SENTRY_TRACE_HEADER, + SENTRY_TRACE_PARENT_CONTEXT_KEY, +} from '../src/constants'; import { SentryPropagator } from '../src/propagator'; import { SENTRY_SPAN_PROCESSOR_MAP } from '../src/spanprocessor'; @@ -204,4 +209,57 @@ describe('SentryPropagator', () => { }); }); }); + + describe('extract', () => { + it('sets sentry span context on the context', () => { + const sentryTraceHeader = 'd4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1'; + carrier[SENTRY_TRACE_HEADER] = sentryTraceHeader; + const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); + expect(trace.getSpanContext(context)).toEqual({ + isRemote: true, + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.SAMPLED, + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + }); + }); + + it('sets defined sentry trace header on context', () => { + const sentryTraceHeader = 'd4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1'; + carrier[SENTRY_TRACE_HEADER] = sentryTraceHeader; + const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); + expect(context.getValue(SENTRY_TRACE_PARENT_CONTEXT_KEY)).toEqual({ + parentSampled: true, + parentSpanId: '6e0c63257de34c92', + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + }); + }); + + it('sets undefined sentry trace header on context', () => { + const sentryTraceHeader = undefined; + carrier[SENTRY_TRACE_HEADER] = sentryTraceHeader; + const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); + expect(context.getValue(SENTRY_TRACE_PARENT_CONTEXT_KEY)).toEqual(undefined); + }); + + it('sets defined dynamic sampling context on context', () => { + const baggage = + 'sentry-environment=production,sentry-release=1.0.0,sentry-transaction=dsc-transaction,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b'; + carrier[SENTRY_BAGGAGE_HEADER] = baggage; + const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); + expect(context.getValue(SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY)).toEqual({ + environment: 'production', + public_key: 'abc', + release: '1.0.0', + trace_id: 'd4cda95b652f4a1592b449d5929fda1b', + transaction: 'dsc-transaction', + }); + }); + + it('sets undefined dynamic sampling context on context', () => { + const baggage = ''; + carrier[SENTRY_BAGGAGE_HEADER] = baggage; + const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); + expect(context.getValue(SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY)).toEqual(undefined); + }); + }); });