/* * 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.profiler.interceptor.bci; import com.navercorp.pinpoint.profiler.instrument.aspect.AspectWeaverClass; import com.navercorp.pinpoint.profiler.util.LoaderUtils; import javassist.*; import org.junit.Assert; import org.junit.Test; import java.lang.reflect.Method; public class AspectWeaverClassTest { private final String ORIGINAL = "com.navercorp.pinpoint.profiler.interceptor.bci.mock.Original"; private final String ORIGINAL_SUB = "com.navercorp.pinpoint.profiler.interceptor.bci.mock.OriginalSub"; private final String ASPECT = "com.navercorp.pinpoint.profiler.interceptor.bci.mock.TestAspect"; private final String ASPECT_NO_EXTENTS = "com.navercorp.pinpoint.profiler.interceptor.bci.mock.TestAspect_NoExtents"; private final String ASPECT_EXTENTS_SUB = "com.navercorp.pinpoint.profiler.interceptor.bci.mock.TestAspect_ExtentsSub"; private final String ERROR_ASPECT1 = "com.navercorp.pinpoint.profiler.interceptor.bci.mock.ErrorAspect"; private final String ERROR_ASPECT2 = "com.navercorp.pinpoint.profiler.interceptor.bci.mock.ErrorAspect2"; private final String ERROR_ASPECT_INVALID_EXTENTS= "com.navercorp.pinpoint.profiler.interceptor.bci.mock.ErrorAspect_InvalidExtents"; public Object createAspect(String originalName, String aspectName) { try { ClassPool classPool = new ClassPool(true); Loader loader = getLoader(classPool); CtClass ctOriginal = classPool.get(originalName); CtClass ctAdvice = classPool.get(aspectName); AspectWeaverClass weaver = new AspectWeaverClass(); weaver.weaving(ctOriginal, ctAdvice); Class aClass = loader.loadClass(originalName); return aClass.newInstance(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } private Loader getLoader(ClassPool pool) { return LoaderUtils.createLoader(pool); } private Object createDefaultAspect() { return createAspect(ORIGINAL, ASPECT); } @Test public void testVoid() throws Exception { Object aspectObject = createDefaultAspect(); invoke(aspectObject, "testVoid"); assertBeforeTouchCount(aspectObject, 1); assertAfterTouchCount(aspectObject, 1); } @Test public void testInt() throws Exception { Object aspectObject = createDefaultAspect(); int returnValue = (Integer)invoke(aspectObject, "testInt"); Assert.assertEquals(1, returnValue); assertBeforeTouchCount(aspectObject, 1); assertAfterTouchCount(aspectObject, 1); } @Test public void testString() throws Exception { Object aspectObject = createDefaultAspect(); String returnValue = (String) invoke(aspectObject, "testString"); Assert.assertEquals(returnValue, "testString"); assertBeforeTouchCount(aspectObject, 1); assertAfterTouchCount(aspectObject, 1); } @Test public void testUtilMethod() throws Exception { Object aspectObject = createDefaultAspect(); int returnValue = (Integer)invoke(aspectObject, "testUtilMethod"); Assert.assertEquals(1, returnValue); assertBeforeTouchCount(aspectObject, 1); assertAfterTouchCount(aspectObject, 1); } @Test public void testNoTouch() throws Exception { Object aspectObject = createDefaultAspect(); Object returnValue = invoke(aspectObject, "testNoTouch"); Assert.assertEquals(null, returnValue); assertBeforeTouchCount(aspectObject, 0); assertAfterTouchCount(aspectObject, 0); } @Test public void testInternalMethod() throws Exception { Object aspectObject = createDefaultAspect(); Object returnValue = invoke(aspectObject, "testInternalMethod"); Assert.assertEquals(null, returnValue); assertBeforeTouchCount(aspectObject, 1); assertAfterTouchCount(aspectObject, 1); } @Test public void testMethodCall() throws Exception { Object aspectObject = createDefaultAspect(); invoke(aspectObject, "testMethodCall"); } @Test(expected = Exception.class) public void testSignatureMiss() throws Exception { createAspect(ORIGINAL, ERROR_ASPECT1); } @Test(expected = Exception.class) public void testInternalTypeMiss() throws Exception { createAspect(ORIGINAL, ERROR_ASPECT2); } @Test public void testNo_extents() throws Exception { Object aspectObject = createAspect(ORIGINAL, ASPECT_NO_EXTENTS); Object returnValue = invoke(aspectObject, "testVoid"); Assert.assertEquals(null, returnValue); } @Test public void testExtents_Sub() throws Exception { Object aspectObject = createAspect(ORIGINAL_SUB, ASPECT_EXTENTS_SUB); Object returnValue = invoke(aspectObject, "testVoid"); Assert.assertEquals(null, returnValue); } @Test(expected = Exception.class) public void testInvalid_extents() throws Exception { Object aspectObject = createAspect(ORIGINAL, ERROR_ASPECT_INVALID_EXTENTS); Object returnValue = invoke(aspectObject, "testVoid"); Assert.assertEquals(null, returnValue); } private Object invoke(Object o, String methodName, Object... args) { try { Class<?> clazz = o.getClass(); Method method = clazz.getMethod(methodName); return method.invoke(o, args); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } private void assertBeforeTouchCount(Object aspectObject, int count) { int touchCount = (Integer)invoke(aspectObject, "getTouchBefore"); Assert.assertEquals(touchCount, count); } private void assertAfterTouchCount(Object aspectObject, int count) { int touchCount = (Integer)invoke(aspectObject, "getTouchAfter"); Assert.assertEquals(touchCount, count); } }