@@ -2531,4 +2531,228 @@ abstract class HttpServerTest<SERVER> extends WithHttpServer<SERVER> {
25312531 null
25322532 }
25332533 }
2534+
2535+ def " test inferred proxy span creation and header propagation" () {
2536+ setup :
2537+ injectSysConfig(" dd.trace_inferred_proxy_services_enabled" , " true" )
2538+ // def request = new Request.Builder()
2539+ // .url(HttpUrl.get(SUCCESS.resolve(SUCCESS.relativePath())))//"$server.address")
2540+ // .get()
2541+ def request = request(SUCCESS , " GET" , null )
2542+ .header(" x-dd-proxy" , " true" )
2543+ .header(" x-dd-proxy-request-time-ms" , " 123" )
2544+ .header(" x-dd-proxy-domain-name" , " localhost" )
2545+ .header(" x-dd-proxy-httpmethod" , " GET" )
2546+ .header(" x-dd-proxy-path" , SUCCESS . path)
2547+ .header(" x-dd-proxy-stage" , " dev" )
2548+ .build()
2549+
2550+ when :
2551+ def response = client. newCall(request). execute()
2552+ if (isDataStreamsEnabled()) {
2553+ TEST_DATA_STREAMS_WRITER . waitForGroups(1 )
2554+ }
2555+
2556+ then :
2557+ response. code() == SUCCESS . status
2558+ response. body(). string() == SUCCESS . body
2559+
2560+ and :
2561+ assertTraces(1 ) {
2562+ trace(spanCount(SUCCESS )) { // +1 for inferredProxySpan
2563+ sortSpansByStart()
2564+ def inferredProxySpan = span(0 )
2565+ inferredProxySpan. operationName == " aws.apigatewaysergserg"
2566+ inferredProxySpan. tags[" component" ] == " aws.apigateway"
2567+ inferredProxySpan. tags[" resource.name" ] == " GET /api/hello"
2568+ inferredProxySpan. tags[" service.name" ] == " example.com"
2569+ inferredProxySpan. tags[" span.type" ] == " web"
2570+ inferredProxySpan. tags[" http.method" ] == " GET"
2571+ inferredProxySpan. tags[" http.url" ] == " http://example.com/api/hello"
2572+ inferredProxySpan. tags[" stage" ] == " dev"
2573+ inferredProxySpan. tags[" _dd.inferred_span" ] == 1
2574+
2575+ serverSpan(it, null , null , " GET" , SUCCESS )
2576+ if (hasHandlerSpan()) {
2577+ handlerSpan(it)
2578+ }
2579+ controllerSpan(it)
2580+ if (hasResponseSpan(SUCCESS )) {
2581+ responseSpan(it, SUCCESS )
2582+ }
2583+ }
2584+ }
2585+
2586+ and :
2587+ if (isDataStreamsEnabled()) {
2588+ def statsGroups = TEST_DATA_STREAMS_WRITER . groups. findAll { it. parentHash == 0 }
2589+ assert statsGroups. size() >= 1
2590+ def first = statsGroups[0 ]
2591+ verifyAll(first) {
2592+ edgeTags. containsAll(DSM_EDGE_TAGS )
2593+ edgeTags. size() == DSM_EDGE_TAGS . size()
2594+ }
2595+ }
2596+ // cleanup:
2597+ // // make sure we've gotten everything
2598+ // TEST_WRITER.waitForTraces(1)
2599+ //
2600+ // println "\n=== Dumping all collected spans ==="
2601+ // // getTraces() returns a List<List<DDSpan>>
2602+ // TEST_WRITER.getTraces().eachWithIndex { trace, tIdx ->
2603+ // println "Trace #${tIdx}:"
2604+ // trace.eachWithIndex { span, sIdx ->
2605+ // // print out whatever fields you care about
2606+ // println " [${sIdx}] ${span.operationName} " +
2607+ // "(trace=${span.context().traceId}, span=${span.context().spanId})"
2608+ // println " tags=${span.tags}"
2609+ // }
2610+ // }
2611+ }
2612+
2613+ def " test inferred proxy span not created when proxy disabled" () {
2614+ setup :
2615+ injectSysConfig(" dd.trace_inferred_proxy_services_enabled" , " false" )
2616+ def request = request(SUCCESS , " GET" , null )
2617+ .header(" x-dd-proxy" , " true" )
2618+ .header(" x-dd-proxy-request-time-ms" , " 123" )
2619+ .header(" x-dd-proxy-domain-name" , " example.com" )
2620+ .header(" x-dd-proxy-httpmethod" , " GET" )
2621+ .header(" x-dd-proxy-path" , " /api/hello" )
2622+ .header(" x-dd-proxy-stage" , " dev" )
2623+ .build()
2624+
2625+ when :
2626+ def response = client. newCall(request). execute()
2627+ if (isDataStreamsEnabled()) {
2628+ TEST_DATA_STREAMS_WRITER . waitForGroups(1 )
2629+ }
2630+
2631+ then :
2632+ response. code() == SUCCESS . status
2633+ response. body(). string() == SUCCESS . body
2634+
2635+ and :
2636+ assertTraces(1 ) {
2637+ trace(spanCount(SUCCESS )) {
2638+ sortSpansByStart()
2639+ serverSpan(it, null , null , " GET" , SUCCESS )
2640+ if (hasHandlerSpan()) {
2641+ handlerSpan(it)
2642+ }
2643+ controllerSpan(it)
2644+ if (hasResponseSpan(SUCCESS )) {
2645+ responseSpan(it, SUCCESS )
2646+ }
2647+ }
2648+ }
2649+
2650+ and :
2651+ if (isDataStreamsEnabled()) {
2652+ def statsGroups = TEST_DATA_STREAMS_WRITER . groups. findAll { it. parentHash == 0 }
2653+ assert statsGroups. size() >= 1
2654+ def first = statsGroups[0 ]
2655+ verifyAll(first) {
2656+ edgeTags. containsAll(DSM_EDGE_TAGS )
2657+ edgeTags. size() == DSM_EDGE_TAGS . size()
2658+ }
2659+ }
2660+ }
2661+
2662+ def " test inferred proxy span not created with unsupported proxy system" () {
2663+ setup :
2664+ injectSysConfig(" dd.trace_inferred_proxy_services_enabled" , " true" )
2665+ def request = request(SUCCESS , " GET" , null )
2666+ .header(" x-dd-proxy" , " unsupported" )
2667+ .header(" x-dd-proxy-request-time-ms" , " 123" )
2668+ .header(" x-dd-proxy-domain-name" , " example.com" )
2669+ .header(" x-dd-proxy-httpmethod" , " GET" )
2670+ .header(" x-dd-proxy-path" , " /api/hello" )
2671+ .header(" x-dd-proxy-stage" , " dev" )
2672+ .build()
2673+
2674+ when :
2675+ def response = client. newCall(request). execute()
2676+ if (isDataStreamsEnabled()) {
2677+ TEST_DATA_STREAMS_WRITER . waitForGroups(1 )
2678+ }
2679+
2680+ then :
2681+ response. code() == SUCCESS . status
2682+ response. body(). string() == SUCCESS . body
2683+
2684+ and :
2685+ assertTraces(1 ) {
2686+ trace(spanCount(SUCCESS )) {
2687+ sortSpansByStart()
2688+ serverSpan(it, null , null , " GET" , SUCCESS )
2689+ if (hasHandlerSpan()) {
2690+ handlerSpan(it)
2691+ }
2692+ controllerSpan(it)
2693+ if (hasResponseSpan(SUCCESS )) {
2694+ responseSpan(it, SUCCESS )
2695+ }
2696+ }
2697+ }
2698+
2699+ and :
2700+ if (isDataStreamsEnabled()) {
2701+ def statsGroups = TEST_DATA_STREAMS_WRITER . groups. findAll { it. parentHash == 0 }
2702+ assert statsGroups. size() >= 1
2703+ def first = statsGroups[0 ]
2704+ verifyAll(first) {
2705+ edgeTags. containsAll(DSM_EDGE_TAGS )
2706+ edgeTags. size() == DSM_EDGE_TAGS . size()
2707+ }
2708+ }
2709+ }
2710+
2711+ def " test inferred proxy span not created with missing required headers" () {
2712+ setup :
2713+ injectSysConfig(" dd.trace_inferred_proxy_services_enabled" , " true" )
2714+ def request = request(SUCCESS , " GET" , null )
2715+ .header(" x-dd-proxy" , " true" )
2716+ .header(" x-dd-proxy-domain-name" , " example.com" )
2717+ .header(" x-dd-proxy-httpmethod" , " GET" )
2718+ .header(" x-dd-proxy-path" , " /api/hello" )
2719+ .header(" x-dd-proxy-stage" , " dev" )
2720+ .build()
2721+
2722+ when :
2723+ def response = client. newCall(request). execute()
2724+ if (isDataStreamsEnabled()) {
2725+ TEST_DATA_STREAMS_WRITER . waitForGroups(1 )
2726+ }
2727+
2728+ then :
2729+ response. code() == SUCCESS . status
2730+ response. body(). string() == SUCCESS . body
2731+
2732+ and :
2733+ assertTraces(1 ) {
2734+ trace(spanCount(SUCCESS )) {
2735+ sortSpansByStart()
2736+ serverSpan(it, null , null , " GET" , SUCCESS )
2737+ if (hasHandlerSpan()) {
2738+ handlerSpan(it)
2739+ }
2740+ controllerSpan(it)
2741+ if (hasResponseSpan(SUCCESS )) {
2742+ responseSpan(it, SUCCESS )
2743+ }
2744+ }
2745+ }
2746+
2747+ and :
2748+ if (isDataStreamsEnabled()) {
2749+ def statsGroups = TEST_DATA_STREAMS_WRITER . groups. findAll { it. parentHash == 0 }
2750+ assert statsGroups. size() >= 1
2751+ def first = statsGroups[0 ]
2752+ verifyAll(first) {
2753+ edgeTags. containsAll(DSM_EDGE_TAGS )
2754+ edgeTags. size() == DSM_EDGE_TAGS . size()
2755+ }
2756+ }
2757+ }
25342758}
0 commit comments