geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dschnei...@apache.org
Subject [26/52] [abbrv] incubator-geode git commit: GEODE-787: MemoryIndexStore needs unit tests
Date Fri, 29 Jan 2016 01:16:43 GMT
GEODE-787: MemoryIndexStore needs unit tests

Minor refactoring and adding of unit tests
Long term plan is to remove the reference to the cache


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/45d5eda8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/45d5eda8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/45d5eda8

Branch: refs/heads/feature/GEODE-831
Commit: 45d5eda8f536734470ea82924679ed5e9e05b2c1
Parents: 2757f63
Author: Jason Huynh <huynhja@gmail.com>
Authored: Mon Jan 18 17:03:30 2016 -0800
Committer: Jason Huynh <huynhja@gmail.com>
Committed: Tue Jan 26 10:46:09 2016 -0800

----------------------------------------------------------------------
 .../query/internal/index/MemoryIndexStore.java  |  67 ++--
 .../internal/cache/GemFireCacheImpl.java        |   7 +
 .../index/MemoryIndexStoreJUnitTest.java        | 396 +++++++++++++++++++
 ...exStoreWithInplaceModificationJUnitTest.java |  54 +++
 4 files changed, 501 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/45d5eda8/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStore.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStore.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStore.java
index 41de5ea..20a7a4f 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStore.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStore.java
@@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentNavigableMap;
 import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import com.gemstone.gemfire.cache.Cache;
 import com.gemstone.gemfire.cache.EntryDestroyedException;
 import com.gemstone.gemfire.cache.Region;
 import com.gemstone.gemfire.cache.RegionAttributes;
@@ -66,6 +67,7 @@ public class MemoryIndexStore implements IndexStore {
 
   private InternalIndexStatistics internalIndexStats;
 
+  private Cache cache;
   private Region region;
   private boolean indexOnRegionKeys;
   private boolean indexOnValues;
@@ -80,16 +82,22 @@ public class MemoryIndexStore implements IndexStore {
   
   public MemoryIndexStore(Region region,
       InternalIndexStatistics internalIndexStats) {
-    this.region = region;
-    RegionAttributes ra = region.getAttributes();
-    // Initialize the reverse-map if in-place modification is set by the
-    // application.
-    if (IndexManager.isObjectModificationInplace()) {
-      this.entryToValuesMap = new ConcurrentHashMap(ra.getInitialCapacity(),
-          ra.getLoadFactor(), ra.getConcurrencyLevel());
-    }
-    this.internalIndexStats = internalIndexStats;
+    this(region, internalIndexStats, GemFireCacheImpl.getInstance());
   }
+  
+  public MemoryIndexStore(Region region,
+	      InternalIndexStatistics internalIndexStats, Cache cache) {
+	    this.region = region;
+	    RegionAttributes ra = region.getAttributes();
+	    // Initialize the reverse-map if in-place modification is set by the
+	    // application.
+	    if (IndexManager.isObjectModificationInplace()) {
+	      this.entryToValuesMap = new ConcurrentHashMap(ra.getInitialCapacity(),
+	          ra.getLoadFactor(), ra.getConcurrencyLevel());
+	    }
+	    this.internalIndexStats = internalIndexStats;
+	    this.cache = cache;
+	  }
 
   @Override
   public void updateMapping(Object newKey, Object oldKey, RegionEntry entry, Object oldValue)
@@ -285,20 +293,13 @@ public class MemoryIndexStore implements IndexStore {
     }
   }
 
-  public boolean basicRemoveMapping(Object key, RegionEntry entry, boolean findOldKey)
+  protected boolean basicRemoveMapping(Object key, RegionEntry entry, boolean findOldKey)
       throws IMQException {
     boolean found = false;
     boolean possiblyAlreadyRemoved = false;
     try {
       boolean retry = false;
-      Object newKey;
-      if (IndexManager.isObjectModificationInplace()
-          && this.entryToValuesMap.containsKey(entry)) {
-        newKey = this.entryToValuesMap.get(entry);
-      }
-      else {
-        newKey = TypeUtils.indexKeyFor(key);
-      }
+      Object newKey = convertToIndexKey(key, entry);
       if (DefaultQuery.testHook != null) {
         DefaultQuery.testHook.doTestHook("ATTEMPT_REMOVE");
       }
@@ -392,6 +393,19 @@ public class MemoryIndexStore implements IndexStore {
     return found;
   }
 
+private Object convertToIndexKey(Object key, RegionEntry entry)
+		throws TypeMismatchException {
+	Object newKey;
+	if (IndexManager.isObjectModificationInplace()
+          && this.entryToValuesMap.containsKey(entry)) {
+        newKey = this.entryToValuesMap.get(entry);
+      }
+      else {
+        newKey = TypeUtils.indexKeyFor(key);
+      }
+	return newKey;
+}
+
   /**
    * Convert a RegionEntry or THashSet<RegionEntry> to be consistently a
    * Collection
@@ -589,15 +603,22 @@ public class MemoryIndexStore implements IndexStore {
     protected Iterator valuesIterator;
     protected Object currKey;
     protected Object currValue; //RegionEntry
-    final long iteratorStartTime = GemFireCacheImpl.getInstance().cacheTimeMillis();
-    protected MemoryIndexStoreEntry currentEntry = new MemoryIndexStoreEntry(iteratorStartTime);
+    final long iteratorStartTime;
+    protected MemoryIndexStoreEntry currentEntry;
     
     private MemoryIndexStoreIterator(Map submap,
                                      Object indexKey, Collection keysToRemove) {
-      this.map = submap;
-      this.indexKey = indexKey;
-      this.keysToRemove = keysToRemove;
+      this (submap, indexKey, keysToRemove, GemFireCacheImpl.getInstance().cacheTimeMillis());
     }
+    
+    private MemoryIndexStoreIterator(Map submap,
+            Object indexKey, Collection keysToRemove, long iteratorStartTime) {
+		this.map = submap;
+		this.indexKey = indexKey;
+		this.keysToRemove = keysToRemove;
+		this.iteratorStartTime = iteratorStartTime;
+		currentEntry = new MemoryIndexStoreEntry(iteratorStartTime);
+	}
 
     /**
      * This iterator iterates over the CSL map as well as on the collection of

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/45d5eda8/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
index 7565871..4e8f0c9 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
@@ -707,6 +707,13 @@ public class GemFireCacheImpl implements InternalCache, ClientCache,
HasCachePer
   public static GemFireCacheImpl getInstance() {
     return instance;
   }
+  
+  /* Used for testing, retain the old instance in the test and re-set the value when test
completes*/
+  public static GemFireCacheImpl setInstanceForTests(GemFireCacheImpl cache) {
+    GemFireCacheImpl oldInstance = instance;
+	  instance = cache;
+	  return oldInstance;
+  }
 
   /**
    * Returns an existing instance. If a cache does not exist

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/45d5eda8/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStoreJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStoreJUnitTest.java
b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStoreJUnitTest.java
new file mode 100644
index 0000000..0a4a13e
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStoreJUnitTest.java
@@ -0,0 +1,396 @@
+/*
+ * 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 com.gemstone.gemfire.cache.query.internal.index;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.stream.IntStream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.query.QueryService;
+import com.gemstone.gemfire.cache.query.internal.index.AbstractIndex.InternalIndexStatistics;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.internal.cache.RegionEntry;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class MemoryIndexStoreJUnitTest {
+
+	Region region;
+	GemFireCacheImpl cache;
+	InternalIndexStatistics mockStats;
+	MemoryIndexStore store;
+	RegionEntry[] mockEntries;
+	int numMockEntries = 10;
+  GemFireCacheImpl actualInstance;
+  
+	public void subclassPreSetup() {
+		
+	}
+	
+	protected Region createRegion() {
+		return mock(LocalRegion.class);
+	}
+	
+	@Before
+	public void setup() {
+		subclassPreSetup();
+		region = createRegion();
+		cache = mock(GemFireCacheImpl.class);
+		actualInstance = GemFireCacheImpl.setInstanceForTests(cache);
+		mockStats = mock(AbstractIndex.InternalIndexStatistics.class);
+		
+		store = new MemoryIndexStore(region, mockStats);
+		store.setIndexOnValues(true);
+		mockEntries = new RegionEntry[numMockEntries];
+		IntStream.range(0, numMockEntries).forEach(i-> {
+			mockEntries[i] = createRegionEntry(i, new Object());
+		});
+	}
+	
+	@After
+	public void teardown() {
+	  GemFireCacheImpl.setInstanceForTests(actualInstance);
+	}
+	
+	@Test
+	public void testSizeOfStoreReturnsNumberOfKeysAndNotActualNumberOfValues() {
+		IntStream.range(0, 150).forEach(i -> {
+			try {
+				store.addMapping(i % 3, createRegionEntry(i, new Object()));
+			}
+			catch (Exception e) {
+				fail();
+			}
+		});
+		assertEquals(150, numObjectsInStore(store));
+	}
+	
+	@Test
+	public void testAddEnoughEntriesToCreateAConcurrentHashSet() {
+		IntStream.range(0, 150).forEach(i -> {
+			try {
+				store.addMapping(1, createRegionEntry(i, new Object()));
+			}
+			catch (Exception e) {
+				fail();
+			}
+		});
+		assertEquals(150, numObjectsInStore(store));
+	}
+	
+	@Test
+	public void testUpdateAgainstAConcurrentHashSet() throws Exception{
+		IntStream.range(0, 150).forEach(i -> {
+			try {
+				store.addMapping(1, createRegionEntry(1, new Object()));
+			}
+			catch (Exception e) {
+				fail();
+			}
+		});
+		RegionEntry entry = createRegionEntry(1, new Object());	
+		store.addMapping(1, entry);
+		store.updateMapping(2, 1, entry, entry.getValue(null));
+		assertEquals(151, numObjectsInStore(store));
+	}
+	
+	@Test
+	public void testCanAddObjectWithUndefinedKey() throws Exception {
+		store.addMapping(QueryService.UNDEFINED, mockEntries[0]);
+		assertEquals(1, numObjectsIterated(store.get(QueryService.UNDEFINED)));
+		assertEquals(0, numObjectsInStore(store));
+	}
+	
+	@Test
+	public void testCanAddManyObjectsWithUndefinedKey() throws Exception {
+		for (int i = 0; i < mockEntries.length; i++) {
+			store.addMapping(QueryService.UNDEFINED, mockEntries[i]);
+		}
+		assertEquals(mockEntries.length, numObjectsIterated(store.get(QueryService.UNDEFINED)));
+		//Undefined will not return without an explicit get for UNDEFINED);
+		assertEquals(0, numObjectsInStore(store));
+	}
+	
+	@Test
+	public void testIteratorWithStartInclusiveAndNoKeysToRemoveReturnsCorrectNumberOfResults()
throws Exception {
+		addMockedEntries(numMockEntries);
+		assertEquals(2, numObjectsIterated(store.iterator(numMockEntries - 2, true, null)));
+	}
+	
+	@Test
+	public void testIteratorWithStartExclusiveAndNoKeysToRemoveReturnsCorrectNumberOfResults()
throws Exception {
+		addMockedEntries(numMockEntries);
+		assertEquals(1, numObjectsIterated(store.iterator(numMockEntries - 2, false, null)));
+	}
+	
+	
+	@Test
+	public void testIteratorWithStartInclusiveAndKeyToRemoveReturnsCorrectNumberOfResults()
throws Exception {
+		addMockedEntries(numMockEntries);
+		Set keysToRemove = new HashSet();
+		keysToRemove.add("1");
+		assertEquals(9, numObjectsIterated(store.iterator(1, true, keysToRemove)));
+	}
+	
+	@Test
+	public void testIteratorWithStartExclusiveAndKeyToRemoveReturnsCorrectNumberOfResults()
throws Exception {
+		addMockedEntries(numMockEntries);
+		Set keysToRemove = new HashSet();
+		keysToRemove.add("1");
+		assertEquals(8, numObjectsIterated(store.iterator(1, false, keysToRemove)));
+	}
+	
+	@Test
+	public void testStartAndEndInclusiveReturnsCorrectResults() throws Exception {
+		addMockedEntries(numMockEntries);
+		assertEquals(6, numObjectsIterated(store.iterator(1, true, 6, true, null)));
+	}
+	
+	@Test
+	public void testStartInclusiveAndEndExclusiveReturnsCorrectResults() throws Exception {
+		addMockedEntries(numMockEntries);
+		assertEquals(5, numObjectsIterated(store.iterator(1, true, 6, false, null)));
+	}
+	
+	@Test
+	public void testStartExclusiveAndEndExclusiveReturnsCorrectResults() throws Exception {
+		addMockedEntries(numMockEntries);
+		assertEquals(4, numObjectsIterated(store.iterator(1, false, 6, false, null)));
+	}
+	
+	@Test
+	public void testStartExclusiveAndEndInclusiveReturnsCorrectResults() throws Exception {
+		addMockedEntries(numMockEntries);
+		assertEquals(5, numObjectsIterated(store.iterator(1, false, 6, true, null)));
+	}
+	
+	@Test
+	public void testStartIsNull() throws Exception {
+		addMockedEntries(numMockEntries);
+		assertEquals(6, numObjectsIterated(store.iterator(null, false, 6, false, null)));
+	}
+	
+	@Test
+	public void testDescendingIteratorReturnsExpectedOrderOfEntries() throws Exception {
+		RegionEntry mockEntry1 = mockEntries[0];
+		RegionEntry mockEntry2 = mockEntries[1];
+		store.addMapping("1", mockEntry1);
+		store.addMapping("2", mockEntry2);
+		Iterator iteratorFirst = store.descendingIterator(null);
+		assertEquals(2, numObjectsIterated(iteratorFirst));
+		
+		Iterator iterator = store.descendingIterator(null);
+		iterator.hasNext();
+		assertEquals(mockEntry2, ((MemoryIndexStore.MemoryIndexStoreEntry)iterator.next()).getRegionEntry());
+		iterator.hasNext();
+		assertEquals(mockEntry1, ((MemoryIndexStore.MemoryIndexStoreEntry)iterator.next()).getRegionEntry());
+	}
+	
+	@Test
+	public void testDescendingIteratorWithRemovedKeysReturnsExpectedOrderOfEntries() throws
Exception {
+		RegionEntry mockEntry1 = mockEntries[0];
+		RegionEntry mockEntry2 = mockEntries[1];
+		RegionEntry mockEntry3 = mockEntries[2];
+		store.addMapping("1", mockEntry1);
+		store.addMapping("2", mockEntry2);
+		store.addMapping("3", mockEntry3);
+		Set keysToRemove = new HashSet();
+		keysToRemove.add("2");
+		Iterator iteratorFirst = store.descendingIterator(keysToRemove);
+		assertEquals(2, numObjectsIterated(iteratorFirst));
+		
+		//keysToRemove has been modified by the store, we need to readd the key to remove
+		keysToRemove.add("2");
+		Iterator iterator = store.descendingIterator(keysToRemove);
+		iterator.hasNext();
+		assertEquals(mockEntry3, ((MemoryIndexStore.MemoryIndexStoreEntry)iterator.next()).getRegionEntry());
+		iterator.hasNext();
+		assertEquals(mockEntry1, ((MemoryIndexStore.MemoryIndexStoreEntry)iterator.next()).getRegionEntry());
+		assertFalse(iterator.hasNext());
+	}
+	
+	@Test
+	public void testDescendingIteratorWithMultipleRemovedKeysReturnsExpectedOrderOfEntries()
throws Exception {
+		RegionEntry mockEntry1 = mockEntries[0];
+		RegionEntry mockEntry2 = mockEntries[1];
+		RegionEntry mockEntry3 = mockEntries[2];
+		store.addMapping("1", mockEntry1);
+		store.addMapping("2", mockEntry2);
+		store.addMapping("3", mockEntry3);
+		Set keysToRemove = new HashSet();
+		keysToRemove.add("2");
+		keysToRemove.add("1");
+		Iterator iteratorFirst = store.descendingIterator(keysToRemove);
+		assertEquals(1, numObjectsIterated(iteratorFirst));
+		
+		//keysToRemove has been modified by the store, we need to readd the key to remove
+		keysToRemove.add("2");
+		keysToRemove.add("1");
+		Iterator iterator = store.descendingIterator(keysToRemove);
+		iterator.hasNext();
+		assertEquals(mockEntry3, ((MemoryIndexStore.MemoryIndexStoreEntry)iterator.next()).getRegionEntry());
+		assertFalse(iterator.hasNext());
+	}
+	
+	@Test
+	public void testSizeWithKeyArgumentReturnsCorrectSize() throws Exception {
+		RegionEntry mockEntry1 = mockEntries[0];
+		RegionEntry mockEntry2 = mockEntries[1];
+		store.addMapping("1", mockEntry1);
+		store.addMapping("2", mockEntry2);
+		assertEquals(1, store.size("1"));
+	}
+	
+	 @Test
+	  public void testGetReturnsExpectedIteratorValue() throws Exception {
+	    RegionEntry mockEntry1 = mockEntries[0];
+	    RegionEntry mockEntry2 = mockEntries[1];
+	    store.addMapping("1", mockEntry1);
+	    store.addMapping("2", mockEntry2);
+	    assertEquals(1, numObjectsIterated(store.get("1")));
+	  }
+	
+	@Test
+	public void testGetReturnsExpectedIteratorWithMultipleValues() throws Exception {
+		RegionEntry mockEntry1 = mockEntries[0];
+		RegionEntry mockEntry2 = mockEntries[1];
+		RegionEntry mockEntry3 = mockEntries[2];
+		RegionEntry mockEntry4 = mockEntries[3];
+		store.addMapping("1", mockEntry1);
+		store.addMapping("1", mockEntry2);
+		store.addMapping("1", mockEntry3);
+		store.addMapping("2", mockEntry4);
+		assertEquals(3, numObjectsIterated(store.get("1")));
+		assertEquals(4, numObjectsInStore(store));
+	}
+	
+	@Test
+	public void testGetWithIndexOnKeysReturnsExpectedIteratorValues() throws Exception {
+		RegionEntry mockEntry1 = mockEntries[0];
+		RegionEntry mockEntry2 = mockEntries[1];
+		store.setIndexOnValues(false);
+		store.setIndexOnRegionKeys(true);
+		store.addMapping("1", mockEntry1);
+		store.addMapping("2", mockEntry2);
+		assertEquals(1, numObjectsIterated(store.get("1")));
+	}
+
+	@Test
+	public void testCorrectlyRemovesEntryProvidedTheWrongKey() throws Exception {
+		RegionEntry mockEntry1 = mockEntries[0];
+		RegionEntry mockEntry2 = mockEntries[1];
+		store.addMapping("1", mockEntry1);
+		store.addMapping("2", mockEntry2);
+		store.removeMapping("1", mockEntry2);
+		assertEquals(1, numObjectsInStore(store));
+		assertTrue(objectContainedIn(store, mockEntry1));
+	}
+
+	@Test
+	public void testRemoveMappingRemovesFromBackingMap() throws Exception {
+		RegionEntry mockEntry1 = mockEntries[0];
+		RegionEntry mockEntry2 = mockEntries[1];
+		store.addMapping("1", mockEntry1);
+		store.addMapping("2", mockEntry2);
+		store.removeMapping("1", mockEntry1);
+		assertEquals(1, numObjectsInStore(store));
+		assertTrue(objectContainedIn(store, mockEntry2));
+	}
+
+	@Test
+	public void testAddMappingAddsToBackingMap() throws Exception {
+		RegionEntry mockEntry1 = mockEntries[0];
+		RegionEntry mockEntry2 = mockEntries[1];
+		store.addMapping("1", mockEntry1);
+		store.addMapping("2", mockEntry2);
+		assertEquals(2, numObjectsInStore(store));
+		assertTrue(objectContainedIn(store, mockEntry1));
+		assertTrue(objectContainedIn(store, mockEntry2));
+	}
+	
+	@Test
+	public void testClear() throws Exception {
+		RegionEntry mockEntry1 = mockEntries[0];
+		RegionEntry mockEntry2 = mockEntries[1];
+		store.addMapping("1", mockEntry1);
+		store.addMapping("1", mockEntry2);
+		store.clear();
+		assertEquals(0, numObjectsInStore(store));
+	}
+
+	private int numObjectsInStore(MemoryIndexStore store) {
+		Iterator iterator = store.iterator(null);
+		return numObjectsIterated(iterator);
+	}
+
+	private int numObjectsIterated(Iterator iterator) {
+		int count = 0;
+		while (iterator.hasNext()) {
+			iterator.next();
+			count++;
+		}
+		return count;
+	}
+
+	private boolean objectContainedIn(MemoryIndexStore store, Object o) {
+		Iterator iterator = store.valueToEntriesMap.values().iterator();
+		return objectContainedIn(iterator, o);
+	}
+	
+	private boolean objectContainedIn(Iterator iterator, Object o) {
+		while (iterator.hasNext()) {
+			if (iterator.next().equals(o)) {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	private void addMockedEntries(int numEntriesToAdd) {
+		IntStream.range(0, numEntriesToAdd).forEach(i -> {
+			try {
+				store.addMapping(mockEntries[i].getKey(), mockEntries[i]);
+			}
+			catch (Exception e) {
+				fail();
+			}
+		});
+	}
+	
+	private RegionEntry createRegionEntry(Object key, Object value) {
+		RegionEntry mockEntry = mock(RegionEntry.class);
+		when(mockEntry.getValue(any())).thenReturn(value);
+		when(mockEntry.getKey()).thenReturn(key);
+		return mockEntry;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/45d5eda8/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStoreWithInplaceModificationJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStoreWithInplaceModificationJUnitTest.java
b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStoreWithInplaceModificationJUnitTest.java
new file mode 100644
index 0000000..79f8616
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MemoryIndexStoreWithInplaceModificationJUnitTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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 com.gemstone.gemfire.cache.query.internal.index;
+
+import static org.mockito.Mockito.mock;
+
+import static org.mockito.Mockito.when;
+
+import org.junit.After;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionAttributes;
+import com.gemstone.gemfire.internal.cache.LocalRegion;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class MemoryIndexStoreWithInplaceModificationJUnitTest extends MemoryIndexStoreJUnitTest
{
+	
+	public void subclassPreSetup() {
+		IndexManager.INPLACE_OBJECT_MODIFICATION_FOR_TEST = true;
+	}
+	
+	protected Region createRegion() {
+		Region region = mock(LocalRegion.class);
+		RegionAttributes ra = mock(RegionAttributes.class);
+		when(region.getAttributes()).thenReturn(ra);
+		when(ra.getInitialCapacity()).thenReturn(16);
+		when(ra.getLoadFactor()).thenReturn(.75f);
+		when(ra.getConcurrencyLevel()).thenReturn(16);
+		return region;
+	}
+	
+	@After
+	public void resetInplaceModification() {
+		IndexManager.INPLACE_OBJECT_MODIFICATION_FOR_TEST = false;
+	}
+	
+	
+}


Mime
View raw message