package org.stagemonitor.tracing; import com.uber.jaeger.context.TracingUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.stagemonitor.configuration.ConfigurationOption; import org.stagemonitor.configuration.ConfigurationRegistry; import org.stagemonitor.core.CorePlugin; import org.stagemonitor.core.elasticsearch.ElasticsearchClient; import org.stagemonitor.core.metrics.MetricsReporterTestHelper; import org.stagemonitor.core.metrics.metrics2.Metric2Registry; import org.stagemonitor.tracing.reporter.ReportingSpanEventListener; import org.stagemonitor.tracing.sampling.SamplePriorityDeterminingSpanEventListener; import org.stagemonitor.tracing.utils.SpanUtils; import org.stagemonitor.tracing.wrapper.SpanWrappingTracer; import java.util.HashMap; import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.stagemonitor.core.metrics.metrics2.MetricName.name; public class MonitoredMethodExecutionTest { private SpanContextInformation spanContext1; private SpanContextInformation spanContext2; private SpanContextInformation spanContext3; private final Metric2Registry registry = new Metric2Registry(); private TestObject testObject; private ConfigurationRegistry configuration; private Map<String, Object> tags; @Before public void clearState() { CorePlugin corePlugin = mock(CorePlugin.class); TracingPlugin tracingPlugin = mock(TracingPlugin.class); when(tracingPlugin.getRateLimitServerSpansPerMinuteOption()).thenReturn(mock(ConfigurationOption.class)); when(tracingPlugin.getRateLimitClientSpansPerMinuteOption()).thenReturn(mock(ConfigurationOption.class)); when(tracingPlugin.getRateLimitClientSpansPerTypePerMinuteOption()).thenReturn(mock(ConfigurationOption.class)); when(tracingPlugin.getProfilerRateLimitPerMinuteOption()).thenReturn(mock(ConfigurationOption.class)); configuration = mock(ConfigurationRegistry.class); when(configuration.getConfig(CorePlugin.class)).thenReturn(corePlugin); when(configuration.getConfig(TracingPlugin.class)).thenReturn(tracingPlugin); when(corePlugin.isStagemonitorActive()).thenReturn(true); when(corePlugin.getThreadPoolQueueCapacityLimit()).thenReturn(1000); when(corePlugin.getMetricRegistry()).thenReturn(registry); when(corePlugin.getElasticsearchClient()).thenReturn(mock(ElasticsearchClient.class)); spanContext1 = spanContext2 = spanContext3 = null; final RequestMonitor requestMonitor = new RequestMonitor(configuration, registry); when(tracingPlugin.getRequestMonitor()).thenReturn(requestMonitor); tags = new HashMap<>(); final SpanWrappingTracer tracer = TracingPlugin.createSpanWrappingTracer(new MockTracer(), configuration, registry, TagRecordingSpanEventListener.asList(tags), new SamplePriorityDeterminingSpanEventListener(configuration), new ReportingSpanEventListener(configuration)); when(tracingPlugin.getTracer()).thenReturn(tracer); testObject = new TestObject(requestMonitor); assertTrue(TracingUtils.getTraceContext().isEmpty()); } @After public void tearDown() throws Exception { assertTrue(TracingUtils.getTraceContext().isEmpty()); } @Test public void testDoubleForwarding() throws Exception { testObject.monitored1(); assertEquals("monitored1()", spanContext1.getOperationName()); assertEquals(tags.toString(), "1", tags.get(SpanUtils.PARAMETERS_PREFIX + "arg0")); assertEquals(tags.toString(), "test", tags.get(SpanUtils.PARAMETERS_PREFIX + "arg1")); assertNotNull(registry.getTimers().get(name("response_time_server").tag("request_name", "monitored1()").layer("All").build())); assertNotNull(registry.getTimers().get(name("response_time_server").tag("request_name", "monitored2()").layer("All").build())); assertNotNull(registry.getTimers().get(name("response_time_server").tag("request_name", "monitored3()").layer("All").build())); assertNull(registry.getTimers().get(name("response_time_server").tag("request_name", "notMonitored()").layer("All").build())); } @Test public void testNormalForwarding() throws Exception { testObject.monitored3(); assertNull(registry.getTimers().get(name("response_time_server").tag("request_name", "monitored1()").layer("All").build())); assertNull(registry.getTimers().get(name("response_time_server").tag("request_name", "monitored2()").layer("All").build())); assertNotNull(registry.getTimers().get(name("response_time_server").tag("request_name", "monitored3()").layer("All").build())); assertNull(registry.getTimers().get(name("response_time_server").tag("request_name", "notMonitored()").layer("All").build())); } private class TestObject { private final RequestMonitor requestMonitor; private TestObject(RequestMonitor requestMonitor) { this.requestMonitor = requestMonitor; } private void monitored1() throws Exception { spanContext1 = requestMonitor.monitor( new MonitoredMethodRequest(configuration, "monitored1()", this::monitored2, MetricsReporterTestHelper.<String, Object>map("arg0", 1).add("arg1", "test"))); } private void monitored2() throws Exception { spanContext2 = requestMonitor.monitor( new MonitoredMethodRequest(configuration, "monitored2()", this::monitored3)); } private void monitored3() throws Exception { spanContext3 = requestMonitor.monitor( new MonitoredMethodRequest(configuration, "monitored3()", this::notMonitored)); } private int notMonitored() { return 1; } } }