package rocks.inspectit.agent.java.sdk.opentracing.internal.impl; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import org.mockito.Mock; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import io.opentracing.References; import io.opentracing.SpanContext; import io.opentracing.propagation.Format; import io.opentracing.propagation.TextMap; import rocks.inspectit.agent.java.sdk.opentracing.ExtendedTracer; import rocks.inspectit.agent.java.sdk.opentracing.Reporter; import rocks.inspectit.agent.java.sdk.opentracing.Timer; import rocks.inspectit.agent.java.sdk.opentracing.TracerProvider; import rocks.inspectit.agent.java.sdk.opentracing.propagation.Propagator; import rocks.inspectit.shared.all.testbase.TestBase; /** * @author Ivan Senic * */ @SuppressWarnings("PMD") public class TracerImplTest extends TestBase { TracerImpl tracer; @Mock Timer timer; @Mock Reporter reporter; @BeforeMethod public void init() { tracer = new TracerImpl(timer, reporter, false); } public static class Constructor extends TracerImplTest { @Test public void noArg() { tracer = new TracerImpl(); assertThat(tracer.getTimer(), is(not(nullValue()))); assertThat(TracerProvider.get(false), is(nullValue())); } @Test public void setToProvider() { tracer = new TracerImpl(timer, reporter, true); assertThat(tracer.getTimer(), is(not(nullValue()))); assertThat(TracerProvider.get(), is((ExtendedTracer) tracer)); } @Test(expectedExceptions = IllegalArgumentException.class) public void nullTimer() { new TracerImpl(null, reporter, false); } @Test(expectedExceptions = IllegalArgumentException.class) public void nullReporter() { new TracerImpl(timer, null, false); } } public static class BuildSpan extends TracerImplTest { @Test public void base() { long time = 122254L; when(timer.getCurrentTimeMicroseconds()).thenReturn(time); SpanBuilderImpl builder = tracer.buildSpan(); SpanImpl span = builder.start(); assertThat(span.getOperationName(), is(nullValue())); assertThat(span.getStartTimeMicros(), is(time)); assertThat(tracer.getCurrentContext(), is(span.context())); assertThat(tracer.isCurrentContextExisting(), is(true)); } @Test public void withOperationName() { long time = 122254L; when(timer.getCurrentTimeMicroseconds()).thenReturn(time); String operationName = "op"; SpanBuilderImpl builder = tracer.buildSpan(operationName); SpanImpl span = builder.start(); assertThat(span.getOperationName(), is(operationName)); assertThat(span.getStartTimeMicros(), is(time)); assertThat(tracer.getCurrentContext(), is(span.context())); assertThat(tracer.isCurrentContextExisting(), is(true)); } @Test public void withThreadContext() { long time = 122254L; when(timer.getCurrentTimeMicroseconds()).thenReturn(time); String operationName = "op"; String referenceType = References.FOLLOWS_FROM; SpanImpl first = tracer.buildSpan().start(); SpanBuilderImpl builder = tracer.buildSpan(operationName, referenceType, true); SpanImpl span = builder.start(); assertThat(span.getOperationName(), is(operationName)); assertThat(span.getStartTimeMicros(), is(time)); assertThat(span.context().getReferenceType(), is(referenceType)); assertThat(span.context().getTraceId(), is(first.context().getTraceId())); assertThat(span.context().getParentId(), is(first.context().getId())); assertThat(tracer.getCurrentContext(), is(span.context())); assertThat(tracer.isCurrentContextExisting(), is(true)); } @Test public void withoutThreadContext() { long time = 122254L; when(timer.getCurrentTimeMicroseconds()).thenReturn(time); String operationName = "op"; String referenceType = References.FOLLOWS_FROM; tracer.buildSpan().start(); SpanBuilderImpl builder = tracer.buildSpan(operationName, referenceType, false); SpanImpl span = builder.start(); assertThat(span.getOperationName(), is(operationName)); assertThat(span.getStartTimeMicros(), is(time)); assertThat(span.context().getReferenceType(), is(nullValue())); assertThat(span.context().getParentId(), is(span.context().getId())); assertThat(tracer.getCurrentContext(), is(span.context())); assertThat(tracer.isCurrentContextExisting(), is(true)); } } public static class Inject extends TracerImplTest { @Mock Propagator<TextMap> propagator; @Mock SpanContextImpl context; @Mock TextMap carrier; @Test public void happyPath() { tracer.registerPropagator(Format.Builtin.TEXT_MAP, propagator); tracer.inject(context, Format.Builtin.TEXT_MAP, carrier); verify(propagator).inject(context, carrier); verifyNoMoreInteractions(propagator); } @Test public void carrierNull() { tracer.registerPropagator(Format.Builtin.TEXT_MAP, propagator); tracer.inject(context, Format.Builtin.TEXT_MAP, null); verifyZeroInteractions(propagator); } @Test public void formatNull() { tracer.registerPropagator(Format.Builtin.TEXT_MAP, propagator); tracer.inject(context, null, carrier); verifyZeroInteractions(propagator); } @Test public void wrongContext() { tracer.registerPropagator(Format.Builtin.TEXT_MAP, propagator); tracer.inject(mock(SpanContext.class), Format.Builtin.TEXT_MAP, carrier); verifyZeroInteractions(propagator); } @Test public void nonExistingPropagator() { Format<String> format = new Format<String>() { }; String string = "test"; tracer.inject(context, format, string); } } public static class Extract extends TracerImplTest { @Mock Propagator<TextMap> propagator; @Mock SpanContextImpl context; @Mock TextMap carrier; @Test public void happyPath() { when(propagator.extract(carrier)).thenReturn(context); tracer.registerPropagator(Format.Builtin.TEXT_MAP, propagator); SpanContext extracted = tracer.extract(Format.Builtin.TEXT_MAP, carrier); assertThat(extracted, is((SpanContext) context)); verify(propagator).extract(carrier); verifyNoMoreInteractions(propagator); } @Test public void carrierNull() { tracer.registerPropagator(Format.Builtin.TEXT_MAP, propagator); SpanContext extracted = tracer.extract(Format.Builtin.TEXT_MAP, null); assertThat(extracted, is(nullValue())); verifyZeroInteractions(propagator); } @Test public void formatNull() { tracer.registerPropagator(Format.Builtin.TEXT_MAP, propagator); SpanContext extracted = tracer.extract(null, carrier); assertThat(extracted, is(nullValue())); verifyZeroInteractions(propagator); } @Test public void nonExistingPropagator() { Format<String> format = new Format<String>() { }; String string = "test"; SpanContext extracted = tracer.extract(format, string); assertThat(extracted, is(nullValue())); } } public static class SpanStarted extends TracerImplTest { @Test public void happyPath() { SpanImpl span = new SpanImpl(tracer); span.setSpanContext(SpanContextImpl.build()); tracer.spanStarted(span); assertThat(tracer.getCurrentContext(), is(span.context())); assertThat(tracer.isCurrentContextExisting(), is(true)); } @Test public void spanNull() { tracer.spanStarted(null); assertThat(tracer.getCurrentContext(), is(nullValue())); assertThat(tracer.isCurrentContextExisting(), is(false)); } } public static class SpanEnded extends TracerImplTest { @Test public void happyPath() { SpanImpl span = new SpanImpl(tracer); span.setSpanContext(SpanContextImpl.build()); tracer.spanStarted(span); tracer.spanEnded(span); assertThat(tracer.getCurrentContext(), is(nullValue())); assertThat(tracer.isCurrentContextExisting(), is(false)); verify(reporter).report(span); verifyNoMoreInteractions(reporter); } @Test public void spanNull() { SpanImpl span = new SpanImpl(tracer); span.setSpanContext(SpanContextImpl.build()); tracer.spanStarted(span); tracer.spanEnded(null); assertThat(tracer.getCurrentContext(), is(span.context())); assertThat(tracer.isCurrentContextExisting(), is(true)); verifyZeroInteractions(reporter); } @Test public void noReporting() { SpanImpl span = new SpanImpl(tracer); span.setSpanContext(SpanContextImpl.build()); span.setReport(false); tracer.spanStarted(span); tracer.spanEnded(span); assertThat(tracer.getCurrentContext(), is(nullValue())); assertThat(tracer.isCurrentContextExisting(), is(false)); verifyZeroInteractions(reporter); } @Test public void twoSpans() { SpanImpl span1 = new SpanImpl(tracer); span1.setSpanContext(SpanContextImpl.build()); SpanImpl span2 = new SpanImpl(tracer); span2.setSpanContext(SpanContextImpl.build()); tracer.spanStarted(span1); tracer.spanStarted(span2); tracer.spanEnded(span2); assertThat(tracer.getCurrentContext(), is(span1.context())); assertThat(tracer.isCurrentContextExisting(), is(true)); verify(reporter).report(span2); verifyNoMoreInteractions(reporter); } @Test public void twoSpansFirstEndsBeforeSecond() { SpanImpl span1 = new SpanImpl(tracer); span1.setSpanContext(SpanContextImpl.build()); SpanImpl span2 = new SpanImpl(tracer); span2.setSpanContext(SpanContextImpl.build()); tracer.spanStarted(span1); tracer.spanStarted(span2); tracer.spanEnded(span1); assertThat(tracer.getCurrentContext(), is(nullValue())); assertThat(tracer.isCurrentContextExisting(), is(false)); verify(reporter).report(span1); verifyNoMoreInteractions(reporter); } @Test public void twoSpansOneNotStarted() { SpanImpl span1 = new SpanImpl(tracer); span1.setSpanContext(SpanContextImpl.build()); SpanImpl span2 = new SpanImpl(tracer); span2.setSpanContext(SpanContextImpl.build()); tracer.spanStarted(span1); tracer.spanEnded(span2); assertThat(tracer.getCurrentContext(), is(span1.context())); assertThat(tracer.isCurrentContextExisting(), is(true)); verify(reporter).report(span2); verifyNoMoreInteractions(reporter); } } public static class SetTimer extends TracerImplTest { @Test(expectedExceptions = IllegalArgumentException.class) public void timerNull() { tracer.setTimer(null); } @Test public void set() { Timer t = mock(Timer.class); tracer.setTimer(t); assertThat(tracer.getTimer(), is(t)); } } }