DatadogHttpExtractorTest.groovy 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package datadog.opentracing.propagation
  2. import datadog.trace.util.test.DDSpecification
  3. import io.opentracing.SpanContext
  4. import io.opentracing.propagation.TextMapExtractAdapter
  5. import static datadog.opentracing.DDTracer.TRACE_ID_MAX
  6. import static datadog.opentracing.propagation.DatadogHttpCodec.ORIGIN_KEY
  7. import static datadog.opentracing.propagation.DatadogHttpCodec.OT_BAGGAGE_PREFIX
  8. import static datadog.opentracing.propagation.DatadogHttpCodec.SPAN_ID_KEY
  9. import static datadog.opentracing.propagation.DatadogHttpCodec.TRACE_ID_KEY
  10. class DatadogHttpExtractorTest extends DDSpecification {
  11. HttpCodec.Extractor extractor = new DatadogHttpCodec.Extractor(["SOME_HEADER": "some-tag"])
  12. def "extract http headers"() {
  13. setup:
  14. def headers = [
  15. (TRACE_ID_KEY.toUpperCase()) : traceId.toString(),
  16. (SPAN_ID_KEY.toUpperCase()) : spanId.toString(),
  17. (OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
  18. (OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
  19. SOME_HEADER : "my-interesting-info",
  20. ]
  21. if (origin) {
  22. headers.put(ORIGIN_KEY, origin)
  23. }
  24. when:
  25. final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(headers))
  26. then:
  27. context.traceId == new BigInteger(traceId)
  28. context.spanId == new BigInteger(spanId)
  29. context.baggage == ["k1": "v1", "k2": "v2"]
  30. context.tags == ["some-tag": "my-interesting-info"]
  31. context.origin == origin
  32. where:
  33. traceId | spanId | origin
  34. "1" | "2" | null
  35. "2" | "3" | "saipan"
  36. TRACE_ID_MAX.toString() | (TRACE_ID_MAX - 1).toString() | "saipan"
  37. (TRACE_ID_MAX - 1).toString() | TRACE_ID_MAX.toString() | "saipan"
  38. }
  39. def "extract header tags with no propagation"() {
  40. when:
  41. TagContext context = extractor.extract(new TextMapExtractAdapter(headers))
  42. then:
  43. !(context instanceof ExtractedContext)
  44. context.getTags() == ["some-tag": "my-interesting-info"]
  45. if (headers.containsKey(ORIGIN_KEY)) {
  46. assert ((TagContext) context).origin == "my-origin"
  47. }
  48. where:
  49. headers | _
  50. [SOME_HEADER: "my-interesting-info"] | _
  51. [(ORIGIN_KEY): "my-origin", SOME_HEADER: "my-interesting-info"] | _
  52. }
  53. def "extract empty headers returns null"() {
  54. expect:
  55. extractor.extract(new TextMapExtractAdapter(["ignored-header": "ignored-value"])) == null
  56. }
  57. def "extract http headers with invalid non-numeric ID"() {
  58. setup:
  59. def headers = [
  60. (TRACE_ID_KEY.toUpperCase()) : "traceId",
  61. (SPAN_ID_KEY.toUpperCase()) : "spanId",
  62. (OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
  63. (OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
  64. SOME_HEADER : "my-interesting-info",
  65. ]
  66. when:
  67. SpanContext context = extractor.extract(new TextMapExtractAdapter(headers))
  68. then:
  69. context == null
  70. }
  71. def "extract http headers with out of range trace ID"() {
  72. setup:
  73. String outOfRangeTraceId = (TRACE_ID_MAX + 1).toString()
  74. def headers = [
  75. (TRACE_ID_KEY.toUpperCase()) : outOfRangeTraceId,
  76. (SPAN_ID_KEY.toUpperCase()) : "0",
  77. (OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
  78. (OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
  79. SOME_HEADER : "my-interesting-info",
  80. ]
  81. when:
  82. SpanContext context = extractor.extract(new TextMapExtractAdapter(headers))
  83. then:
  84. context == null
  85. }
  86. def "extract http headers with out of range span ID"() {
  87. setup:
  88. def headers = [
  89. (TRACE_ID_KEY.toUpperCase()) : "0",
  90. (SPAN_ID_KEY.toUpperCase()) : "-1",
  91. (OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1",
  92. (OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2",
  93. SOME_HEADER : "my-interesting-info",
  94. ]
  95. when:
  96. SpanContext context = extractor.extract(new TextMapExtractAdapter(headers))
  97. then:
  98. context == null
  99. }
  100. def "more ID range validation"() {
  101. setup:
  102. def headers = [
  103. (TRACE_ID_KEY.toUpperCase()): traceId,
  104. (SPAN_ID_KEY.toUpperCase()) : spanId,
  105. ]
  106. when:
  107. final ExtractedContext context = extractor.extract(new TextMapExtractAdapter(headers))
  108. then:
  109. if (expectedTraceId) {
  110. assert context.traceId == expectedTraceId
  111. assert context.spanId == expectedSpanId
  112. } else {
  113. assert context == null
  114. }
  115. where:
  116. gtTraceId | gSpanId | expectedTraceId | expectedSpanId
  117. "-1" | "1" | null | 0G
  118. "1" | "-1" | null | 0G
  119. "0" | "1" | null | 0G
  120. "1" | "0" | 1G | 0G
  121. "$TRACE_ID_MAX" | "1" | TRACE_ID_MAX | 1G
  122. "${TRACE_ID_MAX + 1}" | "1" | null | 1G
  123. "1" | "$TRACE_ID_MAX" | 1G | TRACE_ID_MAX
  124. "1" | "${TRACE_ID_MAX + 1}" | null | 0G
  125. traceId = gtTraceId.toString()
  126. spanId = gSpanId.toString()
  127. }
  128. }