/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.sesame.trace;
import static com.opengamma.sesame.config.ConfigBuilder.config;
import static com.opengamma.sesame.config.ConfigBuilder.implementations;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.fail;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.sesame.config.FunctionModelConfig;
import com.opengamma.sesame.engine.ComponentMap;
import com.opengamma.sesame.engine.TraceType;
import com.opengamma.sesame.function.Output;
import com.opengamma.sesame.graph.FunctionModel;
import com.opengamma.util.test.TestGroup;
@Test(groups = TestGroup.UNIT)
public class StandardTracerTest {
private static final String METHOD1 = "method1";
private static final String METHOD2 = "method2";
private I1 buildFunction() {
FunctionModelConfig functionModelConfig = config(implementations(I1.class, C1.class, I2.class, C2.class));
return FunctionModel.build(I1.class, functionModelConfig, ComponentMap.EMPTY, TracingProxy.INSTANCE);
}
@Test
public void trace1Level() throws NoSuchMethodException {
I1 i1 = buildFunction();
TracingProxy.start(new StandardTracer(TraceType.FULL));
i1.method1(0);
CallGraph trace = TracingProxy.end();
CallGraph expected = CallGraph.builder()
.receiverClass(I1.class)
.methodName(METHOD1)
.parameterTypes(ImmutableList.<Class<?>>of(Integer.TYPE))
.arguments(ImmutableList.<Object>of(0))
.returnValue("foo")
// We have to cheat with the timing information
.duration(trace.getDuration())
.build();
assertEquals(expected, trace);
System.out.println(trace.prettyPrint());
}
@Test
public void trace2LevelsFull() {
I1 i1 = buildFunction();
TracingProxy.start(new StandardTracer(TraceType.FULL));
i1.method1(1);
CallGraph trace = TracingProxy.end();
CallGraph expected = CallGraph.builder()
.receiverClass(I1.class)
.methodName(METHOD1)
.parameterTypes(ImmutableList.<Class<?>>of(Integer.TYPE))
.arguments(ImmutableList.<Object>of(1))
.duration(trace.getDuration())
.returnValue("foo 42")
.calls(ImmutableList.of(
CallGraph.builder()
.receiverClass(I2.class)
.methodName(METHOD2)
.parameterTypes(ImmutableList.<Class<?>>of(Boolean.TYPE))
.arguments(ImmutableList.<Object>of(true))
.returnValue(42)
.duration(trace.getCalls().get(0).getDuration())
.build()))
.build();
assertEquals(expected, trace);
System.out.println(trace.prettyPrint());
}
@Test
public void trace2LevelsString() {
I1 i1 = buildFunction();
TracingProxy.start(new StandardTracer(TraceType.FULL_AS_STRING));
i1.method1(1);
CallGraph trace = TracingProxy.end();
CallGraph expected = CallGraph.builder()
.receiverClass(I1.class)
.methodName(METHOD1)
.parameterTypes(ImmutableList.<Class<?>>of(Integer.TYPE))
.arguments(ImmutableList.<Object>of("1"))
.duration(trace.getDuration())
.returnValue("foo 42")
.calls(ImmutableList.of(
CallGraph.builder()
.receiverClass(I2.class)
.methodName(METHOD2)
.parameterTypes(ImmutableList.<Class<?>>of(Boolean.TYPE))
.arguments(ImmutableList.<Object>of("true"))
.returnValue("42")
.duration(trace.getCalls().get(0).getDuration())
.build()))
.build();
assertEquals(expected, trace);
System.out.println(trace.prettyPrint());
}
@Test
public void trace2LevelsTimings() {
I1 i1 = buildFunction();
TracingProxy.start(new StandardTracer(TraceType.TIMINGS_ONLY));
i1.method1(1);
CallGraph trace = TracingProxy.end();
CallGraph expected = CallGraph.builder()
.receiverClass(I1.class)
.methodName(METHOD1)
.parameterTypes(ImmutableList.<Class<?>>of(Integer.TYPE))
.duration(trace.getDuration())
.returnValue(null)
.calls(ImmutableList.of(
CallGraph.builder()
.receiverClass(I2.class)
.methodName(METHOD2)
.parameterTypes(ImmutableList.<Class<?>>of(Boolean.TYPE))
.returnValue(null)
.duration(trace.getCalls().get(0).getDuration())
.build()))
.build();
assertEquals(expected, trace);
System.out.println(trace.prettyPrint());
}
@Test
public void traceMultiple() {
I1 i1 = buildFunction();
TracingProxy.start(new StandardTracer(TraceType.FULL));
i1.method1(2);
CallGraph trace = TracingProxy.end();
CallGraph expected = CallGraph.builder()
.receiverClass(I1.class)
.methodName(METHOD1)
.parameterTypes(ImmutableList.<Class<?>>of(Integer.TYPE))
.arguments(ImmutableList.<Object>of(2))
.returnValue("bar 42 84")
.duration(trace.getDuration())
.calls(ImmutableList.of(
CallGraph.builder()
.receiverClass(I2.class)
.methodName(METHOD2)
.parameterTypes(ImmutableList.<Class<?>>of(Boolean.TYPE))
.arguments(ImmutableList.<Object>of(true))
.returnValue(42)
.duration(trace.getCalls().get(0).getDuration())
.build(),
CallGraph.builder()
.receiverClass(I2.class)
.methodName(METHOD2)
.parameterTypes(ImmutableList.<Class<?>>of(Boolean.TYPE))
.arguments(ImmutableList.<Object>of(true))
.returnValue(42)
.duration(trace.getCalls().get(1).getDuration())
.build()))
.build();
assertEquals(expected, trace);
System.out.println(trace.prettyPrint());
}
@Test
public void traceException() {
I1 i1 = buildFunction();
TracingProxy.start(new StandardTracer(TraceType.FULL));
try {
i1.method1(3);
fail();
} catch (OpenGammaRuntimeException e) {
// expected
}
CallGraph trace = TracingProxy.end();
CallGraph expected = CallGraph.builder()
.receiverClass(I1.class)
.methodName(METHOD1)
.parameterTypes(ImmutableList.<Class<?>>of(Integer.TYPE))
.arguments(ImmutableList.<Object>of(3))
.throwableClass(OpenGammaRuntimeException.class)
.errorMessage("an exception")
.duration(trace.getDuration())
.calls(ImmutableList.of(
CallGraph.builder()
.receiverClass(I2.class)
.methodName(METHOD2)
.parameterTypes(ImmutableList.<Class<?>>of(Boolean.TYPE))
.arguments(ImmutableList.<Object>of(false))
.throwableClass(OpenGammaRuntimeException.class)
.errorMessage("an exception")
.duration(trace.getCalls().get(0).getDuration())
.build()))
.build();
assertEquals(expected, trace);
System.out.println(trace.prettyPrint());
}
@Test
public void traceExceptionWithTiming() {
I1 i1 = buildFunction();
TracingProxy.start(new StandardTracer(TraceType.TIMINGS_ONLY));
try {
i1.method1(3);
fail();
} catch (OpenGammaRuntimeException e) {
// expected
}
CallGraph trace = TracingProxy.end();
CallGraph expected = CallGraph.builder()
.receiverClass(I1.class)
.methodName(METHOD1)
.parameterTypes(ImmutableList.<Class<?>>of(Integer.TYPE))
.throwableClass(null)
.errorMessage(null)
.duration(trace.getDuration())
.calls(ImmutableList.of(
CallGraph.builder()
.receiverClass(I2.class)
.methodName(METHOD2)
.parameterTypes(ImmutableList.<Class<?>>of(Boolean.TYPE))
.throwableClass(null)
.errorMessage(null)
.duration(trace.getCalls().get(0).getDuration())
.build()))
.build();
assertEquals(expected, trace);
System.out.println(trace.prettyPrint());
}
@Test
public void tracingDisabled() {
I1 i1 = buildFunction();
i1.method1(2);
assertNull(TracingProxy.end());
}
interface I1 {
@Output("not used")
String method1(int i);
}
public static class C1 implements I1 {
private final I2 _i2;
public C1(I2 i2) {
_i2 = i2;
}
@Override
public String method1(int i) {
switch (i) {
case 0:
return "foo";
case 1:
return "foo " + _i2.method2(true);
case 2:
return "bar " + _i2.method2(true) + " " + (_i2.method2(true) * 2);
default:
return "baz " + _i2.method2(false);
}
}
}
interface I2 {
Integer method2(boolean b);
}
public static class C2 implements I2 {
@Override
public Integer method2(boolean b) {
if (b) {
return 42;
} else {
throw new OpenGammaRuntimeException("an exception");
}
}
}
}