diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/framework/CountingBeforeAdvice.java b/org.springframework.aop/src/test/java/org/springframework/aop/framework/CountingBeforeAdvice.java new file mode 100644 index 0000000000000000000000000000000000000000..3f391b2c68c5141ba01d843920b7abfd1156b270 --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/framework/CountingBeforeAdvice.java @@ -0,0 +1,34 @@ +/* + * Copyright 2002-2005 the original author or authors. + * + * 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 org.springframework.aop.framework; + +import java.lang.reflect.Method; + +import org.springframework.aop.MethodBeforeAdvice; + +/** + * Simple before advice example that we can use for counting checks. + * + * @author Rod Johnson + */ +public class CountingBeforeAdvice extends MethodCounter implements MethodBeforeAdvice { + + public void before(Method m, Object[] args, Object target) throws Throwable { + count(m); + } + +} \ No newline at end of file diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/framework/ExposedInvocationTestBean.java b/org.springframework.aop/src/test/java/org/springframework/aop/framework/ExposedInvocationTestBean.java new file mode 100644 index 0000000000000000000000000000000000000000..83f561737914918d9754689a6b4111a5eacd9cd7 --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/framework/ExposedInvocationTestBean.java @@ -0,0 +1,43 @@ +/* + * Copyright 2002-2005 the original author or authors. + * + * 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 org.springframework.aop.framework; + +import org.aopalliance.intercept.MethodInvocation; +import org.springframework.aop.interceptor.ExposeInvocationInterceptor; +import org.springframework.beans.TestBean; + + +/** + * Used to test ExposeInvocationInterceptor. + * @author Rod Johnson + */ +public abstract class ExposedInvocationTestBean extends TestBean { + + public String getName() { + MethodInvocation invocation = ExposeInvocationInterceptor.currentInvocation(); + assertions(invocation); + return super.getName(); + } + + public void absquatulate() { + MethodInvocation invocation = ExposeInvocationInterceptor.currentInvocation(); + assertions(invocation); + super.absquatulate(); + } + + protected abstract void assertions(MethodInvocation invocation); +} \ No newline at end of file diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/framework/InvocationCheckExposedInvocationTestBean.java b/org.springframework.aop/src/test/java/org/springframework/aop/framework/InvocationCheckExposedInvocationTestBean.java new file mode 100644 index 0000000000000000000000000000000000000000..d5c1edc87680e217501d915d393e353ba8ebb567 --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/framework/InvocationCheckExposedInvocationTestBean.java @@ -0,0 +1,31 @@ +/* + * Copyright 2002-2005 the original author or authors. + * + * 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 org.springframework.aop.framework; + +import junit.framework.TestCase; + +import org.aopalliance.intercept.MethodInvocation; +import org.springframework.beans.ITestBean; + + +public class InvocationCheckExposedInvocationTestBean extends ExposedInvocationTestBean { + protected void assertions(MethodInvocation invocation) { + TestCase.assertTrue(invocation.getThis() == this); + TestCase.assertTrue("Invocation should be on ITestBean: " + invocation.getMethod(), + ITestBean.class.isAssignableFrom(invocation.getMethod().getDeclaringClass())); + } +} \ No newline at end of file diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/ConcurrencyThrottleInterceptorTests.java b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/ConcurrencyThrottleInterceptorTests.java new file mode 100644 index 0000000000000000000000000000000000000000..49f143e034e20d3db74ebcae1dbb1f3bae6ab693 --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/ConcurrencyThrottleInterceptorTests.java @@ -0,0 +1,159 @@ +/* + * Copyright 2002-2005 the original author or authors. + * + * 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 org.springframework.aop.interceptor; + +import static org.junit.Assert.*; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Test; + +import org.springframework.aop.framework.Advised; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.beans.DerivedTestBean; +import org.springframework.beans.ITestBean; +import org.springframework.beans.TestBean; +import org.springframework.util.SerializationTestUtils; + +/** + * @author Juergen Hoeller + * @author Chris Beams + * @since 06.04.2004 + */ +public class ConcurrencyThrottleInterceptorTests { + + protected static final Log logger = LogFactory.getLog(ConcurrencyThrottleInterceptorTests.class); + + public static final int NR_OF_THREADS = 100; + + public static final int NR_OF_ITERATIONS = 1000; + + + @Test + public void testSerializable() throws Exception { + DerivedTestBean tb = new DerivedTestBean(); + ProxyFactory proxyFactory = new ProxyFactory(); + proxyFactory.setInterfaces(new Class[] {ITestBean.class}); + ConcurrencyThrottleInterceptor cti = new ConcurrencyThrottleInterceptor(); + proxyFactory.addAdvice(cti); + proxyFactory.setTarget(tb); + ITestBean proxy = (ITestBean) proxyFactory.getProxy(); + proxy.getAge(); + + ITestBean serializedProxy = (ITestBean) SerializationTestUtils.serializeAndDeserialize(proxy); + Advised advised = (Advised) serializedProxy; + ConcurrencyThrottleInterceptor serializedCti = + (ConcurrencyThrottleInterceptor) advised.getAdvisors()[0].getAdvice(); + assertEquals(cti.getConcurrencyLimit(), serializedCti.getConcurrencyLimit()); + serializedProxy.getAge(); + } + + @Test + public void testMultipleThreadsWithLimit1() { + testMultipleThreads(1); + } + + @Test + public void testMultipleThreadsWithLimit10() { + testMultipleThreads(10); + } + + private void testMultipleThreads(int concurrencyLimit) { + TestBean tb = new TestBean(); + ProxyFactory proxyFactory = new ProxyFactory(); + proxyFactory.setInterfaces(new Class[] {ITestBean.class}); + ConcurrencyThrottleInterceptor cti = new ConcurrencyThrottleInterceptor(); + cti.setConcurrencyLimit(concurrencyLimit); + proxyFactory.addAdvice(cti); + proxyFactory.setTarget(tb); + ITestBean proxy = (ITestBean) proxyFactory.getProxy(); + + Thread[] threads = new Thread[NR_OF_THREADS]; + for (int i = 0; i < NR_OF_THREADS; i++) { + threads[i] = new ConcurrencyThread(proxy, null); + threads[i].start(); + } + for (int i = 0; i < NR_OF_THREADS / 10; i++) { + try { + Thread.sleep(5); + } + catch (InterruptedException ex) { + ex.printStackTrace(); + } + threads[i] = new ConcurrencyThread(proxy, + i % 2 == 0 ? (Throwable) new OutOfMemoryError() : (Throwable) new IllegalStateException()); + threads[i].start(); + } + for (int i = 0; i < NR_OF_THREADS; i++) { + try { + threads[i].join(); + } + catch (InterruptedException ex) { + ex.printStackTrace(); + } + } + } + + + private static class ConcurrencyThread extends Thread { + + private ITestBean proxy; + private Throwable ex; + + public ConcurrencyThread(ITestBean proxy, Throwable ex) { + this.proxy = proxy; + this.ex = ex; + } + + public void run() { + if (this.ex != null) { + try { + this.proxy.exceptional(this.ex); + } + catch (RuntimeException ex) { + if (ex == this.ex) { + logger.debug("Expected exception thrown", ex); + } + else { + // should never happen + ex.printStackTrace(); + } + } + catch (Error err) { + if (err == this.ex) { + logger.debug("Expected exception thrown", err); + } + else { + // should never happen + ex.printStackTrace(); + } + } + catch (Throwable ex) { + // should never happen + ex.printStackTrace(); + } + } + else { + for (int i = 0; i < NR_OF_ITERATIONS; i++) { + this.proxy.getName(); + } + } + logger.debug("finished"); + } + } + +} diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/CustomizableTraceInterceptorTests.java b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/CustomizableTraceInterceptorTests.java new file mode 100644 index 0000000000000000000000000000000000000000..da7d05163139ce99eca9161a7ff1fbee4518fe21 --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/CustomizableTraceInterceptorTests.java @@ -0,0 +1,197 @@ +/* + * Copyright 2002-2008 the original author or authors. + * + * 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 org.springframework.aop.interceptor; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.*; + +import java.lang.reflect.Method; + +import org.aopalliance.intercept.MethodInvocation; +import org.apache.commons.logging.Log; +import org.junit.Test; + +/** + * @author Rob Harrop + * @author Rick Evans + * @author Juergen Hoeller + * @author Chris Beams + */ +public class CustomizableTraceInterceptorTests { + + @Test(expected=IllegalArgumentException.class) + public void testSetEmptyEnterMessage() { + // Must not be able to set empty enter message + new CustomizableTraceInterceptor().setEnterMessage(""); + } + + @Test(expected=IllegalArgumentException.class) + public void testSetEnterMessageWithReturnValuePlaceholder() { + // Must not be able to set enter message with return value placeholder + new CustomizableTraceInterceptor().setEnterMessage(CustomizableTraceInterceptor.PLACEHOLDER_RETURN_VALUE); + } + + @Test(expected=IllegalArgumentException.class) + public void testSetEnterMessageWithExceptionPlaceholder() { + // Must not be able to set enter message with exception placeholder + new CustomizableTraceInterceptor().setEnterMessage(CustomizableTraceInterceptor.PLACEHOLDER_EXCEPTION); + } + + @Test(expected=IllegalArgumentException.class) + public void testSetEnterMessageWithInvocationTimePlaceholder() { + // Must not be able to set enter message with invocation time placeholder + new CustomizableTraceInterceptor().setEnterMessage(CustomizableTraceInterceptor.PLACEHOLDER_INVOCATION_TIME); + } + + @Test(expected=IllegalArgumentException.class) + public void testSetEmptyExitMessage() { + // Must not be able to set empty exit message + new CustomizableTraceInterceptor().setExitMessage(""); + } + + @Test(expected=IllegalArgumentException.class) + public void testSetExitMessageWithExceptionPlaceholder() { + // Must not be able to set exit message with exception placeholder + new CustomizableTraceInterceptor().setExitMessage(CustomizableTraceInterceptor.PLACEHOLDER_EXCEPTION); + } + + @Test(expected=IllegalArgumentException.class) + public void testSetEmptyExceptionMessage() { + // Must not be able to set empty exception message + new CustomizableTraceInterceptor().setExceptionMessage(""); + } + + @Test(expected=IllegalArgumentException.class) + public void testSetExceptionMethodWithReturnValuePlaceholder() { + // Must not be able to set exception message with return value placeholder + new CustomizableTraceInterceptor().setExceptionMessage(CustomizableTraceInterceptor.PLACEHOLDER_RETURN_VALUE); + } + + @Test + public void testSunnyDayPathLogsCorrectly() throws Throwable { + Log log = createMock(Log.class); + + MethodInvocation methodInvocation = createMock(MethodInvocation.class); + + Method toString = String.class.getMethod("toString", new Class[]{}); + + expect(log.isTraceEnabled()).andReturn(true); + expect(methodInvocation.getMethod()).andReturn(toString).times(4); + expect(methodInvocation.getThis()).andReturn(this).times(2); + log.trace(isA(String.class)); + expect(methodInvocation.proceed()).andReturn(null); + log.trace(isA(String.class)); + + replay(methodInvocation); + replay(log); + + CustomizableTraceInterceptor interceptor = new StubCustomizableTraceInterceptor(log); + interceptor.invoke(methodInvocation); + + verify(log); + verify(methodInvocation); + } + + @Test + public void testExceptionPathLogsCorrectly() throws Throwable { + Log log = createMock(Log.class); + + MethodInvocation methodInvocation = createMock(MethodInvocation.class); + + Method toString = String.class.getMethod("toString", new Class[]{}); + + expect(log.isTraceEnabled()).andReturn(true); + expect(methodInvocation.getMethod()).andReturn(toString).times(4); + expect(methodInvocation.getThis()).andReturn(this).times(2); + log.trace(isA(String.class)); + IllegalArgumentException exception = new IllegalArgumentException(); + expect(methodInvocation.proceed()).andThrow(exception); + log.trace(isA(String.class), eq(exception)); + + replay(log); + replay(methodInvocation); + + CustomizableTraceInterceptor interceptor = new StubCustomizableTraceInterceptor(log); + try { + interceptor.invoke(methodInvocation); + fail("Must have propagated the IllegalArgumentException."); + } + catch (IllegalArgumentException expected) { + } + + verify(log); + verify(methodInvocation); + } + + @Test + public void testSunnyDayPathLogsCorrectlyWithPrettyMuchAllPlaceholdersMatching() throws Throwable { + Log log = createMock(Log.class); + + MethodInvocation methodInvocation = createMock(MethodInvocation.class); + + Method toString = String.class.getMethod("toString", new Class[0]); + Object[] arguments = new Object[]{"$ One \\$", new Long(2)}; + + expect(log.isTraceEnabled()).andReturn(true); + expect(methodInvocation.getMethod()).andReturn(toString).times(7); + expect(methodInvocation.getThis()).andReturn(this).times(2); + expect(methodInvocation.getArguments()).andReturn(arguments).times(2); + log.trace(isA(String.class)); + expect(methodInvocation.proceed()).andReturn("Hello!"); + log.trace(isA(String.class)); + + replay(methodInvocation); + replay(log); + + CustomizableTraceInterceptor interceptor = new StubCustomizableTraceInterceptor(log); + interceptor.setEnterMessage(new StringBuffer() + .append("Entering the '").append(CustomizableTraceInterceptor.PLACEHOLDER_METHOD_NAME) + .append("' method of the [").append(CustomizableTraceInterceptor.PLACEHOLDER_TARGET_CLASS_NAME) + .append("] class with the following args (").append(CustomizableTraceInterceptor.PLACEHOLDER_ARGUMENTS) + .append(") and arg types (").append(CustomizableTraceInterceptor.PLACEHOLDER_ARGUMENT_TYPES) + .append(").").toString()); + interceptor.setExitMessage(new StringBuffer() + .append("Exiting the '").append(CustomizableTraceInterceptor.PLACEHOLDER_METHOD_NAME) + .append("' method of the [").append(CustomizableTraceInterceptor.PLACEHOLDER_TARGET_CLASS_SHORT_NAME) + .append("] class with the following args (").append(CustomizableTraceInterceptor.PLACEHOLDER_ARGUMENTS) + .append(") and arg types (").append(CustomizableTraceInterceptor.PLACEHOLDER_ARGUMENT_TYPES) + .append("), returning '").append(CustomizableTraceInterceptor.PLACEHOLDER_RETURN_VALUE) + .append("' and taking '").append(CustomizableTraceInterceptor.PLACEHOLDER_INVOCATION_TIME) + .append("' this long.").toString()); + interceptor.invoke(methodInvocation); + + verify(log); + verify(methodInvocation); + } + + + @SuppressWarnings("serial") + private static class StubCustomizableTraceInterceptor extends CustomizableTraceInterceptor { + + private final Log log; + + public StubCustomizableTraceInterceptor(Log log) { + super.setUseDynamicLogger(false); + this.log = log; + } + + protected Log getLoggerForInvocation(MethodInvocation invocation) { + return this.log; + } + } + +} diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/DebugInterceptorTests.java b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/DebugInterceptorTests.java new file mode 100644 index 0000000000000000000000000000000000000000..85f4a43c094522b6951ab1be45e266ae1a145882 --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/DebugInterceptorTests.java @@ -0,0 +1,105 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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 org.springframework.aop.interceptor; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.*; + +import org.aopalliance.intercept.MethodInvocation; +import org.apache.commons.logging.Log; +import org.junit.Test; + +/** + * Unit tests for the {@link DebugInterceptor} class. + * + * @author Rick Evans + * @author Chris Beams + */ +public final class DebugInterceptorTests { + + @Test + public void testSunnyDayPathLogsCorrectly() throws Throwable { + Log log = createMock(Log.class); + + MethodInvocation methodInvocation = createMock(MethodInvocation.class); + + expect(log.isTraceEnabled()).andReturn(true); + log.trace(isA(String.class)); + expect(methodInvocation.proceed()).andReturn(null); + log.trace(isA(String.class)); + + replay(methodInvocation); + replay(log); + + DebugInterceptor interceptor = new StubDebugInterceptor(log); + interceptor.invoke(methodInvocation); + checkCallCountTotal(interceptor); + + verify(methodInvocation); + verify(log); + } + + @Test + public void testExceptionPathStillLogsCorrectly() throws Throwable { + Log log = createMock(Log.class); + + MethodInvocation methodInvocation = createMock(MethodInvocation.class); + + expect(log.isTraceEnabled()).andReturn(true); + log.trace(isA(String.class)); + IllegalArgumentException exception = new IllegalArgumentException(); + expect(methodInvocation.proceed()).andThrow(exception); + log.trace(isA(String.class), eq(exception)); + + replay(methodInvocation); + replay(log); + + DebugInterceptor interceptor = new StubDebugInterceptor(log); + try { + interceptor.invoke(methodInvocation); + fail("Must have propagated the IllegalArgumentException."); + } catch (IllegalArgumentException expected) { + } + checkCallCountTotal(interceptor); + + verify(methodInvocation); + verify(log); + } + + private void checkCallCountTotal(DebugInterceptor interceptor) { + assertEquals("Intercepted call count not being incremented correctly", 1, interceptor.getCount()); + } + + + @SuppressWarnings("serial") + private static final class StubDebugInterceptor extends DebugInterceptor { + + private final Log log; + + + public StubDebugInterceptor(Log log) { + super(true); + this.log = log; + } + + protected Log getLoggerForInvocation(MethodInvocation invocation) { + return log; + } + + } + +} diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisorsTests.java b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisorsTests.java new file mode 100644 index 0000000000000000000000000000000000000000..67bcbd0e0dcc2c863dc2e87178a0d183dd78b7d0 --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/ExposeBeanNameAdvisorsTests.java @@ -0,0 +1,77 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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 org.springframework.aop.interceptor; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.beans.ITestBean; +import org.springframework.beans.TestBean; +import org.springframework.beans.factory.NamedBean; + +/** + * @author Rod Johnson + * @author Chris Beams + */ +public class ExposeBeanNameAdvisorsTests { + + private class RequiresBeanNameBoundTestBean extends TestBean { + private final String beanName; + + public RequiresBeanNameBoundTestBean(String beanName) { + this.beanName = beanName; + } + + public int getAge() { + assertEquals(beanName, ExposeBeanNameAdvisors.getBeanName()); + return super.getAge(); + } + } + + @Test + public void testNoIntroduction() { + String beanName = "foo"; + TestBean target = new RequiresBeanNameBoundTestBean(beanName); + ProxyFactory pf = new ProxyFactory(target); + pf.addAdvisor(ExposeInvocationInterceptor.ADVISOR); + pf.addAdvisor(ExposeBeanNameAdvisors.createAdvisorWithoutIntroduction(beanName)); + ITestBean proxy = (ITestBean) pf.getProxy(); + + assertFalse("No introduction", proxy instanceof NamedBean); + // Requires binding + proxy.getAge(); + } + + @Test + public void testWithIntroduction() { + String beanName = "foo"; + TestBean target = new RequiresBeanNameBoundTestBean(beanName); + ProxyFactory pf = new ProxyFactory(target); + pf.addAdvisor(ExposeInvocationInterceptor.ADVISOR); + pf.addAdvisor(ExposeBeanNameAdvisors.createAdvisorIntroducingNamedBean(beanName)); + ITestBean proxy = (ITestBean) pf.getProxy(); + + assertTrue("Introduction was made", proxy instanceof NamedBean); + // Requires binding + proxy.getAge(); + + NamedBean nb = (NamedBean) proxy; + assertEquals("Name returned correctly", beanName, nb.getBeanName()); + } + +} diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/ExposeInvocationInterceptorTests.java b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/ExposeInvocationInterceptorTests.java new file mode 100644 index 0000000000000000000000000000000000000000..afb8d8f41bfaea2470c5fda511e49cadd6c90a9d --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/ExposeInvocationInterceptorTests.java @@ -0,0 +1,44 @@ +/* + * Copyright 2002-2005 the original author or authors. + * + * 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 org.springframework.aop.interceptor; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.springframework.beans.ITestBean; +import org.springframework.beans.factory.xml.XmlBeanFactory; +import org.springframework.core.io.ClassPathResource; + +/** + * Non-XML tests are in AbstractAopProxyTests + * @author Rod Johnson + * @author Chris Beams + */ +public class ExposeInvocationInterceptorTests { + + @Test + public void testXmlConfig() { + XmlBeanFactory bf = new XmlBeanFactory( + new ClassPathResource("org/springframework/aop/interceptor/exposeInvocation.xml")); + ITestBean tb = (ITestBean) bf.getBean("proxy"); + String name= "tony"; + tb.setName(name); + // Fires context checks + assertEquals(name, tb.getName()); + } + +} diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/NopInterceptor.java b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/NopInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..6bbbc4ff174ca0c6b00aa149a972dbc44e3b3756 --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/NopInterceptor.java @@ -0,0 +1,58 @@ + +/* + * Copyright 2002-2005 the original author or authors. + * + * 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 org.springframework.aop.interceptor; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; + +/** + * Trivial interceptor that can be introduced in a chain to display it. + * + * @author Rod Johnson + */ +public class NopInterceptor implements MethodInterceptor { + + private int count; + + /** + * @see org.aopalliance.intercept.MethodInterceptor#invoke(MethodInvocation) + */ + public Object invoke(MethodInvocation invocation) throws Throwable { + increment(); + return invocation.proceed(); + } + + public int getCount() { + return this.count; + } + + protected void increment() { + ++count; + } + + public boolean equals(Object other) { + if (!(other instanceof NopInterceptor)) { + return false; + } + if (this == other) { + return true; + } + return this.count == ((NopInterceptor) other).count; + } + +} diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/PerformanceMonitorInterceptorTests.java b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/PerformanceMonitorInterceptorTests.java new file mode 100644 index 0000000000000000000000000000000000000000..e13eaeef7c67072fec3e3bf7f41b2154a5338638 --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/PerformanceMonitorInterceptorTests.java @@ -0,0 +1,96 @@ +/* + * Copyright 2002-2007 the original author or authors. + * + * 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 org.springframework.aop.interceptor; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.*; + +import java.lang.reflect.Method; + +import org.aopalliance.intercept.MethodInvocation; +import org.apache.commons.logging.Log; +import org.junit.Test; + +/** + * @author Rob Harrop + * @author Rick Evans + * @author Chris Beams + */ +public class PerformanceMonitorInterceptorTests { + + @Test + public void testSuffixAndPrefixAssignment() { + PerformanceMonitorInterceptor interceptor = new PerformanceMonitorInterceptor(); + + assertNotNull(interceptor.getPrefix()); + assertNotNull(interceptor.getSuffix()); + + interceptor.setPrefix(null); + interceptor.setSuffix(null); + + assertNotNull(interceptor.getPrefix()); + assertNotNull(interceptor.getSuffix()); + } + + @Test + public void testSunnyDayPathLogsPerformanceMetricsCorrectly() throws Throwable { + Log log = createMock(Log.class); + MethodInvocation mi = createMock(MethodInvocation.class); + + Method toString = String.class.getMethod("toString", new Class[0]); + + expect(mi.getMethod()).andReturn(toString); + expect(mi.proceed()).andReturn(null); + log.trace(isA(String.class)); + + replay(mi); + replay(log); + + PerformanceMonitorInterceptor interceptor = new PerformanceMonitorInterceptor(true); + interceptor.invokeUnderTrace(mi, log); + + verify(log); + verify(mi); + } + + @Test + public void testExceptionPathStillLogsPerformanceMetricsCorrectly() throws Throwable { + Log log = createMock(Log.class); + MethodInvocation mi = createMock(MethodInvocation.class); + + Method toString = String.class.getMethod("toString", new Class[0]); + + expect(mi.getMethod()).andReturn(toString); + expect(mi.proceed()).andThrow(new IllegalArgumentException()); + log.trace(isA(String.class)); + + replay(mi); + replay(log); + + PerformanceMonitorInterceptor interceptor = new PerformanceMonitorInterceptor(true); + try { + interceptor.invokeUnderTrace(mi, log); + fail("Must have propagated the IllegalArgumentException."); + } + catch (IllegalArgumentException expected) { + } + + verify(log); + verify(mi); + } + +} diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/SimpleTraceInterceptorTests.java b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/SimpleTraceInterceptorTests.java new file mode 100644 index 0000000000000000000000000000000000000000..5c441c1da868f4937dddac6d180c247f9f37aa94 --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/SimpleTraceInterceptorTests.java @@ -0,0 +1,87 @@ +/* + * Copyright 2002-2006 the original author or authors. + * + * 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 org.springframework.aop.interceptor; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.fail; + +import java.lang.reflect.Method; + +import org.aopalliance.intercept.MethodInvocation; +import org.apache.commons.logging.Log; +import org.junit.Test; + +/** + * Unit tests for the {@link SimpleTraceInterceptor} class. + * + * @author Rick Evans + * @author Chris Beams + */ +public final class SimpleTraceInterceptorTests { + + @Test + public void testSunnyDayPathLogsCorrectly() throws Throwable { + Log log = createMock(Log.class); + MethodInvocation mi = createMock(MethodInvocation.class); + + Method toString = String.class.getMethod("toString", new Class[]{}); + + expect(mi.getMethod()).andReturn(toString); + expect(mi.getThis()).andReturn(this); + log.trace(isA(String.class)); + expect(mi.proceed()).andReturn(null); + log.trace(isA(String.class)); + + replay(log); + replay(mi); + + SimpleTraceInterceptor interceptor = new SimpleTraceInterceptor(true); + interceptor.invokeUnderTrace(mi, log); + + verify(log); + verify(mi); + } + + public void testExceptionPathStillLogsCorrectly() throws Throwable { + Log log = createMock(Log.class); + MethodInvocation mi = createMock(MethodInvocation.class); + + Method toString = String.class.getMethod("toString", new Class[]{}); + + expect(mi.getMethod()).andReturn(toString); + expect(mi.getThis()).andReturn(this); + log.trace(isA(String.class)); + IllegalArgumentException exception = new IllegalArgumentException(); + expect(mi.proceed()).andThrow(exception); + log.trace(isA(String.class)); + + replay(log); + replay(mi); + + final SimpleTraceInterceptor interceptor = new SimpleTraceInterceptor(true); + + try { + interceptor.invokeUnderTrace(mi, log); + fail("Must have propagated the IllegalArgumentException."); + } catch (IllegalArgumentException expected) { + } + + verify(log); + verify(mi); + } + +} diff --git a/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/exposeInvocation.xml b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/exposeInvocation.xml new file mode 100644 index 0000000000000000000000000000000000000000..a44795f043a914d868839f83400ba19f17ef2b35 --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/aop/interceptor/exposeInvocation.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + org.springframework.aop.interceptor.ExposeInvocationInterceptor + + INSTANCE + + + + + + + + + + exposeInvocation,countingBeforeAdvice,nopInterceptor + + + + diff --git a/org.springframework.aop/src/test/java/org/springframework/beans/DerivedTestBean.java b/org.springframework.aop/src/test/java/org/springframework/beans/DerivedTestBean.java new file mode 100644 index 0000000000000000000000000000000000000000..db326041c361d5ff68690851ebe27b34c5f5c15f --- /dev/null +++ b/org.springframework.aop/src/test/java/org/springframework/beans/DerivedTestBean.java @@ -0,0 +1,85 @@ +/* + * Copyright 2002-2007 the original author or authors. + * + * 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 org.springframework.beans; + +import java.io.Serializable; + +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.beans.factory.DisposableBean; + +/** + * @author Juergen Hoeller + * @since 21.08.2003 + */ +public class DerivedTestBean extends TestBean implements Serializable, BeanNameAware, DisposableBean { + + private String beanName; + + private boolean initialized; + + private boolean destroyed; + + + public DerivedTestBean() { + } + + public DerivedTestBean(String[] names) { + if (names == null || names.length < 2) { + throw new IllegalArgumentException("Invalid names array"); + } + setName(names[0]); + setBeanName(names[1]); + } + + public static DerivedTestBean create(String[] names) { + return new DerivedTestBean(names); + } + + + public void setBeanName(String beanName) { + if (this.beanName == null || beanName == null) { + this.beanName = beanName; + } + } + + public String getBeanName() { + return beanName; + } + + public void setSpouseRef(String name) { + setSpouse(new TestBean(name)); + } + + + public void initialize() { + this.initialized = true; + } + + public boolean wasInitialized() { + return initialized; + } + + + public void destroy() { + this.destroyed = true; + } + + public boolean wasDestroyed() { + return destroyed; + } + +}