GEODE-624: add unit test for LifeCycleListener Renamed SimpleMemoryAllocatorLifeCycleListener to LifeCycleListener. New methods in RefCountChangeInfo for unit testing. Renamed ReferenceCountHelper method isDuplicate to isSameCaller.
This closes #53 Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/412f2415 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/412f2415 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/412f2415 Branch: refs/heads/feature/GEODE-291 Commit: 412f2415ea6f5fb20346e3bd722d5defc0b606a3 Parents: 9d047b4 Author: Scott Jewell <[email protected]> Authored: Thu Dec 10 10:30:18 2015 -0800 Committer: Darrel Schneider <[email protected]> Committed: Fri Dec 11 13:35:55 2015 -0800 ---------------------------------------------------------------------- .../internal/offheap/RefCountChangeInfo.java | 77 ++++--- .../internal/offheap/ReferenceCountHelper.java | 14 +- .../offheap/LifecycleListenerJUnitTest.java | 222 +++++++++++++++++++ .../offheap/RefCountChangeInfoJUnitTest.java | 140 ++++++++---- ...moryAllocatorLifecycleListenerJUnitTest.java | 147 ------------ 5 files changed, 367 insertions(+), 233 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/412f2415/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/RefCountChangeInfo.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/RefCountChangeInfo.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/RefCountChangeInfo.java index 67688ed..e3b4b1f 100644 --- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/RefCountChangeInfo.java +++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/RefCountChangeInfo.java @@ -29,7 +29,7 @@ public class RefCountChangeInfo extends Throwable { private final String threadName; private final int rc; private final Object owner; - private int dupCount; + private int useCount; public RefCountChangeInfo(boolean decRefCount, int rc, Object owner) { super(decRefCount ? "FREE" : "USED"); @@ -42,11 +42,16 @@ public class RefCountChangeInfo extends Throwable { return this.owner; } - public int getDupCount() { - return this.dupCount; + public int getUseCount() { + return this.useCount; } - public void decDupCount() { - this.dupCount--; + public int incUseCount() { + this.useCount++; + return this.useCount; + } + public int decUseCount() { + this.useCount--; + return this.useCount; } @Override @@ -56,9 +61,9 @@ public class RefCountChangeInfo extends Throwable { ps.print(this.getMessage()); ps.print(" rc="); ps.print(this.rc); - if (this.dupCount > 0) { - ps.print(" dupCount="); - ps.print(this.dupCount); + if (this.useCount > 0) { + ps.print(" useCount="); + ps.print(this.useCount); } ps.print(" by "); ps.print(this.threadName); @@ -75,47 +80,51 @@ public class RefCountChangeInfo extends Throwable { return baos.toString(); } - - public boolean isDuplicate(RefCountChangeInfo other) { + + public boolean isSameCaller(RefCountChangeInfo other) { if (!getMessage().equals(other.getMessage())) return false; - String trace = getStackTraceString(); - String traceOther = other.getStackTraceString(); + Object trace = getStackTraceString(); + Object traceOther = other.getStackTraceString(); if (trace.hashCode() != traceOther.hashCode()) return false; if (trace.equals(traceOther)) { - this.dupCount++; return true; } else { return false; } } - private String stackTraceString; - String getStackTraceString() { - String result = this.stackTraceString; - if (result == null) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(64*1024); - PrintStream spr = new PrintStream(baos); + private Object stackTraceString; - cleanStackTrace(spr); - result = baos.toString(); - this.stackTraceString = result; + Object getStackTraceString() { + Object result = this.stackTraceString; + if (result == null) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(64 * 1024); + PrintStream spr = new PrintStream(baos); + cleanStackTrace(spr); + result = baos.toString(); + this.stackTraceString = result; } return result; } + void setStackTraceString(Object sts) { + stackTraceString = sts; + } + private void cleanStackTrace(PrintStream ps) { - StackTraceElement[] trace = getStackTrace(); - // skip the initial elements from the offheap package - int skip=0; - for (int i=0; i < trace.length; i++) { - if (!trace[i].getClassName().contains("com.gemstone.gemfire.internal.offheap")) { - skip = i; - break; - } + StackTraceElement[] trace = getStackTrace(); + // skip the initial elements from the offheap package + int skip=0; + for (int i=0; i < trace.length; i++) { + if(!(trace[i].toString().contains("com.gemstone.gemfire.internal.offheap"))) { + skip = i; + break; } - for (int i=skip; i < trace.length; i++) { - ps.println("\tat " + trace[i]); - } - } + } + for (int i=skip; i < trace.length; i++) { + ps.println("\tat " + trace[i]); + } +} + } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/412f2415/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ReferenceCountHelper.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ReferenceCountHelper.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ReferenceCountHelper.java index e396060..778b329 100644 --- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ReferenceCountHelper.java +++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/offheap/ReferenceCountHelper.java @@ -170,6 +170,7 @@ public class ReferenceCountHelper { /** * Used internally to report that a reference count has changed. */ + static void refCountChanged(Long address, boolean decRefCount, int rc) { final Object owner = refCountOwner.get(); if (owner == SKIP_REF_COUNT_TRACKING) { @@ -193,16 +194,16 @@ public class ReferenceCountHelper { if (owner instanceof RegionEntry) { // use identity comparison on region entries since sqlf does some wierd stuff in the equals method if (owner == info.getOwner()) { - if (info.getDupCount() > 0) { - info.decDupCount(); + if (info.getUseCount() > 0) { + info.decUseCount(); } else { list.remove(i); } return; } } else if (owner.equals(info.getOwner())) { - if (info.getDupCount() > 0) { - info.decDupCount(); + if (info.getUseCount() > 0) { + info.decUseCount(); } else { list.remove(i); } @@ -223,8 +224,9 @@ public class ReferenceCountHelper { // list.clear(); // } for (RefCountChangeInfo e: list) { - if (e.isDuplicate(info)) { - // No need to add it + if (e.isSameCaller(info)) { + // No need to add it just increment useCount + e.incUseCount(); return; } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/412f2415/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java new file mode 100755 index 0000000..c886e43 --- /dev/null +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/LifecycleListenerJUnitTest.java @@ -0,0 +1,222 @@ +/* + * 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.internal.offheap; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.test.junit.categories.UnitTest; + +/** + * Tests SimpleMemoryAllocatorImpl.LifecycleListener + * + * @author Kirk Lund + */ +@Category(UnitTest.class) +public class LifecycleListenerJUnitTest { + + private final List<LifecycleListenerCallback> afterCreateCallbacks = new ArrayList<LifecycleListenerCallback>(); + private final List<LifecycleListenerCallback> afterReuseCallbacks = new ArrayList<LifecycleListenerCallback>(); + private final List<LifecycleListenerCallback> beforeCloseCallbacks = new ArrayList<LifecycleListenerCallback>(); + private final TestLifecycleListener listener = new TestLifecycleListener(this.afterCreateCallbacks, this.afterReuseCallbacks, this.beforeCloseCallbacks); + + @After + public void tearDown() throws Exception { + LifecycleListener.removeLifecycleListener(this.listener); + this.afterCreateCallbacks.clear(); + this.afterReuseCallbacks.clear(); + this.beforeCloseCallbacks.clear(); + SimpleMemoryAllocatorImpl.freeOffHeapMemory(); + } + + @Test + public void testAddRemoveListener() { + LifecycleListener.addLifecycleListener(this.listener); + LifecycleListener.removeLifecycleListener(this.listener); + + UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), + new UnsafeMemoryChunk[] { slab }); + + Assert.assertEquals(0, this.afterCreateCallbacks.size()); + Assert.assertEquals(0, this.afterReuseCallbacks.size()); + Assert.assertEquals(0, this.beforeCloseCallbacks.size()); + + ma.close(); + + Assert.assertEquals(0, this.afterCreateCallbacks.size()); + Assert.assertEquals(0, this.afterReuseCallbacks.size()); + Assert.assertEquals(0, this.beforeCloseCallbacks.size()); + + LifecycleListener.removeLifecycleListener(this.listener); + } + + @Test + public void testCallbacksAreCalledAfterCreate() { + LifecycleListener.addLifecycleListener(this.listener); + // saj + System.getProperties().put("gemfire.free-off-heap-memory", "true"); + // saj above + UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), + new UnsafeMemoryChunk[] { slab }); + + Assert.assertEquals(1, this.afterCreateCallbacks.size()); + Assert.assertEquals(0, this.afterReuseCallbacks.size()); + Assert.assertEquals(0, this.beforeCloseCallbacks.size()); + + ma.close(); + + Assert.assertEquals(1, this.afterCreateCallbacks.size()); + Assert.assertEquals(0, this.afterReuseCallbacks.size()); + Assert.assertEquals(1, this.beforeCloseCallbacks.size()); + + LifecycleListener.removeLifecycleListener(this.listener); + } + + @Test + public void testCallbacksAreCalledAfterReuse() { + + LifecycleListener.addLifecycleListener(this.listener); + + System.getProperties().put("gemfire.free-off-heap-memory", "false"); + + UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k + SimpleMemoryAllocatorImpl ma = createAllocator(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab }); + + Assert.assertEquals(1, this.afterCreateCallbacks.size()); + Assert.assertEquals(0, this.afterReuseCallbacks.size()); + Assert.assertEquals(0, this.beforeCloseCallbacks.size()); + + ma.close(); + + Assert.assertEquals(1, this.afterCreateCallbacks.size()); + Assert.assertEquals(0, this.afterReuseCallbacks.size()); + Assert.assertEquals(1, this.beforeCloseCallbacks.size()); + + ma = createAllocator(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), null); + + Assert.assertEquals(1, this.afterCreateCallbacks.size()); + Assert.assertEquals(1, this.afterReuseCallbacks.size()); + Assert.assertEquals(1, this.beforeCloseCallbacks.size()); + + SimpleMemoryAllocatorImpl ma2 = createAllocator(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab }); + assertEquals(null, ma2); + + Assert.assertEquals(1, this.afterCreateCallbacks.size()); + Assert.assertEquals(1, this.afterReuseCallbacks.size()); + Assert.assertEquals(1, this.beforeCloseCallbacks.size()); + + ma.close(); + + Assert.assertEquals(1, this.afterCreateCallbacks.size()); + Assert.assertEquals(1, this.afterReuseCallbacks.size()); + Assert.assertEquals(2, this.beforeCloseCallbacks.size()); + } + + private SimpleMemoryAllocatorImpl createAllocator(OutOfOffHeapMemoryListener ooohml, OffHeapMemoryStats ohms, UnsafeMemoryChunk[] slab) { + try { + return SimpleMemoryAllocatorImpl.create(ooohml, ohms, slab); + } catch (IllegalStateException e) { + return null; + } + } + + @Test + public void testCallbacksAreCalledAfterReuseWithFreeTrue() { + + LifecycleListener.addLifecycleListener(this.listener); + + System.getProperties().put("gemfire.free-off-heap-memory", "true"); + + UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k + SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab }); + + Assert.assertEquals(1, this.afterCreateCallbacks.size()); + Assert.assertEquals(0, this.afterReuseCallbacks.size()); + Assert.assertEquals(0, this.beforeCloseCallbacks.size()); + + ma.close(); + + Assert.assertEquals(1, this.afterCreateCallbacks.size()); + Assert.assertEquals(0, this.afterReuseCallbacks.size()); + Assert.assertEquals(1, this.beforeCloseCallbacks.size()); + + slab = new UnsafeMemoryChunk(1024); // 1k + SimpleMemoryAllocatorImpl ma2 = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[] { slab }); + + Assert.assertEquals(2, this.afterCreateCallbacks.size()); + Assert.assertEquals(0, this.afterReuseCallbacks.size()); + Assert.assertEquals(1, this.beforeCloseCallbacks.size()); + + ma.close(); + + Assert.assertEquals(2, this.afterCreateCallbacks.size()); + Assert.assertEquals(0, this.afterReuseCallbacks.size()); + Assert.assertEquals(2, this.beforeCloseCallbacks.size()); + } + + static final class LifecycleListenerCallback { + private final SimpleMemoryAllocatorImpl allocator; + private final long timeStamp; + private final Throwable creationTime; + + LifecycleListenerCallback(SimpleMemoryAllocatorImpl allocator) { + this.allocator = allocator; + this.timeStamp = System.currentTimeMillis(); + this.creationTime = new Exception(); + } + } + + static class TestLifecycleListener implements LifecycleListener { + private final List<LifecycleListenerCallback> afterCreateCallbacks; + private final List<LifecycleListenerCallback> afterReuseCallbacks; + private final List<LifecycleListenerCallback> beforeCloseCallbacks; + + TestLifecycleListener(List<LifecycleListenerCallback> afterCreateCallbacks, List<LifecycleListenerCallback> afterReuseCallbacks, + List<LifecycleListenerCallback> beforeCloseCallbacks) { + this.afterCreateCallbacks = afterCreateCallbacks; + this.afterReuseCallbacks = afterReuseCallbacks; + this.beforeCloseCallbacks = beforeCloseCallbacks; + } + + @Override + public void afterCreate(SimpleMemoryAllocatorImpl allocator) { + this.afterCreateCallbacks.add(new LifecycleListenerCallback(allocator)); + } + + @Override + public void afterReuse(SimpleMemoryAllocatorImpl allocator) { + this.afterReuseCallbacks.add(new LifecycleListenerCallback(allocator)); + } + + @Override + public void beforeClose(SimpleMemoryAllocatorImpl allocator) { + this.beforeCloseCallbacks.add(new LifecycleListenerCallback(allocator)); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/412f2415/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/RefCountChangeInfoJUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/RefCountChangeInfoJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/RefCountChangeInfoJUnitTest.java index fc726ce..99f4ed8 100644 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/RefCountChangeInfoJUnitTest.java +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/RefCountChangeInfoJUnitTest.java @@ -43,65 +43,92 @@ public class RefCountChangeInfoJUnitTest { String notOwner1 = new String("notInfo1"); RefCountChangeInfo refInfo1 = new RefCountChangeInfo(true, 1, owner1); + RefCountChangeInfo refInfo2 = new RefCountChangeInfo(true, 1, notOwner1); assertEquals(owner1, refInfo1.getOwner()); + assertEquals(notOwner1, refInfo2.getOwner()); + assertFalse(refInfo1.getOwner().equals(refInfo2.getOwner())); - try { - assertEquals(owner1, notOwner1); - fail("Expected owner1 != notOwner1"); - } catch (AssertionError e) { - // Ignore expected error - } + } + + @Test + public void testNullOwner() { + + String owner1 = null; + String notOwner1 = new String("notInfo1"); + + RefCountChangeInfo refInfo1 = new RefCountChangeInfo(true, 1, owner1); + RefCountChangeInfo refInfo2 = new RefCountChangeInfo(true, 1, notOwner1); + assertFalse(isOwnerNull(refInfo2.getOwner())); + assertTrue(hasStringLit(refInfo2.toString(), " owner=")); + + assertEquals(owner1, refInfo1.getOwner()); + assertEquals(notOwner1, refInfo2.getOwner()); + assertTrue(isOwnerNull(refInfo1.getOwner())); + assertFalse(hasStringLit(refInfo1.toString(), " owner=")); } + private boolean isOwnerNull(Object own1) { + return own1 == null; + } + + private boolean hasStringLit(String str, String has) { + if(str.indexOf(has) == -1) return false; + return true; + } + @Test - public void testGetDupCount() { + public void testGetUseCount() { String owner1 = new String("Info1"); String owner2 = new String("Info2"); RefCountChangeInfo refInfo1 = new RefCountChangeInfo(true, 1, owner1); - assertEquals(0, refInfo1.getDupCount()); + assertEquals(0, refInfo1.getUseCount()); RefCountChangeInfo refInfo2 = new RefCountChangeInfo(true, 1, owner1); - assertTrue(refInfo1.isDuplicate(refInfo2)); - assertEquals(1, refInfo1.getDupCount()); + assertTrue(refInfo1.isSameCaller(refInfo2)); + refInfo1.incUseCount(); + assertEquals(1, refInfo1.getUseCount()); // owner not used in isDup RefCountChangeInfo refInfo3 = new RefCountChangeInfo(true, 1, owner2); - assertTrue(refInfo1.isDuplicate(refInfo3)); - assertEquals(2, refInfo1.getDupCount()); + assertTrue(refInfo1.isSameCaller(refInfo3)); + refInfo1.incUseCount(); + assertEquals(2, refInfo1.getUseCount()); RefCountChangeInfo refInfo4 = new RefCountChangeInfo(false, 1, owner2); - assertFalse(refInfo1.isDuplicate(refInfo4)); - assertEquals(2, refInfo1.getDupCount()); + assertFalse(refInfo1.isSameCaller(refInfo4)); + assertEquals(2, refInfo1.getUseCount()); } @Test - public void testDecDupCount() { + public void testDecUseCount() { String owner1 = new String("Info1"); String owner2 = new String("Info2"); RefCountChangeInfo refInfo1 = new RefCountChangeInfo(true, 1, owner1); - assertEquals(0, refInfo1.getDupCount()); + assertEquals(0, refInfo1.getUseCount()); RefCountChangeInfo refInfo2 = new RefCountChangeInfo(true, 1, owner1); - assertTrue(refInfo1.isDuplicate(refInfo2)); - assertEquals(1, refInfo1.getDupCount()); + assertTrue(refInfo1.isSameCaller(refInfo2)); + refInfo1.incUseCount(); + assertEquals(1, refInfo1.getUseCount()); - // owner not used in isDuplicate check + // owner not used in isSameCaller check RefCountChangeInfo refInfo3 = new RefCountChangeInfo(true, 1, owner2); - assertTrue(refInfo1.isDuplicate(refInfo3)); - assertEquals(2, refInfo1.getDupCount()); + assertTrue(refInfo1.isSameCaller(refInfo3)); + refInfo1.incUseCount(); + assertEquals(2, refInfo1.getUseCount()); - refInfo1.decDupCount(); - assertEquals(1, refInfo1.getDupCount()); + refInfo1.decUseCount(); + assertEquals(1, refInfo1.getUseCount()); - refInfo1.decDupCount(); - assertEquals(0, refInfo1.getDupCount()); + refInfo1.decUseCount(); + assertEquals(0, refInfo1.getUseCount()); } @@ -116,44 +143,65 @@ public class RefCountChangeInfoJUnitTest { assertEquals(refInfo1.toString(), refInfo2.toString()); RefCountChangeInfo refInfo3 = new RefCountChangeInfo(false, 1, owner1); - try { - assertEquals(refInfo1.toString(), refInfo3.toString()); - fail("expected refInfo1.toString() != refInfo3.toString()"); - } catch (AssertionError e) { - // ignore expected IllegalArgumentException - } + assertFalse(refInfo1.toString().equals(refInfo3.toString())); RefCountChangeInfo refInfo4 = new RefCountChangeInfo(true, 2, owner1); - try { - assertEquals(refInfo1.toString(), refInfo4.toString()); - fail("expected refInfo1.toString() != refInfo4.toString()"); - } catch (AssertionError e) { - // ignore expected IllegalArgumentException - } + assertFalse(refInfo1.toString().equals(refInfo4.toString())); } @Test - public void testIsDuplicate() { + public void testisSameCaller() { String owner1 = new String("Info1"); String owner2 = new String("Info2"); RefCountChangeInfo refInfo1 = new RefCountChangeInfo(true, 1, owner1); - assertEquals(0, refInfo1.getDupCount()); + assertEquals(0, refInfo1.getUseCount()); RefCountChangeInfo refInfo2 = new RefCountChangeInfo(true, 1, owner1); - assertTrue(refInfo1.isDuplicate(refInfo2)); - assertEquals(1, refInfo1.getDupCount()); + assertTrue(refInfo1.isSameCaller(refInfo2)); + refInfo1.incUseCount(); + assertEquals(1, refInfo1.getUseCount()); + String str = refInfo1.toString(); + str = refInfo1.toString(); + + assertTrue(hasStringLit(refInfo1.toString(), " useCount=1")); - RefCountChangeInfo refInfo3 = new RefCountChangeInfo(false, 1, owner1); - assertFalse(refInfo1.isDuplicate(refInfo3)); - assertEquals(1, refInfo1.getDupCount()); + RefCountChangeInfo refInfo3 = new RefCountChangeInfo(false, 1, owner1); + assertFalse(refInfo1.isSameCaller(refInfo3)); + assertEquals(1, refInfo1.getUseCount()); + RefCountChangeInfo refInfo4 = new RefCountChangeInfo(true, 1, owner2); - assertTrue(refInfo1.isDuplicate(refInfo4)); - assertEquals(2, refInfo1.getDupCount()); + assertTrue(refInfo1.isSameCaller(refInfo4)); + refInfo1.incUseCount(); + assertEquals(2, refInfo1.getUseCount()); + + assertTrue(hasStringLit(refInfo1.toString(), " useCount=2")); + + refInfo1.setStackTraceString("not_the_same"); + assertFalse(refInfo1.isSameCaller(refInfo4)); + assertEquals(2, refInfo1.getUseCount()); + refInfo1.setStackTraceString(null); + + refInfo1.setStackTraceString(new SameHashDifferentTrace()); + refInfo4.setStackTraceString(new SameHashDifferentTrace()); + assertFalse(refInfo1.isSameCaller(refInfo4)); + assertEquals(2, refInfo1.getUseCount()); } + class SameHashDifferentTrace { + + public int hashCode() { + return 1; + } + + public boolean equals(Object notused) { + return false; + } + } + + } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/412f2415/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorLifecycleListenerJUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorLifecycleListenerJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorLifecycleListenerJUnitTest.java deleted file mode 100755 index 2df8656..0000000 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/offheap/SimpleMemoryAllocatorLifecycleListenerJUnitTest.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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.internal.offheap; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.List; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -import com.gemstone.gemfire.test.junit.categories.UnitTest; - -/** - * Tests SimpleMemoryAllocatorImpl.LifecycleListener - * - * @author Kirk Lund - */ -@Category(UnitTest.class) -public class SimpleMemoryAllocatorLifecycleListenerJUnitTest { - - private final List<LifecycleListenerCallback> afterCreateCallbacks = new ArrayList<LifecycleListenerCallback>(); - private final List<LifecycleListenerCallback> afterReuseCallbacks = new ArrayList<LifecycleListenerCallback>(); - private final List<LifecycleListenerCallback> beforeCloseCallbacks = new ArrayList<LifecycleListenerCallback>(); - private final TestLifecycleListener listener = new TestLifecycleListener( - this.afterCreateCallbacks, this.afterReuseCallbacks, this.beforeCloseCallbacks); - - @After - public void tearDown() throws Exception { - LifecycleListener.removeLifecycleListener(this.listener); - this.afterCreateCallbacks.clear(); - this.afterReuseCallbacks.clear(); - this.beforeCloseCallbacks.clear(); - SimpleMemoryAllocatorImpl.freeOffHeapMemory(); - } - - @Test - public void testAddRemoveListener() { - LifecycleListener.addLifecycleListener(this.listener); - LifecycleListener.removeLifecycleListener(this.listener); - - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - - Assert.assertEquals(0, this.afterCreateCallbacks.size()); - Assert.assertEquals(0, this.afterReuseCallbacks.size()); - Assert.assertEquals(0, this.beforeCloseCallbacks.size()); - - ma.close(); - - Assert.assertEquals(0, this.afterCreateCallbacks.size()); - Assert.assertEquals(0, this.afterReuseCallbacks.size()); - Assert.assertEquals(0, this.beforeCloseCallbacks.size()); - } - - @Test - public void testCallbacksAreCalledAfterCreate() { - LifecycleListener.addLifecycleListener(this.listener); - - UnsafeMemoryChunk slab = new UnsafeMemoryChunk(1024); // 1k - SimpleMemoryAllocatorImpl ma = SimpleMemoryAllocatorImpl.create(new NullOutOfOffHeapMemoryListener(), new NullOffHeapMemoryStats(), new UnsafeMemoryChunk[]{slab}); - - Assert.assertEquals(1, this.afterCreateCallbacks.size()); - Assert.assertEquals(0, this.afterReuseCallbacks.size()); - Assert.assertEquals(0, this.beforeCloseCallbacks.size()); - - ma.close(); - - Assert.assertEquals(1, this.afterCreateCallbacks.size()); - Assert.assertEquals(0, this.afterReuseCallbacks.size()); - Assert.assertEquals(1, this.beforeCloseCallbacks.size()); - } - - static final class LifecycleListenerCallback { - private final SimpleMemoryAllocatorImpl allocator; - private final long timeStamp; - private final Throwable creationTime; - LifecycleListenerCallback(SimpleMemoryAllocatorImpl allocator) { - this.allocator = allocator; - this.timeStamp = System.currentTimeMillis(); - this.creationTime = new Exception(); - } - SimpleMemoryAllocatorImpl getAllocator() { - return this.allocator; - } - Throwable getStackTrace() { - return this.creationTime; - } - long getCreationTime() { - return this.timeStamp; - } - @Override - public String toString() { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - pw.print(new StringBuilder(). - append(super.toString()). - append(" created at "). - append(this.timeStamp). - append(" by ").toString()); - this.creationTime.printStackTrace(pw); - return sw.toString(); - } - } - - static class TestLifecycleListener implements LifecycleListener { - private final List<LifecycleListenerCallback> afterCreateCallbacks; - private final List<LifecycleListenerCallback> afterReuseCallbacks; - private final List<LifecycleListenerCallback> beforeCloseCallbacks; - TestLifecycleListener(List<LifecycleListenerCallback> afterCreateCallbacks, - List<LifecycleListenerCallback> afterReuseCallbacks, - List<LifecycleListenerCallback> beforeCloseCallbacks) { - this.afterCreateCallbacks = afterCreateCallbacks; - this.afterReuseCallbacks = afterReuseCallbacks; - this.beforeCloseCallbacks = beforeCloseCallbacks; - } - @Override - public void afterCreate(SimpleMemoryAllocatorImpl allocator) { - this.afterCreateCallbacks.add(new LifecycleListenerCallback(allocator)); - } - @Override - public void afterReuse(SimpleMemoryAllocatorImpl allocator) { - this.afterReuseCallbacks.add(new LifecycleListenerCallback(allocator)); - } - @Override - public void beforeClose(SimpleMemoryAllocatorImpl allocator) { - this.beforeCloseCallbacks.add(new LifecycleListenerCallback(allocator)); - } - } -}
