package org.infinispan.notifications.cachelistener; import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertTrue; import static org.testng.AssertJUnit.fail; import java.util.List; import org.infinispan.Cache; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.Configuration; import org.infinispan.container.InternalEntryFactoryImpl; import org.infinispan.distribution.DistributionManager; import org.infinispan.interceptors.locking.ClusteringDependentLogic; import org.infinispan.notifications.IncorrectListenerException; import org.infinispan.notifications.Listener; import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved; import org.infinispan.notifications.cachelistener.annotation.CacheEntryVisited; import org.infinispan.notifications.cachelistener.cluster.ClusterEventManager; import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent; import org.infinispan.notifications.cachelistener.event.Event; import org.infinispan.test.AbstractInfinispanTest; import org.testng.annotations.Test; @Test(groups = "unit", testName = "notifications.cachelistener.ListenerRegistrationTest") public class ListenerRegistrationTest extends AbstractInfinispanTest { private CacheNotifierImpl newNotifier() { CacheNotifierImpl notifier = new CacheNotifierImpl(); Cache mockCache = mock(Cache.class, RETURNS_DEEP_STUBS); Configuration config = mock(Configuration.class, RETURNS_DEEP_STUBS); when(config.clustering().cacheMode()).thenReturn(CacheMode.LOCAL); notifier.injectDependencies(mockCache, new ClusteringDependentLogic.LocalLogic(), null, config, mock(DistributionManager.class), new InternalEntryFactoryImpl(), mock(ClusterEventManager.class)); return notifier; } public void testControl() { Object l = new TestControlListener(); CacheNotifierImpl n = newNotifier(); n.addListener(l); assertEquals(1, n.getListeners().size()); } public void testCacheListenerNoMethods() { Object l = new TestCacheListenerNoMethodsListener(); CacheNotifierImpl n = newNotifier(); n.addListener(l); assertEquals("Hello", l.toString()); assertTrue("No listeners should be registered.", n.getListeners().isEmpty()); // since the valid listener has no methods to listen } public void testNonAnnotatedListener() { Object l = new TestNonAnnotatedListener(); CacheNotifierImpl n = newNotifier(); try { n.addListener(l); fail("Should not accept an un-annotated cache listener"); } catch (IncorrectListenerException icle) { // expected } assertTrue("No listeners should be registered.", n.getListeners().isEmpty()); } public void testNonPublicListener() { Object l = new TestNonPublicListener(); CacheNotifierImpl n = newNotifier(); try { n.addListener(l); fail("Should not accept a private callback class"); } catch (IncorrectListenerException icle) { // expected } assertTrue("No listeners should be registered.", n.getListeners().isEmpty()); } public void testNonPublicListenerMethod() { Object l = new TestNonPublicListenerMethodListener(); CacheNotifierImpl n = newNotifier(); n.addListener(l); // should not fail, should just not register anything assertTrue("No listeners should be registered.", n.getListeners().isEmpty()); } public void testNonVoidReturnTypeMethod() { Object l = new TestNonVoidReturnTypeMethodListener(); CacheNotifierImpl n = newNotifier(); try { n.addListener(l); fail("Should not accept a listener method with a return type"); } catch (IncorrectListenerException icle) { // expected } assertTrue("No listeners should be registered.", n.getListeners().isEmpty()); } public void testIncorrectMethodSignature1() { Object l = new TestIncorrectMethodSignature1Listener(); CacheNotifierImpl n = newNotifier(); try { n.addListener(l); fail("Should not accept a cache listener with a bad method signature"); } catch (IncorrectListenerException icle) { // expected } assertTrue("No listeners should be registered.", n.getListeners().isEmpty()); } public void testIncorrectMethodSignature2() { Object l = new TestIncorrectMethodSignature2Listener(); CacheNotifierImpl n = newNotifier(); try { n.addListener(l); fail("Should not accept a cache listener with a bad method signature"); } catch (IncorrectListenerException icle) { // expected } assertTrue("No listeners should be registered.", n.getListeners().isEmpty()); } public void testIncorrectMethodSignature3() { Object l = new TestIncorrectMethodSignature3Listener(); CacheNotifierImpl n = newNotifier(); try { n.addListener(l); fail("Should not accept a cache listener with a bad method signature"); } catch (IncorrectListenerException icle) { // expected } assertTrue("No listeners should be registered.", n.getListeners().isEmpty()); } public void testUnassignableMethodSignature() { Object l = new TestUnassignableMethodSignatureListener(); CacheNotifierImpl n = newNotifier(); try { n.addListener(l); fail("Should not accept a cache listener with a bad method signature"); } catch (IncorrectListenerException icle) { // expected } assertTrue("No listeners should be registered.", n.getListeners().isEmpty()); } public void testPartlyUnassignableMethodSignature() { Object l = new TestPartlyUnassignableMethodSignatureListener(); CacheNotifierImpl n = newNotifier(); try { n.addListener(l); fail("Should not accept a cache listener with a bad method signature"); } catch (IncorrectListenerException icle) { // expected } } public void testMultipleMethods() { Object l = new TestMultipleMethodsListener(); CacheNotifierImpl n = newNotifier(); n.addListener(l); List invocations = n.cacheEntryVisitedListeners; assertEquals(1, invocations.size()); invocations = n.cacheEntryRemovedListeners; assertEquals(1, invocations.size()); assertEquals(1, n.getListeners().size()); } public void testMultipleAnnotationsOneMethod() { Object l = new TestMultipleAnnotationsOneMethodListener(); CacheNotifierImpl n = newNotifier(); n.addListener(l); List invocations = n.cacheEntryVisitedListeners; assertEquals(1, invocations.size()); invocations = n.cacheEntryRemovedListeners; assertEquals(1, invocations.size()); assertEquals(1, n.getListeners().size()); } public void testMultipleMethodsOneAnnotation() { Object l = new TestMultipleMethodsOneAnnotationListener(); CacheNotifierImpl n = newNotifier(); n.addListener(l); List invocations = n.cacheEntryVisitedListeners; assertEquals(2, invocations.size()); assertEquals(1, n.getListeners().size()); } @Listener static public class TestControlListener { @CacheEntryVisited @CacheEntryRemoved public void callback(Event e) { } } @Listener static public class TestCacheListenerNoMethodsListener { public String toString() { return "Hello"; } } static public class TestNonAnnotatedListener { public String toString() { return "Hello"; } } @Listener static protected class TestNonPublicListener { @CacheEntryVisited public void callback() { } } @Listener static public class TestNonPublicListenerMethodListener { @CacheEntryVisited protected void callback(Event e) { } } @Listener static public class TestNonVoidReturnTypeMethodListener { @CacheEntryVisited public String callback(Event e) { return "Hello"; } } @Listener static public class TestIncorrectMethodSignature1Listener { @CacheEntryVisited public void callback() { } } @Listener static public class TestIncorrectMethodSignature2Listener { @CacheEntryVisited public void callback(Event e, String s) { } } @Listener static public class TestIncorrectMethodSignature3Listener { @CacheEntryVisited public void callback(Event e, String... s) { } } @Listener static public class TestUnassignableMethodSignatureListener { @CacheEntryVisited public void callback(CacheEntryRemovedEvent e) { } } @Listener static public class TestPartlyUnassignableMethodSignatureListener { @CacheEntryVisited @CacheEntryRemoved public void callback(CacheEntryRemovedEvent e) { } } @Listener static public class TestMultipleMethodsListener { @CacheEntryVisited public void callback1(Event e) { } @CacheEntryRemoved public void callback2(Event e) { } } @Listener static public class TestMultipleAnnotationsOneMethodListener { @CacheEntryRemoved @CacheEntryVisited public void callback(Event nme) { } } @Listener static public class TestMultipleMethodsOneAnnotationListener { @CacheEntryVisited public void callback1(Event e) { } @CacheEntryVisited public void callback2(Event e) { } } }