You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ds...@apache.org on 2015/12/03 23:59:23 UTC

[3/3] incubator-geode git commit: improve OffHeapStorage unit test coverage

improve OffHeapStorage unit test coverage


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

Branch: refs/heads/feature/GEODE-622
Commit: 53bfde8c0476f83622c40edbd73a6d0cbb9c9c66
Parents: e762758
Author: Darrel Schneider <ds...@pivotal.io>
Authored: Thu Dec 3 14:51:05 2015 -0800
Committer: Darrel Schneider <ds...@pivotal.io>
Committed: Thu Dec 3 14:51:05 2015 -0800

----------------------------------------------------------------------
 .../internal/offheap/OffHeapStorage.java        |  21 +--
 .../offheap/OffHeapStorageJUnitTest.java        | 174 +++++++++++++++++++
 2 files changed, 181 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/53bfde8c/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapStorage.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapStorage.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapStorage.java
index 0e41cce..82cbfeb 100755
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapStorage.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/OffHeapStorage.java
@@ -147,6 +147,7 @@ public class OffHeapStorage implements OffHeapMemoryStats {
         result = MAX_SLAB_SIZE;
       }
     }
+    assert result > 0 && result <= MAX_SLAB_SIZE && result <= offHeapMemorySize;
     return result;
   }
   
@@ -191,15 +192,6 @@ public class OffHeapStorage implements OffHeapMemoryStats {
       
       // determine off-heap and slab sizes
       final long maxSlabSize = calcMaxSlabSize(offHeapMemorySize);
-      assert maxSlabSize > 0;
-      
-      // validate sizes
-      if (maxSlabSize > MAX_SLAB_SIZE) {
-        throw new IllegalArgumentException("gemfire.OFF_HEAP_SLAB_SIZE of value " + offHeapMemorySize + " exceeds maximum value of " + MAX_SLAB_SIZE);
-      }
-      if (maxSlabSize > offHeapMemorySize) {
-        throw new IllegalArgumentException("The off heap slab size (which is " + maxSlabSize + "; set it with gemfire.OFF_HEAP_SLAB_SIZE) must be less than or equal to the total size (which is " + offHeapMemorySize + "; set it with gemfire.OFF_HEAP_SLAB_SIZE).");
-      }
       
       final int slabCount = calcSlabCount(maxSlabSize, offHeapMemorySize);
 
@@ -214,9 +206,10 @@ public class OffHeapStorage implements OffHeapMemoryStats {
   }
   
   private static final long MAX_SLAB_SIZE = Integer.MAX_VALUE;
-  private static final long MIN_SLAB_SIZE = 1024;
+  static final long MIN_SLAB_SIZE = 1024;
 
-  private static int calcSlabCount(long maxSlabSize, long offHeapMemorySize) {
+  // non-private for unit test access
+  static int calcSlabCount(long maxSlabSize, long offHeapMemorySize) {
     long result = offHeapMemorySize / maxSlabSize;
     if ((offHeapMemorySize % maxSlabSize) >= MIN_SLAB_SIZE) {
       result++;
@@ -422,13 +415,13 @@ public class OffHeapStorage implements OffHeapMemoryStats {
         if (this.ids == null) {
           return;
         }
-        final InternalDistributedSystem dsToDisconnect = this.ids;
-        this.ids = null; // set null to prevent memory leak after closure!
-        
         if (stayConnectedOnOutOfOffHeapMemory) {
           return;
         }
         
+        final InternalDistributedSystem dsToDisconnect = this.ids;
+        this.ids = null; // set null to prevent memory leak after closure!
+        
         if (dsToDisconnect.getDistributionManager().getRootCause() == null) {
           dsToDisconnect.getDistributionManager().setRootCause(cause);
         }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/53bfde8c/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
index 5a103e2..340cee1 100755
--- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/OffHeapStorageJUnitTest.java
@@ -17,14 +17,29 @@
 package com.gemstone.gemfire.internal.offheap;
 
 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 java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
+import com.gemstone.gemfire.OutOfOffHeapMemoryException;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.distributed.internal.DistributionStats;
+import com.gemstone.gemfire.distributed.internal.InternalLocator;
 import com.gemstone.gemfire.test.junit.categories.UnitTest;
+import com.jayway.awaitility.Awaitility;
 
 @Category(UnitTest.class)
 public class OffHeapStorageJUnitTest {
@@ -104,4 +119,163 @@ public class OffHeapStorageJUnitTest {
       System.clearProperty("gemfire.OFF_HEAP_SLAB_SIZE");
     }
   }
+  @Test
+  public void testCreateOffHeapStorage() {
+    System.setProperty(InternalLocator.FORCE_LOCATOR_DM_TYPE, "true");
+    try {
+      assertEquals(null, OffHeapStorage.createOffHeapStorage(null, null, 0, null));
+    } finally {
+      System.clearProperty(InternalLocator.FORCE_LOCATOR_DM_TYPE);
+    }
+    // TODO: mock the StatiticsFactory and InternalDistributedSystem that createOffHeapStorage require
+    Cache c = new CacheFactory().set("mcast-port", "0").create();
+    try {
+      try {
+        OffHeapStorage.createOffHeapStorage(null, c.getDistributedSystem(), OffHeapStorage.MIN_SLAB_SIZE-1, c.getDistributedSystem());
+      } catch (IllegalArgumentException expected) {
+        expected.getMessage().equals("The amount of off heap memory must be at least " + OffHeapStorage.MIN_SLAB_SIZE + " but it was set to " + (OffHeapStorage.MIN_SLAB_SIZE-1));
+      }
+      try {
+        OffHeapStorage.createOffHeapStorage(null, c.getDistributedSystem(), OffHeapStorage.MIN_SLAB_SIZE, null);
+      } catch (IllegalArgumentException expected) {
+        expected.getMessage().equals("InternalDistributedSystem is null");
+      }
+      MemoryAllocator ma = OffHeapStorage.createOffHeapStorage(null, c.getDistributedSystem(), 1024*1024, c.getDistributedSystem());
+      try {
+        OffHeapMemoryStats stats = ma.getStats();
+        assertEquals(1024*1024, stats.getFreeMemory());
+        assertEquals(1024*1024, stats.getMaxMemory());
+        assertEquals(0, stats.getUsedMemory());
+        assertEquals(0, stats.getCompactions());
+        assertEquals(0, stats.getCompactionTime());
+        assertEquals(0, stats.getFragmentation());
+        assertEquals(1, stats.getFragments());
+        assertEquals(1024*1024, stats.getLargestFragment());
+        assertEquals(0, stats.getObjects());
+        assertEquals(0, stats.getReads());
+
+        stats.incFreeMemory(100);
+        assertEquals(1024*1024+100, stats.getFreeMemory());
+        stats.incFreeMemory(-100);
+        assertEquals(1024*1024, stats.getFreeMemory());
+
+        stats.incMaxMemory(100);
+        assertEquals(1024*1024+100, stats.getMaxMemory());
+        stats.incMaxMemory(-100);
+        assertEquals(1024*1024, stats.getMaxMemory());
+
+        stats.incUsedMemory(100);
+        assertEquals(100, stats.getUsedMemory());
+        stats.incUsedMemory(-100);
+        assertEquals(0, stats.getUsedMemory());
+
+        stats.incObjects(100);
+        assertEquals(100, stats.getObjects());
+        stats.incObjects(-100);
+        assertEquals(0, stats.getObjects());
+
+        stats.incReads();
+        assertEquals(1, stats.getReads());
+
+        stats.setFragmentation(100);
+        assertEquals(100, stats.getFragmentation());
+        stats.setFragmentation(0);
+        assertEquals(0, stats.getFragmentation());
+
+        stats.setFragments(2);
+        assertEquals(2, stats.getFragments());
+        stats.setFragments(1);
+        assertEquals(1, stats.getFragments());
+
+        stats.setLargestFragment(100);
+        assertEquals(100, stats.getLargestFragment());
+        stats.setLargestFragment(1024*1024);
+        assertEquals(1024*1024, stats.getLargestFragment());
+
+        boolean originalEnableClockStats = DistributionStats.enableClockStats;
+        DistributionStats.enableClockStats = true;
+        try {
+          long start = stats.startCompaction();
+          while (stats.startCompaction() == start) {
+            Thread.yield();
+          }
+          stats.endCompaction(start);
+          assertEquals(1, stats.getCompactions());
+          assertTrue(stats.getCompactionTime() > 0);
+        } finally {
+          DistributionStats.enableClockStats = originalEnableClockStats;
+        }
+
+        stats.incObjects(100);
+        stats.incUsedMemory(100);
+        stats.setFragmentation(100);
+        OffHeapStorage ohs = (OffHeapStorage) stats;
+        ohs.initialize(new NullOffHeapMemoryStats());
+        assertEquals(0, stats.getFreeMemory());
+        assertEquals(0, stats.getMaxMemory());
+        assertEquals(0, stats.getUsedMemory());
+        assertEquals(0, stats.getCompactions());
+        assertEquals(0, stats.getCompactionTime());
+        assertEquals(0, stats.getFragmentation());
+        assertEquals(0, stats.getFragments());
+        assertEquals(0, stats.getLargestFragment());
+        assertEquals(0, stats.getObjects());
+        assertEquals(0, stats.getReads());
+        System.setProperty(OffHeapStorage.STAY_CONNECTED_ON_OUTOFOFFHEAPMEMORY_PROPERTY, "true");
+        try {
+          try {
+            ma.allocate(1024*1024+1, null);
+            fail("expected OutOfOffHeapMemoryException");
+          } catch (OutOfOffHeapMemoryException expected) {
+          }
+          assertTrue(c.getDistributedSystem().isConnected());
+          try {
+            ma.allocate(1024*1024+1, null);
+            fail("expected OutOfOffHeapMemoryException");
+          } catch (OutOfOffHeapMemoryException expected) {
+          }
+          assertTrue(c.getDistributedSystem().isConnected());
+        } finally {
+          System.clearProperty(OffHeapStorage.STAY_CONNECTED_ON_OUTOFOFFHEAPMEMORY_PROPERTY);
+        }
+        try {
+          ma.allocate(1024*1024+1, null);
+          fail("expected OutOfOffHeapMemoryException");
+        } catch (OutOfOffHeapMemoryException expected) {
+        }
+        try {
+          ma.allocate(1024*1024+1, null);
+          fail("expected OutOfOffHeapMemoryException");
+        } catch (OutOfOffHeapMemoryException expected) {
+        }
+        Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> {
+          return !c.getDistributedSystem().isConnected();
+        });
+
+      } finally {
+        System.setProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY, "true");
+        try {
+          ma.close();
+        } finally {
+          System.clearProperty(SimpleMemoryAllocatorImpl.FREE_OFF_HEAP_MEMORY_PROPERTY);
+        }
+      }
+   } finally {
+      c.close();
+    }
+  }
+  @Test
+  public void testCalcSlabCount() {
+    final long MSS = OffHeapStorage.MIN_SLAB_SIZE;
+    assertEquals(100, OffHeapStorage.calcSlabCount(MSS*4, MSS*4*100));
+    assertEquals(100, OffHeapStorage.calcSlabCount(MSS*4, (MSS*4*100) + (MSS-1)));
+    assertEquals(101, OffHeapStorage.calcSlabCount(MSS*4, (MSS*4*100) + MSS));
+    assertEquals(Integer.MAX_VALUE, OffHeapStorage.calcSlabCount(MSS, MSS * Integer.MAX_VALUE));
+    assertEquals(Integer.MAX_VALUE, OffHeapStorage.calcSlabCount(MSS, (MSS * Integer.MAX_VALUE) + MSS-1));
+    try {
+      OffHeapStorage.calcSlabCount(MSS, (((long)MSS) * Integer.MAX_VALUE) + MSS);
+      fail("Expected IllegalArgumentException");
+    } catch (IllegalArgumentException expected) {
+    }
+  }
 }