| /*========================================================================= |
| * Copyright (c) 2002-2014 Pivotal Software, Inc. All Rights Reserved. |
| * This product is protected by U.S. and international copyright |
| * and intellectual property laws. Pivotal products are covered by |
| * more patents listed at http://www.pivotal.io/patents. |
| *========================================================================= |
| */ |
| package com.gemstone.gemfire.cache; |
| |
| import static org.junit.Assert.*; |
| |
| import com.gemstone.gemfire.cache.util.*; |
| import com.gemstone.gemfire.distributed.*; |
| import com.gemstone.gemfire.test.junit.categories.IntegrationTest; |
| |
| import java.util.*; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.experimental.categories.Category; |
| |
| /** |
| * Unit test for basic CacheListener feature. |
| * NOTE: these tests using a loner DistributedSystem and local scope regions |
| * so all the listener features tested are for local listeners being invoked |
| * for local operations. |
| * @author Darrel Schneider |
| * @since 5.0 |
| */ |
| @Category(IntegrationTest.class) |
| public class CacheListenerJUnitTest { |
| |
| private DistributedSystem ds; |
| private Cache c; |
| private int invokeCount; |
| private CacheEvent lastEvent; |
| |
| @Before |
| public void setUp() throws Exception { |
| Properties p = new Properties(); |
| p.setProperty("mcast-port", "0"); |
| p.setProperty("locators", ""); |
| this.ds = DistributedSystem.connect(p); |
| this.c = CacheFactory.create(this.ds); |
| } |
| |
| @After |
| public void tearDown() throws Exception { |
| if (this.c != null) { |
| this.c.close(); |
| this.c = null; |
| } |
| if (this.ds != null) { |
| this.ds.disconnect(); |
| this.ds = null; |
| } |
| } |
| |
| /** |
| * Confirms that listeners are invoked in the correct order |
| */ |
| @Test |
| public void testInvocationOrder() throws Exception { |
| CacheListener cl1 = new CacheListenerAdapter() { |
| public void afterCreate(EntryEvent event) { |
| CacheListenerJUnitTest.this.invokeCount++; |
| assertEquals(1, CacheListenerJUnitTest.this.invokeCount); |
| } |
| }; |
| CacheListener cl2 = new RegionMembershipListenerAdapter() { |
| public void afterCreate(EntryEvent event) { |
| CacheListenerJUnitTest.this.invokeCount++; |
| assertEquals(2, CacheListenerJUnitTest.this.invokeCount); |
| } |
| }; |
| CacheListener cl3 = new RegionRoleListenerAdapter() { |
| public void afterCreate(EntryEvent event) { |
| CacheListenerJUnitTest.this.invokeCount++; |
| assertEquals(3, CacheListenerJUnitTest.this.invokeCount); |
| } |
| }; |
| AttributesFactory af = new AttributesFactory(); |
| af.addCacheListener(cl1); |
| af.addCacheListener(cl2); |
| af.addCacheListener(cl3); |
| Region r = this.c.createRegion("r", af.create()); |
| |
| clearListener(); |
| r.create("key1", "value1"); |
| assertEquals(3, this.invokeCount); |
| |
| CacheListener cl4 = new CacheListenerAdapter() { |
| public void afterCreate(EntryEvent event) { |
| CacheListenerJUnitTest.this.invokeCount++; |
| assertEquals(4, CacheListenerJUnitTest.this.invokeCount); |
| } |
| }; |
| clearListener(); |
| r.getAttributesMutator().addCacheListener(cl4); |
| r.create("key2", "value2"); |
| assertEquals(4, this.invokeCount); |
| } |
| |
| /** |
| * Tests the mutator CacheListener ops to make sure they do the correct thing |
| */ |
| @Test |
| public void testBasicMutator() throws Exception { |
| CacheListener cl1 = new CacheListenerAdapter() {}; |
| CacheListener cl2 = new CacheListenerAdapter() {}; |
| // CacheListener cl3 = new CacheListenerAdapter() {}; |
| AttributesFactory af = new AttributesFactory(); |
| Region r = this.c.createRegion("r", af.create()); |
| RegionAttributes ra = r.getAttributes(); |
| AttributesMutator am = r.getAttributesMutator(); |
| assertEquals(null, ra.getCacheListener()); |
| assertEquals(Collections.EMPTY_LIST, Arrays.asList(ra.getCacheListeners())); |
| try { |
| am.addCacheListener(null); |
| fail("expected IllegalArgumentException"); |
| } catch (IllegalArgumentException expected) { |
| } |
| try { |
| am.removeCacheListener(null); |
| fail("expected IllegalArgumentException"); |
| } catch (IllegalArgumentException expected) { |
| } |
| try { |
| am.initCacheListeners(new CacheListener[]{cl1, null}); |
| fail("expected IllegalArgumentException"); |
| } catch (IllegalArgumentException expected) { |
| } |
| am.addCacheListener(cl1); |
| assertEquals(cl1, ra.getCacheListener()); |
| assertEquals(Arrays.asList(new CacheListener[]{cl1}), Arrays.asList(ra.getCacheListeners())); |
| |
| am.addCacheListener(cl2); |
| assertEquals(Arrays.asList(new CacheListener[]{cl1,cl2}), Arrays.asList(ra.getCacheListeners())); |
| try { |
| ra.getCacheListener(); |
| fail("expected IllegalStateException"); |
| } catch (IllegalStateException expected) { |
| } |
| try { |
| am.setCacheListener(cl1); |
| fail("expected IllegalStateException"); |
| } catch (IllegalStateException expected) { |
| } |
| am.removeCacheListener(cl1); |
| assertEquals(Arrays.asList(new CacheListener[]{cl2}), Arrays.asList(ra.getCacheListeners())); |
| am.removeCacheListener(cl1); |
| assertEquals(Arrays.asList(new CacheListener[]{cl2}), Arrays.asList(ra.getCacheListeners())); |
| am.removeCacheListener(cl2); |
| assertEquals(Arrays.asList(new CacheListener[]{}), Arrays.asList(ra.getCacheListeners())); |
| am.initCacheListeners(new CacheListener[]{cl1, cl2}); |
| assertEquals(Arrays.asList(new CacheListener[]{cl1,cl2}), Arrays.asList(ra.getCacheListeners())); |
| am.initCacheListeners(null); |
| assertEquals(Arrays.asList(new CacheListener[]{}), Arrays.asList(ra.getCacheListeners())); |
| am.initCacheListeners(new CacheListener[]{}); |
| assertEquals(Arrays.asList(new CacheListener[]{}), Arrays.asList(ra.getCacheListeners())); |
| } |
| |
| private void clearListener() { |
| this.invokeCount = 0; |
| this.lastEvent = null; |
| } |
| /** |
| * Tests the local afterRegionCreate event |
| */ |
| @Test |
| public void testAfterRegionCreate() throws Exception { |
| CacheListener cl1 = new CacheListenerAdapter() { |
| public void afterRegionCreate(RegionEvent event) { |
| CacheListenerJUnitTest.this.invokeCount++; |
| CacheListenerJUnitTest.this.lastEvent = event; |
| } |
| }; |
| AttributesFactory af = new AttributesFactory(); |
| af.addCacheListener(cl1); |
| clearListener(); |
| Region r = this.c.createRegion("r", af.create()); |
| assertEquals(1, this.invokeCount); |
| assertTrue(this.lastEvent instanceof RegionEvent); |
| CacheEvent e = this.lastEvent; |
| assertEquals(r, e.getRegion()); |
| assertEquals(this.ds.getDistributedMember(), e.getDistributedMember()); |
| assertEquals(null, e.getCallbackArgument()); |
| assertEquals(Operation.REGION_CREATE, e.getOperation()); |
| assertEquals(false, ((RegionEvent)e).isReinitializing()); |
| assertEquals(false, e.isOriginRemote()); |
| assertEquals(false, e.isExpiration()); |
| assertEquals(false, e.isDistributed()); |
| } |
| |
| @Test |
| public void testTxPutThatIsCreate() throws Exception { |
| CacheListener cl1 = new CacheListenerAdapter() { |
| public void afterUpdate(EntryEvent e) { |
| CacheListenerJUnitTest.this.invokeCount = 2; |
| CacheListenerJUnitTest.this.lastEvent = e; |
| } |
| public void afterCreate(EntryEvent e) { |
| CacheListenerJUnitTest.this.invokeCount = 1; |
| CacheListenerJUnitTest.this.lastEvent = e; |
| } |
| }; |
| AttributesFactory af = new AttributesFactory(); |
| af.addCacheListener(cl1); |
| clearListener(); |
| Region r = this.c.createRegion("r", af.create()); |
| r.put("key1", "value1-0"); |
| assertEquals(1, this.invokeCount); |
| assertEquals(Operation.CREATE, this.lastEvent.getOperation()); |
| |
| clearListener(); |
| r.put("key1", "value1-1"); |
| assertEquals(2, this.invokeCount); |
| assertEquals(Operation.UPDATE, this.lastEvent.getOperation()); |
| |
| r.localDestroy("key1"); |
| |
| // now try it with a transaction |
| TransactionListener tl1 = new TransactionListenerAdapter() { |
| public void afterRollback(TransactionEvent e) { |
| CacheListenerJUnitTest.this.invokeCount = 1; |
| assertEquals(1, e.getEvents().size()); |
| CacheListenerJUnitTest.this.lastEvent = e.getEvents().get(0); |
| } |
| }; |
| CacheTransactionManager ctm = this.c.getCacheTransactionManager(); |
| ctm.addListener(tl1); |
| |
| ctm.begin(); |
| clearListener(); |
| r.put("key1", "value1-0"); |
| assertEquals(0, this.invokeCount); |
| assertNull(this.lastEvent); |
| |
| clearListener(); |
| r.put("key1", "value1-1"); |
| assertEquals(0, this.invokeCount); |
| assertNull(this.lastEvent); |
| clearListener(); |
| ctm.rollback(); |
| assertEquals(1, this.invokeCount); |
| assertEquals(Operation.CREATE, this.lastEvent.getOperation()); |
| |
| ctm.begin(); |
| clearListener(); |
| r.put("key1", "value1-0"); |
| assertEquals(0, this.invokeCount); |
| assertNull(this.lastEvent); |
| |
| clearListener(); |
| r.put("key1", "value1-1"); |
| assertEquals(0, this.invokeCount); |
| assertNull(this.lastEvent); |
| clearListener(); |
| ctm.commit(); |
| assertEquals(1, this.invokeCount); |
| assertEquals(Operation.CREATE, this.lastEvent.getOperation()); |
| |
| } |
| |
| @Test |
| public void testTxOpOrder() throws Exception { |
| AttributesFactory af = new AttributesFactory(); |
| clearListener(); |
| Region r = this.c.createRegion("r", af.create()); |
| |
| TransactionListener tl1 = new TransactionListenerAdapter() { |
| public void afterRollback(TransactionEvent e) { |
| assertEquals(3, e.getEvents().size()); |
| String[] keys = new String[] { |
| (String)((EntryEvent)e.getEvents().get(0)).getKey(), |
| (String)((EntryEvent)e.getEvents().get(1)).getKey(), |
| (String)((EntryEvent)e.getEvents().get(2)).getKey()}; |
| assertEquals(Arrays.asList(new String[]{"b", "c", "a"}), |
| Arrays.asList(keys)); |
| CacheListenerJUnitTest.this.invokeCount = 1; |
| } |
| }; |
| CacheTransactionManager ctm = this.c.getCacheTransactionManager(); |
| ctm.addListener(tl1); |
| |
| ctm.begin(); |
| clearListener(); |
| r.put("b", "value1"); |
| r.put("c", "value2"); |
| r.put("a", "value3"); |
| ctm.rollback(); |
| assertEquals(1, this.invokeCount); |
| } |
| |
| @Test |
| public void testMultiRegionTxOpOrder() throws Exception { |
| AttributesFactory af = new AttributesFactory(); |
| clearListener(); |
| Region r1 = this.c.createRegion("r1", af.create()); |
| Region r2 = r1.createSubregion("r2", af.create()); |
| Region r3 = r2.createSubregion("r3", af.create()); |
| |
| TransactionListener tl1 = new TransactionListenerAdapter() { |
| public void afterCommit(TransactionEvent e) { |
| assertEquals(3, e.getEvents().size()); |
| String[] keys = new String[] { |
| (String)((EntryEvent)e.getEvents().get(0)).getKey(), |
| (String)((EntryEvent)e.getEvents().get(1)).getKey(), |
| (String)((EntryEvent)e.getEvents().get(2)).getKey()}; |
| assertEquals(Arrays.asList(new String[]{"b", "c", "a"}), |
| Arrays.asList(keys)); |
| CacheListenerJUnitTest.this.invokeCount = 1; |
| } |
| }; |
| CacheTransactionManager ctm = this.c.getCacheTransactionManager(); |
| ctm.addListener(tl1); |
| |
| ctm.begin(); |
| clearListener(); |
| r2.put("b", "value1"); |
| r3.put("c", "value2"); |
| r1.put("a", "value3"); |
| ctm.commit(); |
| assertEquals(1, this.invokeCount); |
| } |
| } |