1- import static datadog.trace.agent.test.base.HttpServerTest.someBytes
2- import static datadog.trace.agent.test.base.HttpServerTest.websocketCloseSpan
3- import static datadog.trace.agent.test.base.HttpServerTest.websocketReceiveSpan
4- import static datadog.trace.agent.test.base.HttpServerTest.websocketSendSpan
5- import static datadog.trace.agent.test.utils.TraceUtils.basicSpan
6- import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace
7- import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_CLASSES_EXCLUDE
8- import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_MESSAGES_ENABLED
9- import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_MESSAGES_INHERIT_SAMPLING
10- import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_MESSAGES_SEPARATE_TRACES
11- import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_TAG_SESSION_ID
12- import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan
13-
141import datadog.trace.agent.test.AgentTestRunner
152import datadog.trace.api.DDTags
3+ import datadog.trace.api.sampling.PrioritySampling
164import datadog.trace.bootstrap.instrumentation.api.AgentSpan
175import datadog.trace.bootstrap.instrumentation.api.InstrumentationTags
186import datadog.trace.bootstrap.instrumentation.api.Tags
197import datadog.trace.core.DDSpan
8+ import datadog.trace.core.propagation.ExtractedContext
209import net.bytebuddy.utility.RandomString
2110import org.glassfish.tyrus.container.inmemory.InMemoryClientContainer
2211import org.glassfish.tyrus.server.TyrusServerConfiguration
@@ -29,6 +18,19 @@ import javax.websocket.server.ServerApplicationConfig
2918import javax.websocket.server.ServerEndpointConfig
3019import java.nio.ByteBuffer
3120
21+ import static datadog.trace.agent.test.base.HttpServerTest.someBytes
22+ import static datadog.trace.agent.test.base.HttpServerTest.websocketCloseSpan
23+ import static datadog.trace.agent.test.base.HttpServerTest.websocketReceiveSpan
24+ import static datadog.trace.agent.test.base.HttpServerTest.websocketSendSpan
25+ import static datadog.trace.agent.test.utils.TraceUtils.basicSpan
26+ import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace
27+ import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_CLASSES_EXCLUDE
28+ import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_MESSAGES_ENABLED
29+ import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_MESSAGES_INHERIT_SAMPLING
30+ import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_MESSAGES_SEPARATE_TRACES
31+ import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_TAG_SESSION_ID
32+ import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan
33+
3234class WebsocketTest extends AgentTestRunner {
3335
3436 @Override
@@ -38,8 +40,8 @@ class WebsocketTest extends AgentTestRunner {
3840 injectSysConfig(TRACE_CLASSES_EXCLUDE , " EndpointWrapper" )
3941 }
4042
41- def createHandshakeSpan (String spanName , String url ) {
42- def span = TEST_TRACER . startSpan(" test" , spanName, null )
43+ def createHandshakeSpan (String spanName , String url , Object parentContext = null ) {
44+ def span = TEST_TRACER . startSpan(" test" , spanName, parentContext )
4345 handshakeTags(url). each { span. setTag(it. key, it. value) }
4446 span. finish()
4547 span
@@ -574,4 +576,60 @@ class WebsocketTest extends AgentTestRunner {
574576 }
575577 })
576578 }
579+
580+ def " test trace state is inherited" () {
581+ when :
582+ String url = " ws://inmemory/test"
583+ def clientHandshake = createHandshakeSpan(" http.request" , url) // simulate client span
584+ clientHandshake. setSamplingPriority(PrioritySampling . SAMPLER_DROP ) // simulate sampler drop
585+ def serverHandshake = createHandshakeSpan(" servlet.request" , url,
586+ new ExtractedContext (clientHandshake. context(). getTraceId(), clientHandshake. context(). getSpanId(), clientHandshake. context(). getSamplingPriority(),
587+ " test" , 0 , [" example_baggage" : " test" ], null , null , null , null , null )) // simulate server span
588+ def session = deployEndpointAndConnect(new Endpoints.TestEndpoint (new Endpoints.FullStringHandler ()),
589+ clientHandshake, serverHandshake, url)
590+
591+ runUnderTrace(" parent" ) {
592+ session. getBasicRemote(). sendText(" Hello" )
593+ session. close()
594+ }
595+ then :
596+ def ht = handshakeTags(url)
597+ assertTraces(5 , {
598+ trace(1 ) {
599+ basicSpan(it, " http.request" , " GET /test" , null , null , ht)
600+ }
601+ trace(1 ) {
602+ span {
603+ operationName " servlet.request"
604+ resourceName " GET /test"
605+ childOf(clientHandshake as DDSpan )
606+ tags {
607+ for (def entry : ht) {
608+ tag(entry. key, entry. value)
609+ }
610+ defaultTags(true )
611+ }
612+ }
613+ }
614+ trace(3 ) {
615+ sortSpansByStart()
616+ basicSpan(it, " parent" )
617+ websocketSendSpan(it, clientHandshake as DDSpan , " text" , 5 , 1 , span(0 ))
618+ websocketCloseSpan(it, clientHandshake as DDSpan , true , 1000 , null , span(0 ))
619+ }
620+ trace(1 ) {
621+ websocketReceiveSpan(it, serverHandshake as DDSpan , " text" , 5 , 1 )
622+ }
623+ trace(1 ) {
624+ websocketCloseSpan(it, serverHandshake as DDSpan , false , 1000 , { it == null || it == ' no reason given' })
625+ }
626+ })
627+ // check that the handshake trace state is inherited
628+ TEST_WRITER . flatten(). findAll { span -> (span as DDSpan ). getSpanType() == " websocket" && (span as DDSpan ). getParentId() == 0 }. each {
629+ assert (it as DDSpan ). getSamplingPriority() == serverHandshake. getSamplingPriority()
630+ assert (it as DDSpan ). getOrigin() == serverHandshake. context(). getOrigin()
631+ assert (it as DDSpan ). getBaggage() == serverHandshake. context(). getBaggageItems()
632+ assert ! (it as DDSpan ). getBaggage(). isEmpty()
633+ }
634+ }
577635}
0 commit comments