org.apache.accumulo.tracer.TracerTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.accumulo.tracer.TracerTest.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.accumulo.tracer;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.accumulo.core.trace.Span;
import org.apache.accumulo.core.trace.Trace;
import org.apache.accumulo.core.trace.thrift.TInfo;
import org.apache.accumulo.core.trace.wrappers.TraceWrap;
import org.apache.accumulo.tracer.thrift.TestService;
import org.apache.accumulo.tracer.thrift.TestService.Iface;
import org.apache.accumulo.tracer.thrift.TestService.Processor;
import org.apache.htrace.HTraceConfiguration;
import org.apache.htrace.Sampler;
import org.apache.htrace.SpanReceiver;
import org.apache.htrace.wrappers.TraceProxy;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.junit.Before;
import org.junit.Test;

public class TracerTest {
    static class SpanStruct {
        public SpanStruct(long traceId, long spanId, long parentId, long start, long stop, String description,
                Map<byte[], byte[]> data) {
            super();
            this.traceId = traceId;
            this.spanId = spanId;
            this.parentId = parentId;
            this.start = start;
            this.stop = stop;
            this.description = description;
            this.data = data;
        }

        public long traceId;
        public long spanId;
        public long parentId;
        public long start;
        public long stop;
        public String description;
        public Map<byte[], byte[]> data;

        public long millis() {
            return stop - start;
        }
    }

    static class TestReceiver implements SpanReceiver {
        public Map<Long, List<SpanStruct>> traces = new HashMap<>();

        public TestReceiver() {
        }

        public TestReceiver(HTraceConfiguration conf) {
        }

        @Override
        public void receiveSpan(org.apache.htrace.Span s) {
            long traceId = s.getTraceId();
            SpanStruct span = new SpanStruct(traceId, s.getSpanId(), s.getParentId(), s.getStartTimeMillis(),
                    s.getStopTimeMillis(), s.getDescription(), s.getKVAnnotations());
            if (!traces.containsKey(traceId))
                traces.put(traceId, new ArrayList<SpanStruct>());
            traces.get(traceId).add(span);
        }

        @Override
        public void close() throws IOException {
        }
    }

    @SuppressWarnings("deprecation")
    @Test
    public void testTrace() throws Exception {
        TestReceiver tracer = new TestReceiver();
        org.apache.htrace.Trace.addReceiver(tracer);

        assertFalse(Trace.isTracing());
        Trace.start("nop").stop();
        assertTrue(tracer.traces.size() == 0);
        assertFalse(Trace.isTracing());

        Trace.on("nop").stop();
        assertTrue(tracer.traces.size() == 1);
        assertFalse(Trace.isTracing());

        Span start = Trace.on("testing");
        assertEquals(Trace.currentTrace().getSpan(), start.getScope().getSpan());
        assertTrue(Trace.isTracing());

        Span span = Trace.start("shortest trace ever");
        span.stop();
        long traceId = Trace.currentTraceId();
        assertNotNull(tracer.traces.get(traceId));
        assertTrue(tracer.traces.get(traceId).size() == 1);
        assertEquals("shortest trace ever", tracer.traces.get(traceId).get(0).description);

        Span pause = Trace.start("pause");
        Thread.sleep(100);
        pause.stop();
        assertTrue(tracer.traces.get(traceId).size() == 2);
        assertTrue(tracer.traces.get(traceId).get(1).millis() >= 100);

        Thread t = new Thread(Trace.wrap(new Runnable() {
            @Override
            public void run() {
                assertTrue(Trace.isTracing());
            }
        }), "My Task");
        t.start();
        t.join();

        assertTrue(tracer.traces.get(traceId).size() == 3);
        assertEquals("My Task", tracer.traces.get(traceId).get(2).description);
        Trace.off();
        assertFalse(Trace.isTracing());
    }

    static class Service implements TestService.Iface {
        @Override
        public boolean checkTrace(TInfo t, String message) throws TException {
            Span trace = Trace.start(message);
            try {
                return Trace.isTracing();
            } finally {
                trace.stop();
            }
        }
    }

    @Test
    public void testThrift() throws Exception {
        TestReceiver tracer = new TestReceiver();
        org.apache.htrace.Trace.addReceiver(tracer);

        ServerSocket socket = new ServerSocket(0);
        TServerSocket transport = new TServerSocket(socket);
        transport.listen();
        TThreadPoolServer.Args args = new TThreadPoolServer.Args(transport);
        args.processor(new Processor<Iface>(TraceWrap.service(new Service())));
        final TServer tserver = new TThreadPoolServer(args);
        Thread t = new Thread() {
            @Override
            public void run() {
                tserver.serve();
            }
        };
        t.start();
        TTransport clientTransport = new TSocket(new Socket("localhost", socket.getLocalPort()));
        TestService.Iface client = new TestService.Client(new TBinaryProtocol(clientTransport),
                new TBinaryProtocol(clientTransport));
        client = TraceWrap.client(client);
        assertFalse(client.checkTrace(null, "test"));

        Span start = Trace.on("start");
        assertTrue(client.checkTrace(null, "my test"));
        start.stop();

        assertNotNull(tracer.traces.get(start.traceId()));
        String traces[] = { "my test", "checkTrace", "client:checkTrace", "start" };
        assertTrue(tracer.traces.get(start.traceId()).size() == traces.length);
        for (int i = 0; i < traces.length; i++)
            assertEquals(traces[i], tracer.traces.get(start.traceId()).get(i).description);

        tserver.stop();
        t.join(100);
    }

    Callable<Object> callable;

    @Before
    public void setup() {
        callable = new Callable<Object>() {
            @Override
            public Object call() throws IOException {
                throw new IOException();
            }
        };
    }

    /**
     * Verify that exceptions propagate up through the trace wrapping with sampling enabled, as the cause of the reflexive exceptions.
     */
    @Test(expected = IOException.class)
    public void testTracedException() throws Throwable {
        try {
            TraceProxy.trace(callable).call();
        } catch (InvocationTargetException e) {
            throw e.getCause();
        }
    }

    /**
     * Verify that exceptions propagate up through the trace wrapping with sampling disabled, as the cause of the reflexive exceptions.
     */
    @Test(expected = IOException.class)
    public void testUntracedException() throws Throwable {
        try {
            TraceProxy.trace(callable, Sampler.NEVER).call();
        } catch (InvocationTargetException e) {
            throw e.getCause();
        }
    }
}