Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.rave.synchronization; import org.apache.rave.service.LockService; import org.apache.rave.synchronization.annotation.Synchronized; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.junit.Before; import org.junit.Test; import org.springframework.aop.TargetClassAware; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import static org.easymock.EasyMock.*; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; public class SynchronizingAspectTest { private LockService lockService; private SynchronizingAspect aspect; @Before public void setup() { lockService = createMock(LockService.class); aspect = new SynchronizingAspect(lockService); } @Test public void testStaticDiscriminatorStaticIdEmptyCondition() throws Throwable { String expectedDiscriminator = "StaticDiscriminator"; String expectedId = "staticId"; String expectedResult = "testStaticDiscriminatorStaticIdEmptyCondition"; TestService service = new DefaultTestService(); Method expectedMethod = service.getClass() .getDeclaredMethod("testStaticDiscriminatorStaticIdEmptyCondition", TestObject.class); TestObject argument = new TestObject(1L, "Jesse"); Object[] joinPointArgs = { argument }; ProceedingJoinPoint joinPoint = prepareJoinPoint(expectedDiscriminator, expectedId, service, expectedMethod, argument, joinPointArgs); String result = (String) aspect.synchronizeInvocation(joinPoint); assertThat(result, is(expectedResult)); } @Test public void testStaticDiscriminatorStaticIdEmptyConditionJdkProxy() throws Throwable { //Test to get coverage over code paths hit when a proxy is being used for the target class String expectedDiscriminator = "StaticDiscriminator"; String expectedId = "staticId"; String expectedResult = "testStaticDiscriminatorStaticIdEmptyCondition"; InvocationHandler handler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("getTargetClass")) { return DefaultTestService.class; } else if (method.getName().equals("testStaticDiscriminatorStaticIdEmptyCondition")) { return "testStaticDiscriminatorStaticIdEmptyCondition"; } else { throw new RuntimeException(); } } }; TestService service = (TestService) Proxy.newProxyInstance(DefaultTestService.class.getClassLoader(), new Class[] { TestService.class, TargetClassAware.class }, handler); Method expectedMethod = service.getClass() .getDeclaredMethod("testStaticDiscriminatorStaticIdEmptyCondition", TestObject.class); TestObject argument = new TestObject(1L, "Jesse"); Object[] joinPointArgs = { argument }; ProceedingJoinPoint joinPoint = prepareJoinPoint(expectedDiscriminator, expectedId, service, expectedMethod, argument, joinPointArgs); String result = (String) aspect.synchronizeInvocation(joinPoint); assertThat(result, is(expectedResult)); } @Test public void testStaticDiscriminatorDynamicIdDynamicCondition() throws Throwable { String expectedDiscriminator = "StaticDiscriminator"; String expectedId = String.valueOf(1L); String expectedResult = "testStaticDiscriminatorDynamicIdDynamicCondition"; TestService service = new DefaultTestService(); Method expectedMethod = service.getClass() .getDeclaredMethod("testStaticDiscriminatorDynamicIdDynamicCondition", TestObject.class); TestObject argument = new TestObject(1L, "Jesse"); Object[] joinPointArgs = { argument }; ProceedingJoinPoint joinPoint = prepareJoinPoint(expectedDiscriminator, expectedId, service, expectedMethod, argument, joinPointArgs); String result = (String) aspect.synchronizeInvocation(joinPoint); assertThat(result, is(expectedResult)); } @Test public void testStaticDiscriminatorDynamicIdDynamicConditionConditionFails() throws Throwable { String expectedDiscriminator = "StaticDiscriminator"; String expectedId = String.valueOf(1L); String expectedResult = "testStaticDiscriminatorDynamicIdDynamicCondition"; TestService service = new DefaultTestService(); Method expectedMethod = service.getClass() .getDeclaredMethod("testStaticDiscriminatorDynamicIdDynamicCondition", TestObject.class); TestObject argument = new TestObject(-1L, "Jesse"); Object[] joinPointArgs = { argument }; ProceedingJoinPoint joinPoint = prepareJoinPoint(expectedDiscriminator, expectedId, service, expectedMethod, argument, joinPointArgs); String result = (String) aspect.synchronizeInvocation(joinPoint); assertThat(result, is(expectedResult)); } @Test public void synchronizePointcutCoverageTest() { aspect.synchronizePointcut(); } @Test public void expressionCacheBranchesCoverageTest() throws Throwable { //calling twice in a row should warm up the expression caches and cover those branches testStaticDiscriminatorDynamicIdDynamicCondition(); reset(lockService); testStaticDiscriminatorDynamicIdDynamicCondition(); } private ProceedingJoinPoint prepareJoinPoint(String expectedDiscriminator, String expectedId, TestService service, Method expectedMethod, TestObject argument, Object[] joinPointArgs) throws Throwable { MethodSignature methodSignature = createMock(MethodSignature.class); expect(methodSignature.getMethod()).andReturn(expectedMethod); replay(methodSignature); ProceedingJoinPoint joinPoint = createMock(ProceedingJoinPoint.class); expect(joinPoint.getSignature()).andReturn(methodSignature); expect(joinPoint.getTarget()).andReturn(service); expect(joinPoint.getArgs()).andReturn(joinPointArgs); expect(joinPoint.proceed()).andReturn(expectedMethod.invoke(service, argument)); replay(joinPoint); Lock lock = new ReentrantLock(); expect(lockService.borrowLock(expectedDiscriminator, expectedId)).andReturn(lock); lockService.returnLock(lock); replay(lockService); return joinPoint; } private interface TestService { public String testStaticDiscriminatorStaticIdEmptyCondition(TestObject testObject); public String testStaticDiscriminatorDynamicIdDynamicCondition(TestObject testObject); } private class DefaultTestService implements TestService { @Synchronized(discriminator = "'StaticDiscriminator'", id = "'staticId'") public String testStaticDiscriminatorStaticIdEmptyCondition(TestObject testObject) { return "testStaticDiscriminatorStaticIdEmptyCondition"; } @Synchronized(discriminator = "'StaticDiscriminator'", id = "#testObject.id", condition = "#testObject.id >= 0") public String testStaticDiscriminatorDynamicIdDynamicCondition(TestObject testObject) { return "testStaticDiscriminatorDynamicIdDynamicCondition"; } } private class TestObject { private long id; private String name; private TestObject() { } private TestObject(long id, String name) { this.id = id; this.name = name; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } }