/* * Copyright 2014 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.bootstrap.interceptor; import static org.mockito.Mockito.*; import org.junit.Assert; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.navercorp.pinpoint.bootstrap.context.SpanRecorder; import com.navercorp.pinpoint.bootstrap.context.Trace; import com.navercorp.pinpoint.bootstrap.context.TraceContext; public class SpanSimpleAroundInterceptorTest { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Test public void lifeCycle() throws Exception { Trace trace = newTrace(); TraceContext context = newTraceContext(trace); TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor(context); checkSpanInterceptor(context, interceptor); } @Test public void beforeExceptionLifeCycle() throws Exception { Trace trace = newTrace(); TraceContext context = newTraceContext(trace); TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor(context) { @Override protected void doInBeforeTrace(SpanRecorder trace, Object target, Object[] args) { touchBefore(); throw new RuntimeException(); } }; checkSpanInterceptor(context, interceptor); } private Trace newTrace() { Trace trace = mock(Trace.class); when(trace.canSampled()).thenReturn(true); return trace; } private TraceContext newTraceContext(final Trace trace) { final Answer answer = new Answer() { private boolean stop = false; @Override public Object answer(InvocationOnMock invocation) throws Throwable { final String methodName = invocation.getMethod().getName(); if (methodName.equals("removeTraceObject")) { stop = true; } if (stop) { return null; } return trace; } }; TraceContext traceContext = mock(TraceContext.class); when(traceContext.currentRawTraceObject()).thenAnswer(answer); when(traceContext.newTraceObject()).thenAnswer(answer); when(traceContext.removeTraceObject()).thenAnswer(answer); return traceContext; } @Test public void afterExceptionLifeCycle() throws Exception { Trace trace = newTrace(); TraceContext context = newTraceContext(trace); TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor(context) { @Override protected void doInAfterTrace(SpanRecorder trace, Object target, Object[] args, Object result, Throwable throwable) { touchAfter(); throw new RuntimeException(); } }; checkSpanInterceptor(context, interceptor); } @Test public void beforeAfterExceptionLifeCycle() throws Exception { Trace trace = newTrace(); TraceContext context = newTraceContext(trace); TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor(context) { @Override protected void doInBeforeTrace(SpanRecorder recorder, Object target, Object[] args) { touchBefore(); throw new RuntimeException(); } @Override protected void doInAfterTrace(SpanRecorder recorder, Object target, Object[] args, Object result, Throwable throwable) { touchAfter(); throw new RuntimeException(); } }; checkSpanInterceptor(context, interceptor); } @Test public void traceCreateFail() { TraceContext context = mock(TraceContext.class); when(context.newTraceObject()).thenReturn(null); TestSpanSimpleAroundInterceptor interceptor = new TestSpanSimpleAroundInterceptor(context); checkTraceCreateFailInterceptor(context, interceptor); } private void checkSpanInterceptor(TraceContext context, TestSpanSimpleAroundInterceptor interceptor) { Trace createTrace = interceptor.createTrace(null, null); interceptor.before(new Object(), null); Assert.assertEquals("beforeTouchCount", interceptor.getBeforeTouchCount(), 1); Trace before = context.currentRawTraceObject(); Assert.assertEquals(createTrace, before); interceptor.after(new Object(), null, null, null); Assert.assertEquals("afterTouchCount", interceptor.getAfterTouchCount(), 1); Trace after = context.currentRawTraceObject(); Assert.assertNull(after); } private void checkTraceCreateFailInterceptor(TraceContext context, TestSpanSimpleAroundInterceptor interceptor) { Trace createTrace = interceptor.createTrace(null, null); Assert.assertNull(createTrace); interceptor.before(new Object(), null); Assert.assertEquals(interceptor.getBeforeTouchCount(), 0); Assert.assertNull(context.currentRawTraceObject()); interceptor.after(new Object(), null, null, null); Assert.assertEquals(interceptor.getAfterTouchCount(), 0); Assert.assertNull(context.currentRawTraceObject()); } @Test public void testCreateTrace() throws Exception { } @Test public void testDoInAfterTrace() throws Exception { } public static class TestSpanSimpleAroundInterceptor extends SpanSimpleAroundInterceptor { private int beforeTouchCount; private int afterTouchCount; public TestSpanSimpleAroundInterceptor(TraceContext traceContext) { super(traceContext, null, TestSpanSimpleAroundInterceptor.class); } @Override protected Trace createTrace(Object target, Object[] args) { return traceContext.newTraceObject(); } @Override protected void doInBeforeTrace(SpanRecorder recorder, Object target, Object[] args) { touchBefore(); } protected void touchBefore() { beforeTouchCount++; } public int getAfterTouchCount() { return afterTouchCount; } @Override protected void doInAfterTrace(SpanRecorder recorder, Object target, Object[] args, Object result, Throwable throwable) { touchAfter(); } protected void touchAfter() { afterTouchCount++; } public int getBeforeTouchCount() { return beforeTouchCount; } @Override protected void deleteTrace(Trace trace, Object target, Object[] args, Object result, Throwable throwable) { } } }