package org.stagemonitor.tracing.elasticsearch; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatchers; import org.mockito.Mockito; import org.stagemonitor.core.util.JsonUtils; import org.stagemonitor.tracing.SpanContextInformation; import org.stagemonitor.tracing.reporter.ReadbackSpan; import org.stagemonitor.tracing.reporter.SpanReporter; import org.stagemonitor.tracing.utils.SpanUtils; import org.stagemonitor.util.StringUtils; import java.util.ArrayList; import java.util.List; import java.util.ServiceLoader; import io.opentracing.tag.Tags; import static org.junit.Assert.assertEquals; public class ElasticsearchSpanReporterTest extends AbstractElasticsearchSpanReporterTest { private ElasticsearchSpanReporter reporter; @Override @Before public void setUp() throws Exception { super.setUp(); reporter = new ElasticsearchSpanReporter(spanLogger); reporter.init(configuration); JsonUtils.getMapper().registerModule(new ReadbackSpan.SpanJsonModule()); reportingSpanEventListener.addReporter(reporter); } @Test public void testReportSpan() throws Exception { final SpanContextInformation spanContext = reportSpanWithCallTree(1000, "Report Me"); Mockito.verify(elasticsearchClient).index(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.any()); Assert.assertTrue(reporter.isActive(spanContext)); } @Test public void testLogReportSpan() throws Exception { Mockito.when(elasticsearchTracingPlugin.isOnlyLogElasticsearchSpanReports()).thenReturn(true); final SpanContextInformation spanContext = reportSpanWithCallTree(1000, "Report Me"); Mockito.verify(elasticsearchClient, Mockito.times(0)).index(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.any()); Mockito.verify(spanLogger).info(ArgumentMatchers.startsWith("{\"index\":{\"_index\":\"stagemonitor-spans-" + StringUtils.getLogstashStyleDate() + "\",\"_type\":\"spans\"}}\n")); Assert.assertTrue(reporter.isActive(spanContext)); } @Test public void testReportSpanDontReport() throws Exception { final SpanContextInformation info = reportSpanWithCallTree(1, "Regular Foo"); Assert.assertTrue(reporter.isActive(info)); Assert.assertFalse(info.isSampled()); assertEquals((short) 0, tags.get(Tags.SAMPLING_PRIORITY.getKey())); } @Test public void testElasticsearchExcludeCallTree() throws Exception { Mockito.when(tracingPlugin.getExcludeCallTreeFromReportWhenFasterThanXPercentOfRequests()).thenReturn(1d); reportSpanWithCallTree(1000, "Report Me"); reportSpanWithCallTree(500, "Report Me"); reportSpanWithCallTree(250, "Report Me"); ArgumentCaptor<ReadbackSpan> spanCaptor = ArgumentCaptor.forClass(ReadbackSpan.class); Mockito.verify(elasticsearchClient, Mockito.times(3)).index(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), spanCaptor.capture()); ReadbackSpan span = spanCaptor.getValue(); Assert.assertNull(span.getTags().get(SpanUtils.CALL_TREE_ASCII)); Assert.assertNull(span.getTags().get(SpanUtils.CALL_TREE_JSON)); } @Test public void testElasticsearchDontExcludeCallTree() throws Exception { Mockito.when(tracingPlugin.getExcludeCallTreeFromReportWhenFasterThanXPercentOfRequests()).thenReturn(0d); reportSpanWithCallTree(250, "Report Me"); reportSpanWithCallTree(500, "Report Me"); reportSpanWithCallTree(1000, "Report Me"); ArgumentCaptor<ReadbackSpan> spanCaptor = ArgumentCaptor.forClass(ReadbackSpan.class); Mockito.verify(elasticsearchClient, Mockito.times(3)).index(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), spanCaptor.capture()); verifyContainsCallTree(spanCaptor.getValue(), true); } private void verifyContainsCallTree(ReadbackSpan span, boolean contains) { assertEquals(contains, span.getTags().get(SpanUtils.CALL_TREE_ASCII) != null); assertEquals(contains, span.getTags().get(SpanUtils.CALL_TREE_JSON) != null); } @Test public void testElasticsearchExcludeFastCallTree() throws Exception { Mockito.when(tracingPlugin.getExcludeCallTreeFromReportWhenFasterThanXPercentOfRequests()).thenReturn(0.85d); SpanContextInformation spanContext = reportSpanWithCallTree(1000, "Report Me"); Assert.assertFalse(spanContext.getPostExecutionInterceptorContext().isExcludeCallTree()); verifyContainsCallTree(spanContext.getReadbackSpan(), true); spanContext = reportSpanWithCallTree(250, "Report Me"); Assert.assertTrue(spanContext.getPostExecutionInterceptorContext().isExcludeCallTree()); verifyContainsCallTree(spanContext.getReadbackSpan(), false); } @Test public void testElasticsearchDontExcludeSlowCallTree() throws Exception { Mockito.when(tracingPlugin.getExcludeCallTreeFromReportWhenFasterThanXPercentOfRequests()).thenReturn(0.85d); reportSpanWithCallTree(250, "Report Me"); reportSpanWithCallTree(1000, "Report Me"); Mockito.verify(elasticsearchClient, Mockito.times(2)).index(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.isA(ReadbackSpan.class)); } @Test public void testInterceptorServiceLoader() throws Exception { Mockito.when(tracingPlugin.getExcludeCallTreeFromReportWhenFasterThanXPercentOfRequests()).thenReturn(0d); reportSpanWithCallTree(250, "Report Me"); ArgumentCaptor<ReadbackSpan> spanCaptor = ArgumentCaptor.forClass(ReadbackSpan.class); Mockito.verify(elasticsearchClient).index(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), spanCaptor.capture()); ReadbackSpan span = spanCaptor.getValue(); Assert.assertTrue((Boolean) span.getTags().get("serviceLoaderWorks")); } @Test public void testLoadedViaServiceLoader() throws Exception { List<Class<? extends SpanReporter>> spanReporters = new ArrayList<>(); ServiceLoader.load(SpanReporter.class).forEach(reporter -> spanReporters.add(reporter.getClass())); Assert.assertTrue(spanReporters.contains(ElasticsearchSpanReporter.class)); } }