All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.undefinedlabs.scope.rules.AbstractScopeAgentRuleTest Maven / Gradle / Ivy

package com.undefinedlabs.scope.rules;

import com.undefinedlabs.scope.ScopeTracer;
import com.undefinedlabs.scope.coverage.GlobalCoverageReporter;
import com.undefinedlabs.scope.coverage.reporter.impl.CoverageReporterImpl;
import com.undefinedlabs.scope.logger.FileScopeLogger;
import com.undefinedlabs.scope.logger.ScopeLogger;
import com.undefinedlabs.scope.reporter.internal.RemoteReporter;
import com.undefinedlabs.scope.reporter.internal.remote.model.ScopeEvent;
import com.undefinedlabs.scope.reporter.internal.remote.model.ScopeSpan;
import com.undefinedlabs.scope.sender.Sender;
import com.undefinedlabs.scope.sender.internal.OkHttpSender;
import com.undefinedlabs.scope.utils.event.EventKeys;
import com.undefinedlabs.scope.utils.event.EventValues;
import com.undefinedlabs.scope.utils.tag.TagKeys;
import com.undefinedlabs.scope.utils.tag.TagValues;
import io.grpc.Server;
import io.grpc.Status;
import io.opentracing.Span;
import io.opentracing.Tracer;
import io.opentracing.tag.Tags;
import io.opentracing.util.GlobalTracer;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.slf4j.Logger;

import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Field;
import java.net.ServerSocket;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.mockito.Mockito.spy;

public abstract class AbstractScopeAgentRuleTest {

    //protected static final ScopeLogger LOGGER = ScopeLoggerResolver.INSTANCE.get();

    private static final String SAMPLE_API_KEY = "sampleApiKey";
    private static final String SAMPLE_PREVIOUS_SPAN = "samplePreviousSpan";
    private Span previousSpan;

    static {
        ScopeMockWebServer.start();

        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run(){
                GlobalTracer.get().close();
                ScopeMockWebServer.shutdown();
            }
        });
    }

    @BeforeClass
    public static void staticSetup() {
        if(!GlobalTracer.isRegistered()) {
            final Sender mockSender = spy(OkHttpSender.Builder.newDefault(ScopeMockWebServer.url(""), SAMPLE_API_KEY).build());

            final Tracer scopeTracer = ScopeTracer.Builder.newDefault()
                    .withReporter(RemoteReporter.Builder.newDefault()
                            .withFlushInterval(Integer.MAX_VALUE)
                            .withSender(mockSender)
                            .build())
                    .build();

            GlobalTracer.registerIfAbsent(scopeTracer);
        }

        if(!GlobalCoverageReporter.isRegistered()) {
            GlobalCoverageReporter.registerIfAbsent(CoverageReporterImpl.Builder.newDefault().build());
        }
    }

    protected static Sender flushGlobalTracer() throws IllegalAccessException, InterruptedException, ExecutionException, TimeoutException {
        final GlobalTracer globalTracer = (GlobalTracer) GlobalTracer.get();
        final Field tracer = FieldUtils.getField(GlobalTracer.class, "tracer", true);
        final ScopeTracer scopeTracer = (ScopeTracer) tracer.get(globalTracer);
        ((RemoteReporter) scopeTracer.reporter()).flush().get(10, TimeUnit.SECONDS);

        return ((RemoteReporter) scopeTracer.reporter()).sender();
    }

    protected abstract List getTransformers();

    protected abstract boolean mustCreatePreviousSpan();

    protected static Server startGrpcMockServer(final Server server) {
        try {
            return server.start();
        } catch(IOException e){
            throw new RuntimeException(e);
        }
    }

    protected static boolean shutdownGrpcMockServer(final Server server) {
        try {
            server.shutdown();
            return server.awaitTermination(10, TimeUnit.SECONDS);
        } catch(InterruptedException e) {
            throw new RuntimeException(e);
        }
    }


    @Before
    public void setup() {
        if(mustCreatePreviousSpan()){
            final Tracer tracer = GlobalTracer.get();
            this.previousSpan = tracer.buildSpan(SAMPLE_PREVIOUS_SPAN).ignoreActiveSpan().start();
            tracer.activateSpan(previousSpan);
        }
    }

    @After
    public void finish() {
        if(mustCreatePreviousSpan() && this.previousSpan != null) {
            this.previousSpan.finish();
        }
    }

    protected void instrumentedTracing(final Runnable testLogicExecution) {
        assertThat(ByteBuddyAgent.install()).isInstanceOf(Instrumentation.class);
        final List transformers = getTransformers();

        try {
            //Then
            testLogicExecution.run();

        } finally {
            for (ClassFileTransformer transformer : transformers) {
                ByteBuddyAgent.getInstrumentation().removeTransformer(transformer);
            }
        }
    }

    protected static Map intoSpanMapBasedOnOperationNames(Collection scopeSpans) {
        final Map scopeSpansMap = new HashMap<>();

        for(ScopeSpan scopeSpan : scopeSpans) {
            scopeSpansMap.put(scopeSpan.getOperation(), scopeSpan);
        }

        return Collections.unmodifiableMap(scopeSpansMap);
    }

    protected static Map> intoEventsMapBasedOnSpanId(final Collection scopeEvents) {
        final Map> scopeEventsBySpanId = new HashMap<>();

        for(ScopeEvent scopeEvent : scopeEvents) {
            if (scopeEventsBySpanId.get(scopeEvent.getContext().getSpanId()) == null) {
                scopeEventsBySpanId.put(scopeEvent.getContext().getSpanId(), new ArrayList<>(Collections.singletonList(scopeEvent)));
            }else {
                scopeEventsBySpanId.get(scopeEvent.getContext().getSpanId()).add(scopeEvent);
            }
        }

        return Collections.unmodifiableMap(scopeEventsBySpanId);
    }

    protected List instrumentAgentBuilders(final AbstractScopeAgentRule rule) {
        final List transformers = new ArrayList<>();
        final Iterable agentBuilders = rule.transformers();
        for(final AgentBuilder agentBuilder : agentBuilders) {
            transformers.add(agentBuilder.installOnByteBuddyAgent());
        }
        return transformers;
    }

    protected static void sleep(final long millis) {
        try {
            Thread.sleep(millis);
        } catch(InterruptedException e) {
            throw new RuntimeException(e);
        }
    }


    protected static void assertHttpSpanError(ScopeSpan span) {
        if(span == null){
            return;
        }

        assertHttpSpan(span);
        assertThat(span.getTags().get(TagKeys.ERROR)).isEqualTo(true);
    }

    protected static void assertHttpSpan(ScopeSpan span) {
        if(span == null){
            return;
        }

        final Map tags = span.getTags();
        assertThat(tags.get(TagKeys.COMPONENT)).isNotNull();
        assertThat(tags.get(TagKeys.SPAN_KIND)).isNotNull();
        assertThat(tags.get(TagKeys.Network.HTTP_URL)).isNotNull();
        assertThat(tags.get(TagKeys.Network.HTTP_METHOD)).isNotNull();
        assertThat(tags.get(TagKeys.Network.PEER_HOSTNAME)).isNotNull();
        assertThat(tags.get(TagKeys.Network.PEER_PORT)).isNotNull();
        assertThat(tags.get(TagKeys.Network.PEER_SERVICE)).isEqualTo(TagValues.Network.Service.HTTP);
    }


    protected static void assertHttpSpanSuccess(ScopeSpan span) {
        if(span == null){
            return;
        }

        assertHttpSpan(span);
        assertThat(span.getTags().get(TagKeys.Network.HTTP_STATUS_CODE)).isNotNull();
    }

    protected static void assertThatErrorSpanEvents(List scopeEvents) {
        assertThat(scopeEvents).isNotNull().hasSize(1);

        final ScopeEvent scopeEvent = scopeEvents.get(0);
        assertThat(scopeEvent.getFields().get(EventKeys.General.EVENT)).isEqualTo(EventValues.Test.TEST_ERROR);
        assertThat(scopeEvent.getFields().get(EventKeys.General.EXCEPTION)).isNotNull();
        assertThat(scopeEvent.getFields().get(EventKeys.General.SOURCE)).isNotNull();
    }

    protected static void assertThatSucceedSpanEvents(List scopeEvents) {
        assertThat(scopeEvents).isNull();
    }


    protected static void assertDBSpan(ScopeSpan scopeSpan) {
        if(SAMPLE_PREVIOUS_SPAN.equalsIgnoreCase(scopeSpan.getOperation())){
            return;
        }

        assertThat(scopeSpan.getTags().get(TagKeys.COMPONENT)).isEqualTo(TagValues.Component.SQL);
        assertThat(scopeSpan.getTags().get(TagKeys.DB.DB_CONNECTION)).isNotNull();
        assertThat(scopeSpan.getTags().get(TagKeys.DB.DB_TYPE)).isNotNull();
        assertThat(scopeSpan.getTags().get(TagKeys.DB.DB_USER)).isNotNull();
        assertThat(scopeSpan.getTags().get(TagKeys.DB.DB_INSTANCE)).isNotNull();
        assertThat(scopeSpan.getTags().get(TagKeys.DB.DB_STATEMENT)).isNotNull();
        assertThat(scopeSpan.getTags().get(TagKeys.DB.DB_PRODUCT_NAME)).isNotNull();
        assertThat(scopeSpan.getTags().get(TagKeys.DB.DB_PRODUCT_VERSION)).isNotNull();
        assertThat(scopeSpan.getTags().get(TagKeys.DB.DB_DRIVER_NAME)).isNotNull();
        assertThat(scopeSpan.getTags().get(TagKeys.DB.DB_DRIVER_VERSION)).isNotNull();
        assertThat(scopeSpan.getTags().get(TagKeys.Network.PEER_SERVICE)).isNotNull();
    }

    protected static void assertGrpcFailedEvents(List events) {
        assertThat(events).isNotNull().isNotEmpty();

        for(ScopeEvent event : events) {
            assertThat(event.getFields().get(EventKeys.General.EVENT)).isNotNull();
            assertThat(event.getFields().get(EventKeys.General.MESSAGE)).isNotNull();
        }
    }

    protected static void assertGrpcSuccessEvents(List events) {
        assertThat(events).isNotNull().isNotEmpty();

        for(ScopeEvent event : events) {
            assertThat(event.getFields().get(EventKeys.General.EVENT)).isNotNull().isNotEqualTo(EventValues.General.ERROR);
            assertThat(event.getFields().get(EventKeys.General.MESSAGE)).isNotNull();
        }
    }

    protected static void assertGrpcServerFailureSpan(ScopeSpan span) {
        assertThat(span).isNotNull();

        final Map tags = span.getTags();
        assertThat(tags.get(TagKeys.SPAN_KIND)).isNotNull();
        assertThat(tags.get(TagKeys.COMPONENT)).isEqualTo(TagValues.Component.GRPC);
        assertThat(tags.get(TagKeys.Network.PEER_SERVICE)).isEqualTo(TagValues.Network.Service.RPC);
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_METHOD_NAME)).isNotNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_METHOD_TYPE)).isNotNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_STATUS)).isEqualTo(Status.INTERNAL.getCode().name());
        assertThat(tags.get(TagKeys.ERROR)).isEqualTo(true);

    }

    protected static void assertGrpcClientFailureSpan(ScopeSpan span) {
        assertThat(span).isNotNull();

        final Map tags = span.getTags();
        assertThat(tags.get(TagKeys.SPAN_KIND)).isEqualTo(Tags.SPAN_KIND_CLIENT);
        assertThat(tags.get(TagKeys.COMPONENT)).isEqualTo(TagValues.Component.GRPC);
        assertThat(tags.get(TagKeys.Network.PEER_SERVICE)).isEqualTo(TagValues.Network.Service.RPC);
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_METHOD_NAME)).isNotNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_METHOD_TYPE)).isNotNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_AUTHORITY)).isNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_COMPRESSOR)).isNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_DEADLINE)).isNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_MAX_INBOUND_MESSAGE_SIZE)).isNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_MAX_OUTBOUND_MESSAGE_SIZE)).isNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_STREAM_TRACER_FACTORIES)).isNotNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_STATUS)).isEqualTo(Status.INTERNAL.getCode().name());
        assertThat(tags.get(TagKeys.ERROR)).isEqualTo(true);

    }

    protected static void assertGrpcServerSuccessSpan(ScopeSpan span) {
        assertThat(span).isNotNull();

        final Map tags = span.getTags();
        assertThat(tags.get(TagKeys.SPAN_KIND)).isEqualTo(Tags.SPAN_KIND_SERVER);
        assertThat(tags.get(TagKeys.COMPONENT)).isEqualTo(TagValues.Component.GRPC);
        assertThat(tags.get(TagKeys.Network.PEER_SERVICE)).isEqualTo(TagValues.Network.Service.RPC);
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_METHOD_NAME)).isNotNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_METHOD_TYPE)).isNotNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_STATUS)).isEqualTo(Status.OK.getCode().name());
        assertThat(tags.get(TagKeys.ERROR)).isNull();
    }

    protected static void assertGrpcClientSuccessSpan(ScopeSpan span) {
        assertThat(span).isNotNull();

        final Map tags = span.getTags();
        assertThat(tags.get(TagKeys.SPAN_KIND)).isEqualTo(Tags.SPAN_KIND_CLIENT);
        assertThat(tags.get(TagKeys.COMPONENT)).isEqualTo(TagValues.Component.GRPC);
        assertThat(tags.get(TagKeys.Network.PEER_SERVICE)).isEqualTo(TagValues.Network.Service.RPC);
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_METHOD_NAME)).isNotNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_METHOD_TYPE)).isNotNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_AUTHORITY)).isNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_COMPRESSOR)).isNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_DEADLINE)).isNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_MAX_INBOUND_MESSAGE_SIZE)).isNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_MAX_OUTBOUND_MESSAGE_SIZE)).isNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_STREAM_TRACER_FACTORIES)).isNotNull();
        assertThat(tags.get(TagKeys.Network.Grpc.GRPC_STATUS)).isEqualTo(Status.OK.getCode().name());
        assertThat(tags.get(TagKeys.ERROR)).isNull();
    }

    protected static void assertJMSFailureSpan(ScopeSpan scopeSpan) {
        assertJMSCommonSpan(scopeSpan);
        assertThat(scopeSpan.getTags().get(TagKeys.ERROR)).isEqualTo(true);
    }

    protected static void assertJMSSuccessSpan(ScopeSpan scopeSpan) {
        assertJMSCommonSpan(scopeSpan);

        assertThat(scopeSpan.getTags().get(TagKeys.Network.Messaging.MESSAGE_BUS_ID)).isNotNull();
        assertThat(scopeSpan.getTags().get(TagKeys.Network.Messaging.MESSAGE_BUS_EXPIRATION)).isNotNull();
        assertThat(scopeSpan.getTags().get(TagKeys.Network.Messaging.MESSAGE_BUS_DELIVERY_TIME)).isNotNull();
    }

    protected static void assertJMSCommonSpan(ScopeSpan scopeSpan) {
        assertThat(scopeSpan).isNotNull();

        final Map tags = scopeSpan.getTags();
        assertThat(tags.get(TagKeys.SPAN_KIND)).isNotNull();
        assertThat(tags.get(TagKeys.COMPONENT)).isEqualTo(TagValues.Component.JMS);
    }

    protected static Collection selectSpanKind(List scopeSpans, String spanKindValue) {
        final Set selectedSpans = new HashSet<>();
        for(final ScopeSpan scopeSpan : scopeSpans) {
            if(spanKindValue.equalsIgnoreCase((String) scopeSpan.getTags().get(TagKeys.SPAN_KIND))) {
                selectedSpans.add(scopeSpan);
            }
        }
        return selectedSpans;
    }


    protected int getAvailablePort() {
        try(final ServerSocket serverSocket = new ServerSocket(0)) {
            return serverSocket.getLocalPort();
        } catch(Exception e){
            throw new RuntimeException(e);
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy