/*
* Copyright 2015 NAVER Corp.
*
* Licensed 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 com.navercorp.pinpoint.web.calltree.span;
import static org.junit.Assert.assertEquals;
import org.apache.commons.collections.CollectionUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* @author jaehong.kim
*/
public class CallTreeIteratorTest {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private static final boolean SYNC = false;
private static final boolean ASYNC = true;
private static final long START_TIME = 1430983914531L;
private static final int ELAPSED = 10;
private CallTreeFactory factory = new CallTreeFactory();
@Test
public void internal00() {
// current is internal, prev is internal
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 1);
callStack.add("####", 3, 1, 1);
callStack.add("#####", 4, 1, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void internal01() {
// current is internal, prev is internal
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 1);
callStack.add("####", 3, 1, 1);
callStack.add("####", 3, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void internal02() {
// current is internal, prev is internal
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 1);
callStack.add("####", 3, 1, 1);
callStack.add("###", 2, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void internal03() {
// current is internal, prev is internal
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 1);
callStack.add("####", 3, 1, 1);
callStack.add("##", 1, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void internal10() {
// current is internal, prev is remote
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 3);
callStack.add("RRRR", 3, 1, 1);
callStack.add("#####", 4, 1, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void internal11() {
// current is internal, prev is remote
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 2);
callStack.add("RRRR", 3, 1, 1);
callStack.add("####", 3, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void internal12() {
// current is internal, prev is remote
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 2);
callStack.add("RRRR", 3, 1, 1);
callStack.add("###", 2, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void internal13() {
// current is internal, prev is remote
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 2);
callStack.add("RRRR", 3, 1, 1);
callStack.add("##", 1, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void internal20() {
// current is internal, prev is async
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 4);
callStack.add("AAAA", 3, 2, 1);
callStack.add("#####", 4, 1, 1);
callStack.add("####", 3, 4, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void internal21() {
// current is internal, prev is async
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 4);
callStack.add("AAAA", 3, 2, 1);
callStack.add("#####", 4, 1, 1);
callStack.add("###", 2, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void internal22() {
// current is internal, prev is async
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 4);
callStack.add("AAAA", 3, 2, 1);
callStack.add("#####", 4, 1, 1);
callStack.add("##", 1, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void remote00() {
// current is remote, prev is internal
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 6);
callStack.add("RRRR", 3, 1, 1); // check
callStack.add("#####", 4, 1, 4);
callStack.add("RRRRRR", 5, 1, 1); // check
callStack.add("#######", 6, 1, 2);
callStack.add("RRRRRRRR", 7, 1, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void remote01() {
// current is remote, prev is internal
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 2);
callStack.add("####", 3, 1, 1);
callStack.add("RRRR", 3, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void remote02() {
// current is remote, prev is internal
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 2);
callStack.add("###", 2, 1, 1);
callStack.add("####", 3, 1, 1);
callStack.add("RRR", 2, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void remote03() {
// current is remote, prev is internal
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 2);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 1);
callStack.add("####", 3, 1, 1);
callStack.add("RR", 1, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void remote10() {
// current is remote, prev is async
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 5);
callStack.add("AAAA", 3, 2, 1);
callStack.add("#####", 4, 1, 2);
callStack.add("RRRRRR", 5, 1, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void remote11() {
// current is remote, prev is async
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 5);
callStack.add("AAAA", 3, 2, 2);
callStack.add("#####", 4, 1, 1);
callStack.add("RRRRR", 4, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void remote12() {
// current is remote, prev is async
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 5);
callStack.add("AAAA", 3, 2, 1);
callStack.add("#####", 4, 1, 1);
callStack.add("RRRR", 3, 4, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void remote13() {
// current is remote, prev is async
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 2);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 4);
callStack.add("AAAA", 3, 2, 1);
callStack.add("#####", 4, 1, 1);
callStack.add("RR", 1, 0, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void async00() {
// current is async, prev is internal
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 1);
callStack.add("####", 3, 1, 3);
callStack.add("AAAAA", 4, 2, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void async01() {
// current is async, prev is internal
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 3);
callStack.add("####", 3, 1, 1);
callStack.add("AAAA", 3, 3, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void async02() {
// current is async, prev is internal
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 3);
callStack.add("###", 2, 1, 1);
callStack.add("####", 3, 1, 1);
callStack.add("AAA", 2, 4, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void async10() {
// current is async, prev is remote
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 5);
callStack.add("RRRR", 3, 1, 1);
callStack.add("#####", 4, 1, 3);
callStack.add("AAAAAA", 5, 2, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void async11() {
// current is async, prev is remote
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 6);
callStack.add("RRRR", 3, 1, 1);
callStack.add("#####", 4, 1, 3);
callStack.add("######", 5, 1, 1);
callStack.add("AAAAAA", 5, 3, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void async12() {
// current is async, prev is remote
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 4);
callStack.add("RRRR", 3, 1, 1);
callStack.add("AAAA", 3, 3, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void async13() {
// current is async, prev is remote
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 3);
callStack.add("###", 2, 1, 2);
callStack.add("RRRR", 3, 1, 1);
callStack.add("AAA", 2, 4, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void async20() {
// current is async, prev is async
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 5);
callStack.add("AAAA", 3, 2, 3);
callStack.add("AAAAA", 4, 2, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void async21() {
// current is async, prev is async
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 1);
callStack.add("###", 2, 1, 3);
callStack.add("AAAA", 3, 2, 1);
callStack.add("###", 2, 0, 3);
callStack.add("AAAA", 3, 2, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
@Test
public void async22() {
// current is async, prev is async
CallStackDummy callStack = new CallStackDummy();
callStack.add("R", 0, 0, 1);
callStack.add("##", 1, 1, 3);
callStack.add("###", 2, 1, 3);
callStack.add("AAAA", 3, 2, 1);
callStack.add("AAA", 2, 5, 1); // check
CallTree callTree = factory.get(callStack.getEvents());
assertCallTree(callTree, callStack.getDepths(), callStack.getGaps(), callStack.getExecs(), true);
}
private void assertCallTree(CallTree callTree, List<Integer> expectedDepths, List<Integer> expectedGaps, List<Integer> expectedExecs, boolean check) {
Queue<Integer> depths = new LinkedBlockingQueue<>(expectedDepths);
Queue<Integer> gaps = new LinkedBlockingQueue<>(expectedGaps);
Queue<Integer> execs = new LinkedBlockingQueue<>(expectedExecs);
int index = 0;
CallTreeIterator iterator = callTree.iterator();
final StringBuilder buffer = new StringBuilder("\n");
while (iterator.hasNext()) {
CallTreeNode node = iterator.next();
SpanAlign align = node.getValue();
if (check && CollectionUtils.isNotEmpty(depths)) {
final int depth = depths.poll();
assertEquals("depth " + index, depth, align.getDepth());
}
if (check && CollectionUtils.isNotEmpty(gaps)) {
final int gap = gaps.poll();
assertEquals("gap " + index, gap, align.getGap());
}
if (check && CollectionUtils.isNotEmpty(execs)) {
final int exec = execs.poll();
assertEquals("exec " + index, exec, align.getExecutionMilliseconds());
}
for (int i = 0; i <= align.getDepth(); i++) {
if (align.isSpan()) {
buffer.append("R");
} else if (align.isAsync()) {
buffer.append("A");
} else {
buffer.append("#");
}
}
buffer.append(" : depth=");
buffer.append(align.getDepth());
buffer.append(" : gap=");
buffer.append(align.getGap());
buffer.append(", exec=");
buffer.append(align.getExecutionMilliseconds());
buffer.append(", elapsed=");
buffer.append(align.getElapsed());
buffer.append(", startTime=");
buffer.append(align.getStartTime());
buffer.append(", lastTime=");
buffer.append(align.getLastTime());
if (!align.isSpan()) {
buffer.append(", nextAsyncId=");
buffer.append(align.getSpanEventBo().getNextAsyncId());
buffer.append(", asyncId=");
buffer.append(align.getSpanEventBo().getAsyncId());
}
buffer.append("\n");
index++;
}
logger.debug(buffer.toString());
}
private Queue<Integer> parseExpected(String expectedValues) {
if (expectedValues == null) {
return null;
}
String[] tokens = expectedValues.split(",");
Queue<Integer> expected = new LinkedBlockingQueue<Integer>();
for (String token : tokens) {
expected.add(Integer.parseInt(token.trim()));
}
return expected;
}
class CallStackDummy {
List<String> events = new ArrayList<String>();
List<Integer> depths = new ArrayList<Integer>();
List<Integer> gaps = new ArrayList<Integer>();
List<Integer> execs = new ArrayList<Integer>();
public void add(String event, int depth, int gap, int exec) {
events.add(event);
depths.add(depth);
gaps.add(gap);
execs.add(exec);
}
List<String> getEvents() {
return events;
}
List<Integer> getDepths() {
return depths;
}
List<Integer> getGaps() {
return gaps;
}
List<Integer> getExecs() {
return execs;
}
}
}