blob: 9bdaced526b94c8a7df6969c155c334842185def [file] [log] [blame]
/*=========================================================================
* 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);
}
}