JavaagentInstrumentationTest.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /*
  2. * Copyright The OpenTelemetry Authors
  3. * SPDX-License-Identifier: Apache-2.0
  4. */
  5. package io.opentelemetry.opencensusshim;
  6. import io.opencensus.trace.AttributeValue;
  7. import io.opencensus.trace.Tracing;
  8. import io.opencensus.trace.samplers.Samplers;
  9. import io.opentelemetry.api.common.AttributeKey;
  10. import io.opentelemetry.api.trace.Span;
  11. import io.opentelemetry.api.trace.SpanKind;
  12. import io.opentelemetry.api.trace.Tracer;
  13. import io.opentelemetry.context.Scope;
  14. import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
  15. import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
  16. import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions;
  17. import org.assertj.core.api.AbstractBooleanAssert;
  18. import org.junit.jupiter.api.BeforeEach;
  19. import org.junit.jupiter.api.Test;
  20. import org.junit.jupiter.api.extension.RegisterExtension;
  21. public class JavaagentInstrumentationTest {
  22. @RegisterExtension
  23. static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
  24. @BeforeEach
  25. void setup() {
  26. // by default in opencensus, a probability sampling is used which is not 100%;
  27. // we specifically set this configuration here to always sample to ensure traces are emitted for
  28. // our tests
  29. Tracing.getTraceConfig()
  30. .updateActiveTraceParams(
  31. Tracing.getTraceConfig().getActiveTraceParams().toBuilder()
  32. .setSampler(Samplers.alwaysSample())
  33. .build());
  34. }
  35. @Test
  36. void testInterleavedSpansOcFirst() {
  37. io.opencensus.trace.Tracer ocTracer = Tracing.getTracer();
  38. Tracer otelTracer = testing.getOpenTelemetry().getTracer("test");
  39. io.opencensus.trace.Span outerSpan = ocTracer.spanBuilder("outer-span").startSpan();
  40. Span midSpan;
  41. io.opencensus.trace.Span innerSpan;
  42. outerSpan.putAttribute("outer", AttributeValue.booleanAttributeValue(true));
  43. try (io.opencensus.common.Scope outerScope = ocTracer.withSpan(outerSpan)) {
  44. midSpan =
  45. otelTracer
  46. .spanBuilder("mid-span")
  47. .setSpanKind(SpanKind.INTERNAL)
  48. .setAttribute("middle", true)
  49. .startSpan();
  50. try (Scope midScope = midSpan.makeCurrent()) {
  51. innerSpan = ocTracer.spanBuilder("inner-span").startSpan();
  52. innerSpan.putAttribute("inner", AttributeValue.booleanAttributeValue(true));
  53. // make current and immediately close -- avoid empty try block
  54. ocTracer.withSpan(innerSpan).close();
  55. innerSpan.end();
  56. } finally {
  57. midSpan.end();
  58. }
  59. } finally {
  60. outerSpan.end();
  61. }
  62. Tracing.getExportComponent().shutdown();
  63. // expecting 1 trace with 3 spans
  64. testing.waitAndAssertTraces(
  65. ta ->
  66. // ensure each span's attributes haven't seeped into parents or children
  67. ta.hasSpansSatisfyingExactly(
  68. // outer span
  69. sa ->
  70. sa.hasName("outer-span")
  71. .hasNoParent()
  72. .hasAttribute(AttributeKey.booleanKey("outer"), true)
  73. .hasAttributesSatisfying(
  74. OpenTelemetryAssertions.satisfies(
  75. AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
  76. OpenTelemetryAssertions.satisfies(
  77. AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull)),
  78. // middle span
  79. sa ->
  80. sa.hasName("mid-span")
  81. .hasParent(ta.getSpan(0))
  82. .hasAttribute(AttributeKey.booleanKey("middle"), true)
  83. .hasAttributesSatisfying(
  84. OpenTelemetryAssertions.satisfies(
  85. AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
  86. OpenTelemetryAssertions.satisfies(
  87. AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull)),
  88. // inner span
  89. sa ->
  90. sa.hasName("inner-span")
  91. .hasParent(ta.getSpan(1))
  92. .hasAttribute(AttributeKey.booleanKey("inner"), true)
  93. .hasAttributesSatisfying(
  94. OpenTelemetryAssertions.satisfies(
  95. AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull),
  96. OpenTelemetryAssertions.satisfies(
  97. AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull))));
  98. }
  99. @Test
  100. void testInterleavedSpansOtelFirst() {
  101. io.opencensus.trace.Tracer ocTracer = Tracing.getTracer();
  102. Tracer otelTracer = testing.getOpenTelemetry().getTracer("test");
  103. Span outerSpan =
  104. otelTracer
  105. .spanBuilder("outer-span")
  106. .setSpanKind(SpanKind.INTERNAL)
  107. .setAttribute("outer", true)
  108. .startSpan();
  109. io.opencensus.trace.Span midSpan;
  110. Span innerSpan;
  111. try (Scope outerScope = outerSpan.makeCurrent()) {
  112. midSpan = ocTracer.spanBuilder("mid-span").startSpan();
  113. midSpan.putAttribute("middle", AttributeValue.booleanAttributeValue(true));
  114. try (io.opencensus.common.Scope midScope = ocTracer.withSpan(midSpan)) {
  115. innerSpan =
  116. otelTracer
  117. .spanBuilder("inner-span")
  118. .setSpanKind(SpanKind.INTERNAL)
  119. .setAttribute("inner", true)
  120. .startSpan();
  121. // make current and immediately close -- avoid empty try block
  122. innerSpan.makeCurrent().close();
  123. innerSpan.end();
  124. } finally {
  125. midSpan.end();
  126. }
  127. } finally {
  128. outerSpan.end();
  129. }
  130. Tracing.getExportComponent().shutdown();
  131. // expecting 1 trace with 3 spans
  132. testing.waitAndAssertTraces(
  133. ta ->
  134. // ensure each span's attributes haven't seeped into parents or children
  135. ta.hasSpansSatisfyingExactly(
  136. // outer span
  137. sa ->
  138. sa.hasName("outer-span")
  139. .hasNoParent()
  140. .hasAttribute(AttributeKey.booleanKey("outer"), true)
  141. .hasAttributesSatisfying(
  142. OpenTelemetryAssertions.satisfies(
  143. AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
  144. OpenTelemetryAssertions.satisfies(
  145. AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull)),
  146. // middle span
  147. sa ->
  148. sa.hasName("mid-span")
  149. .hasParent(ta.getSpan(0))
  150. .hasAttribute(AttributeKey.booleanKey("middle"), true)
  151. .hasAttributesSatisfying(
  152. OpenTelemetryAssertions.satisfies(
  153. AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
  154. OpenTelemetryAssertions.satisfies(
  155. AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull)),
  156. // inner span
  157. sa ->
  158. sa.hasName("inner-span")
  159. .hasParent(ta.getSpan(1))
  160. .hasAttribute(AttributeKey.booleanKey("inner"), true)
  161. .hasAttributesSatisfying(
  162. OpenTelemetryAssertions.satisfies(
  163. AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull),
  164. OpenTelemetryAssertions.satisfies(
  165. AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull))));
  166. }
  167. @Test
  168. void testStartingWithOtelSpan() {
  169. io.opencensus.trace.Tracer ocTracer = Tracing.getTracer();
  170. Tracer otelTracer = testing.getOpenTelemetry().getTracer("test");
  171. Span otelSpan =
  172. otelTracer
  173. .spanBuilder("otel-span")
  174. .setSpanKind(SpanKind.INTERNAL)
  175. .setAttribute("present-on-otel", true)
  176. .startSpan();
  177. io.opencensus.trace.Span ocSpan;
  178. try (Scope scope = otelSpan.makeCurrent()) {
  179. ocSpan = ocTracer.spanBuilder("oc-span").startSpan();
  180. try (io.opencensus.common.Scope ocScope = ocTracer.withSpan(ocSpan)) {
  181. ocTracer
  182. .getCurrentSpan()
  183. .putAttribute("present-on-oc", AttributeValue.booleanAttributeValue(true));
  184. }
  185. ocSpan.end();
  186. }
  187. otelSpan.end();
  188. Tracing.getExportComponent().shutdown();
  189. testing.waitAndAssertTraces(
  190. trace ->
  191. trace.hasSpansSatisfyingExactly(
  192. span ->
  193. span.hasName("otel-span")
  194. .hasNoParent()
  195. .hasAttribute(AttributeKey.booleanKey("present-on-otel"), true),
  196. span ->
  197. span.hasName("oc-span")
  198. .hasParent(trace.getSpan(0))
  199. .hasAttribute(AttributeKey.booleanKey("present-on-oc"), true)));
  200. }
  201. @Test
  202. void testStartingWithOpenCensusSpan() {
  203. io.opencensus.trace.Tracer ocTracer = Tracing.getTracer();
  204. Tracer otelTracer = testing.getOpenTelemetry().getTracer("test");
  205. io.opencensus.trace.Span ocSpan = ocTracer.spanBuilder("oc-span").startSpan();
  206. ocSpan.putAttribute("present-on-oc", AttributeValue.booleanAttributeValue(true));
  207. Span otelSpan;
  208. try (io.opencensus.common.Scope ocScope = ocTracer.withSpan(ocSpan)) {
  209. otelSpan = otelTracer.spanBuilder("otel-span").setSpanKind(SpanKind.INTERNAL).startSpan();
  210. try (Scope scope = otelSpan.makeCurrent()) {
  211. Span.current().setAttribute("present-on-otel", true);
  212. }
  213. otelSpan.end();
  214. }
  215. ocSpan.end();
  216. Tracing.getExportComponent().shutdown();
  217. testing.waitAndAssertTraces(
  218. trace ->
  219. trace.hasSpansSatisfyingExactly(
  220. span ->
  221. span.hasName("oc-span")
  222. .hasNoParent()
  223. .hasAttribute(AttributeKey.booleanKey("present-on-oc"), true),
  224. span ->
  225. span.hasName("otel-span")
  226. .hasParent(trace.getSpan(0))
  227. .hasAttribute(AttributeKey.booleanKey("present-on-otel"), true)));
  228. }
  229. @Test
  230. void testNestedOpenCensusSpans() {
  231. io.opencensus.trace.Tracer ocTracer = Tracing.getTracer();
  232. io.opencensus.trace.Span outerSpan = ocTracer.spanBuilder("outer-span").startSpan();
  233. io.opencensus.trace.Span midSpan;
  234. io.opencensus.trace.Span innerSpan;
  235. outerSpan.putAttribute("outer", AttributeValue.booleanAttributeValue(true));
  236. try (io.opencensus.common.Scope outerScope = ocTracer.withSpan(outerSpan)) {
  237. midSpan = ocTracer.spanBuilder("mid-span").startSpan();
  238. midSpan.putAttribute("middle", AttributeValue.booleanAttributeValue(true));
  239. try (io.opencensus.common.Scope midScope = ocTracer.withSpan(midSpan)) {
  240. innerSpan = ocTracer.spanBuilder("inner-span").startSpan();
  241. innerSpan.putAttribute("inner", AttributeValue.booleanAttributeValue(true));
  242. // make current and immediately close -- avoid empty try block
  243. ocTracer.withSpan(innerSpan).close();
  244. innerSpan.end();
  245. } finally {
  246. midSpan.end();
  247. }
  248. } finally {
  249. outerSpan.end();
  250. }
  251. Tracing.getExportComponent().shutdown();
  252. // expecting 1 trace with 3 spans
  253. testing.waitAndAssertTraces(
  254. ta ->
  255. // ensure each span's attributes haven't seeped into parents or children
  256. ta.hasSpansSatisfyingExactly(
  257. // outer span
  258. sa ->
  259. sa.hasName("outer-span")
  260. .hasNoParent()
  261. .hasAttribute(AttributeKey.booleanKey("outer"), true)
  262. .hasAttributesSatisfying(
  263. OpenTelemetryAssertions.satisfies(
  264. AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
  265. OpenTelemetryAssertions.satisfies(
  266. AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull)),
  267. // middle span
  268. sa ->
  269. sa.hasName("mid-span")
  270. .hasParent(ta.getSpan(0))
  271. .hasAttribute(AttributeKey.booleanKey("middle"), true)
  272. .hasAttributesSatisfying(
  273. OpenTelemetryAssertions.satisfies(
  274. AttributeKey.booleanKey("inner"), AbstractBooleanAssert::isNull),
  275. OpenTelemetryAssertions.satisfies(
  276. AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull)),
  277. // inner span
  278. sa ->
  279. sa.hasName("inner-span")
  280. .hasParent(ta.getSpan(1))
  281. .hasAttribute(AttributeKey.booleanKey("inner"), true)
  282. .hasAttributesSatisfying(
  283. OpenTelemetryAssertions.satisfies(
  284. AttributeKey.booleanKey("middle"), AbstractBooleanAssert::isNull),
  285. OpenTelemetryAssertions.satisfies(
  286. AttributeKey.booleanKey("outer"), AbstractBooleanAssert::isNull))));
  287. }
  288. }