blob: 4ee1356068d55661c7f4e5c2920736ba58e63752 [file] [log] [blame]
/*
* 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 org.apache.geode.internal.offheap;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.SystemOutRule;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.apache.geode.internal.cache.RegionEntry;
/*
* PowerMock used in this test to verify static method MemoryAllocatorImpl.debugLog
*/
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"*.UnitTest"})
@PrepareForTest({MemoryAllocatorImpl.class})
public class ReferenceCountHelperImplTest {
ReferenceCountHelperImpl rchi;
@Rule
public SystemOutRule sor = new SystemOutRule();
@Test
public void doTrackReferenceCountsWithTrackRefsTrueAndTrackFreesTrue() {
rchi = getTrueTrue();
assertTrue(rchi.trackReferenceCounts());
}
@Test
public void doTrackReferenceCountsWithTrackRefsTrueAndTrackFreesFalse() {
rchi = getTrueFalse();
assertTrue(rchi.trackReferenceCounts());
}
@Test
public void doTrackReferenceCountsWithTrackRefsFalseAndTrackFreesTrue() {
rchi = getFalseTrue();
assertFalse(rchi.trackReferenceCounts());
}
@Test
public void doTrackReferenceCountsWithTrackRefsFalseAndTrackFreesFalse() {
rchi = getFalseFalse();
assertFalse(rchi.trackReferenceCounts());
}
@Test
public void doTrackFreedReferenceCountsWithTrackRefsTrueAndTrackFreesTrue() {
rchi = getTrueTrue();
assertTrue(rchi.trackFreedReferenceCounts());
}
@Test
public void doTrackFreedReferenceCountsWithTrackRefsTrueAndTrackFreesFalse() {
rchi = getTrueFalse();
assertFalse(rchi.trackFreedReferenceCounts());
}
@Test
public void doTrackFreedReferenceCountsWithTrackRefsFalseAndTrackFreesTrue() {
rchi = getFalseTrue();
assertTrue(rchi.trackFreedReferenceCounts());
}
@Test
public void doTrackFreedReferenceCountsWithTrackRefsFalseAndTrackFreesFalse() {
rchi = getFalseFalse();
assertFalse(rchi.trackFreedReferenceCounts());
}
@Test
public void doSkipRefCountTrackingWithTrackRefsTrueAndTrackFreesTrue() {
rchi = getTrueTrue();
Object preOwner = rchi.getReferenceCountOwner();
rchi.skipRefCountTracking();
Object postOwner = rchi.getReferenceCountOwner();
assertTrue(postOwner != preOwner); // skip sets owner to SKIP_REF_COUNT_TRACKING
assertFalse(rchi.isRefCountTracking());
Long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
rchi.refCountChanged(address, decRefCount, rc);
List<RefCountChangeInfo> list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
rchi.unskipRefCountTracking();
postOwner = rchi.getReferenceCountOwner();
assertEquals(postOwner, preOwner);
assertTrue(rchi.isRefCountTracking());
}
@Test
public void doSkipRefCountTrackingWithTrackRefsFalseAndTrackFreesTrue() {
rchi = getFalseTrue();
Object preOwner = rchi.getReferenceCountOwner();
assertEquals(null, preOwner); // getReferenceCountOwner returns null if not tracking
rchi.skipRefCountTracking();
assertFalse(rchi.isRefCountTracking());
rchi.unskipRefCountTracking();
assertFalse(rchi.isRefCountTracking()); // system prop not set
}
@Test
public void doSkipRefCountTrackingWithTrackRefsFalseAndTrackFreesFalse() {
rchi = getFalseFalse();
Object preOwner = rchi.getReferenceCountOwner();
assertEquals(null, preOwner); // getReferenceCountOwner returns null if not tracking
rchi.skipRefCountTracking();
assertFalse(rchi.isRefCountTracking());
rchi.unskipRefCountTracking();
assertFalse(rchi.isRefCountTracking()); // system prop not set
}
@Test
public void doSkipRefCountTrackingWithTrackRefsTrueAndTrackFreesFalse() {
rchi = getTrueFalse();
Object preOwner = rchi.getReferenceCountOwner();
rchi.skipRefCountTracking();
Object postOwner = rchi.getReferenceCountOwner();
assertTrue(postOwner != preOwner); // skip sets owner to SKIP_REF_COUNT_TRACKING
assertFalse(rchi.isRefCountTracking());
rchi.unskipRefCountTracking();
postOwner = rchi.getReferenceCountOwner();
assertEquals(postOwner, preOwner);
assertTrue(rchi.isRefCountTracking());
}
@Test
public void doSetReferenceCountOwnerWithTrackRefsTrueAndTrackFreesTrue() {
rchi = getTrueTrue();
String owner = null;
rchi.setReferenceCountOwner(owner);
AtomicInteger ai = rchi.getReenterCount();
assertEquals(0, ai.get());
owner = new String("SomeOwner");
rchi.setReferenceCountOwner(owner);
ai = rchi.getReenterCount();
assertEquals(1, ai.get());
assertEquals(rchi.getReferenceCountOwner(), owner);
String owner2 = new String("SomeOwner2");
rchi.setReferenceCountOwner(owner2);
ai = rchi.getReenterCount();
assertEquals(2, ai.get());
assertTrue(rchi.getReferenceCountOwner() != owner2); // stays original owner until cnt = 0
String owner3 = null;
rchi.setReferenceCountOwner(owner3);
ai = rchi.getReenterCount();
assertEquals(1, ai.get());
assertEquals(rchi.getReferenceCountOwner(), owner);
owner = null;
rchi.setReferenceCountOwner(owner);
ai = rchi.getReenterCount();
assertEquals(0, ai.get());
assertEquals(rchi.getReferenceCountOwner(), null);
RegionEntry re = mock(RegionEntry.class);
rchi.setReferenceCountOwner(re);
ai = rchi.getReenterCount();
assertEquals(1, ai.get());
assertEquals(rchi.getReferenceCountOwner(), re);
Long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
rchi.refCountChanged(address, decRefCount, rc);
List<RefCountChangeInfo> list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
RefCountChangeInfo rcci = list.get(0);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(1, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
decRefCount = true;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(0, list.size());
}
@Test
public void doSetReferenceCountOwnerWithTrackRefsFalseAndTrackFreesTrue() {
rchi = getFalseTrue();
String owner = null;
rchi.setReferenceCountOwner(owner);
assertEquals(rchi.getReferenceCountOwner(), owner);
AtomicInteger ai = rchi.getReenterCount();
assertEquals(null, ai);
}
@Test
public void doSetReferenceCountOwnerWithTrackRefsFalseAndTrackFreesFalse() {
rchi = getFalseFalse();
String owner = null;
rchi.setReferenceCountOwner(owner);
assertEquals(rchi.getReferenceCountOwner(), owner);
AtomicInteger ai = rchi.getReenterCount();
assertEquals(null, ai);
}
@Test
public void doSetReferenceCountOwnerWithTrackRefsTrueAndTrackFreesFalse() {
rchi = getTrueFalse();
String owner = null;
rchi.setReferenceCountOwner(owner);
AtomicInteger ai = rchi.getReenterCount();
assertEquals(0, ai.get());
owner = new String("SomeOwner");
rchi.setReferenceCountOwner(owner);
ai = rchi.getReenterCount();
assertEquals(1, ai.get());
assertEquals(rchi.getReferenceCountOwner(), owner);
String owner2 = new String("SomeOwner2");
rchi.setReferenceCountOwner(owner2);
ai = rchi.getReenterCount();
assertEquals(2, ai.get());
assertTrue(rchi.getReferenceCountOwner() != owner2); // stays original owner until cnt = 0
String owner3 = null;
rchi.setReferenceCountOwner(owner3);
ai = rchi.getReenterCount();
assertEquals(1, ai.get());
assertEquals(rchi.getReferenceCountOwner(), owner);
owner = null;
rchi.setReferenceCountOwner(owner);
ai = rchi.getReenterCount();
assertEquals(0, ai.get());
assertEquals(rchi.getReferenceCountOwner(), null);
}
@Test
public void doCreateReferenceCountOwnerWithTrackRefsTrueAndTrackFreesTrue() {
rchi = getTrueTrue();
Object owner = rchi.createReferenceCountOwner();
assertFalse(owner == null);
AtomicInteger ai = rchi.getReenterCount();
assertEquals(1, ai.get());
owner = null;
rchi.setReferenceCountOwner(owner);
ai = rchi.getReenterCount();
assertEquals(0, ai.get());
assertEquals(rchi.getReferenceCountOwner(), null);
}
@Test
public void doCreateReferenceCountOwnerWithTrackRefsFalseAndTrackFreesTrue() {
rchi = getFalseTrue();
Object owner = rchi.createReferenceCountOwner();
assertTrue(owner == null);
}
@Test
public void doCreateReferenceCountOwnerWithTrackRefsFalseAndTrackFreesFalse() {
rchi = getFalseFalse();
Object owner = rchi.createReferenceCountOwner();
assertTrue(owner == null);
}
@Test
public void doCreateReferenceCountOwnerWithTrackRefsTrueAndTrackFreesFalse() {
rchi = getTrueFalse();
Object owner = rchi.createReferenceCountOwner();
assertFalse(owner == null);
AtomicInteger ai = rchi.getReenterCount();
assertEquals(1, ai.get());
owner = null;
rchi.setReferenceCountOwner(owner);
ai = rchi.getReenterCount();
assertEquals(0, ai.get());
assertEquals(rchi.getReferenceCountOwner(), null);
}
@Test
public void doRefCountChangedNoOwnerWithTrackRefsTrueAndTrackFreesTrue() {
rchi = getTrueTrue();
Long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
rchi.freeRefCountInfo(address); // quick check of free of nonexistent info
Object owner = rchi.getReferenceCountOwner();
assertTrue(owner == null);
rchi.refCountChanged(address, decRefCount, rc);
List<RefCountChangeInfo> list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
RefCountChangeInfo rcci = list.get(0);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(1, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
decRefCount = true;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(2, list.size()); // inc and dec are tracked in different changeinfo objects (?)
rcci = list.get(1);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(2, list.size());
rcci = list.get(1);
assertEquals(1, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
list = rchi.peekRefCountInfo(address);
assertEquals(2, list.size()); // list contains 2 entries from inc/dec done above
List<RefCountChangeInfo> freeInfo = rchi.getFreeRefCountInfo(address);
assertEquals(null, freeInfo); // no freeRefCountInfo calls yet
rchi.freeRefCountInfo(address); // when freed, moved to FreeRefCountInfo list
List<RefCountChangeInfo> freeInfo2 = rchi.getFreeRefCountInfo(address);
assertEquals(2, freeInfo2.size()); // the inc/dec info moved to freeRefCountInfo list
list = rchi.getRefCountInfo(address);
assertEquals(null, list); // the inc/dec ref count list should now be null
}
@Test
public void doRefCountChangedNoOwnerWithTrackRefsFalseAndTrackFreesTrue() {
rchi = getFalseTrue();
Long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
Object owner = rchi.getReferenceCountOwner();
assertTrue(owner == null);
rchi.refCountChanged(address, decRefCount, rc);
List<RefCountChangeInfo> list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
decRefCount = true;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
List<RefCountChangeInfo> freeInfo = rchi.getFreeRefCountInfo(address);
assertEquals(null, freeInfo); // no freeRefCountInfo calls yet
rchi.freeRefCountInfo(address); // noop when not tracking
freeInfo = rchi.getFreeRefCountInfo(address);
assertEquals(null, freeInfo); // should still be null
}
@Test
public void doRefCountChangedNoOwnerWithTrackRefsFalseAndTrackFreesFalse() {
rchi = getFalseFalse();
Long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
Object owner = rchi.getReferenceCountOwner();
assertTrue(owner == null);
rchi.refCountChanged(address, decRefCount, rc);
List<RefCountChangeInfo> list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
decRefCount = true;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
List<RefCountChangeInfo> freeInfo = rchi.getFreeRefCountInfo(address);
assertEquals(null, freeInfo); // no freeRefCountInfo calls yet
rchi.freeRefCountInfo(address); // noop when not tracking
freeInfo = rchi.getFreeRefCountInfo(address);
assertEquals(null, freeInfo); // should still be null
}
@Test
public void doRefCountChangedNoOwnerWithTrackRefsTrueAndTrackFreesFalse() {
rchi = getTrueFalse();
Long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
Object owner = rchi.getReferenceCountOwner();
assertTrue(owner == null);
rchi.refCountChanged(address, decRefCount, rc);
List<RefCountChangeInfo> list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
RefCountChangeInfo rcci = list.get(0);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(1, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
decRefCount = true;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(2, list.size()); // inc and dec are tracked in different changeinfo objects (?)
rcci = list.get(1);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(2, list.size());
rcci = list.get(1);
assertEquals(1, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
list = rchi.peekRefCountInfo(address);
assertEquals(2, list.size()); // list contains 2 entries from inc/dec done above
List<RefCountChangeInfo> freeInfo = rchi.getFreeRefCountInfo(address);
assertEquals(null, freeInfo); // no freeRefCountInfo calls yet
rchi.freeRefCountInfo(address); // when freed, moved to FreeRefCountInfo list
List<RefCountChangeInfo> freeInfo2 = rchi.getFreeRefCountInfo(address);
assertEquals(null, freeInfo2); // not tracking freed info
list = rchi.getRefCountInfo(address);
assertEquals(null, list); // the inc/dec ref count list should now be null
}
@Test
public void doRefCountChangedWithOwnerWithTrackRefsTrueAndTrackFreesTrue() {
rchi = getTrueTrue();
Long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
Object owner = rchi.createReferenceCountOwner();
assertFalse(owner == null);
AtomicInteger ai = rchi.getReenterCount();
assertEquals(1, ai.get());
owner = null;
rchi.setReferenceCountOwner(owner);
ai = rchi.getReenterCount();
assertEquals(0, ai.get());
assertEquals(rchi.getReferenceCountOwner(), null);
owner = rchi.createReferenceCountOwner();
assertFalse(owner == null);
ai = rchi.getReenterCount();
assertEquals(1, ai.get());
rchi.refCountChanged(address, decRefCount, rc);
List<RefCountChangeInfo> list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
RefCountChangeInfo rcci = list.get(0);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(1, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
decRefCount = true;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size()); // inc and dec are tracked in different changeinfo objects (?)
rcci = list.get(0);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.getRefCountInfo(address);
assertEquals(0, list.size());
}
@Test
public void doRefCountChangedWithOwnerWithTrackRefsFalseAndTrackFreesTrue() {
rchi = getFalseTrue();
Long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
Object owner = rchi.createReferenceCountOwner();
assertTrue(owner == null);
rchi.refCountChanged(address, decRefCount, rc);
List<RefCountChangeInfo> list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
decRefCount = true;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list); // inc and dec are tracked in different changeinfo objects (?)
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
List<RefCountChangeInfo> freeInfo = rchi.getFreeRefCountInfo(address);
assertEquals(null, freeInfo); // no freeRefCountInfo calls yet
rchi.freeRefCountInfo(address); // when freed, moved to FreeRefCountInfo list
freeInfo = rchi.getFreeRefCountInfo(address);
assertEquals(null, freeInfo); // the inc/dec info moved to freeRefCountInfo list
}
@Test
public void doRefCountChangedWithOwnerWithTrackRefsFalseAndTrackFreesFalse() {
rchi = getFalseFalse();
Long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
Object owner = rchi.createReferenceCountOwner();
assertTrue(owner == null);
rchi.refCountChanged(address, decRefCount, rc);
List<RefCountChangeInfo> list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
decRefCount = true;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list); // inc and dec are tracked in different changeinfo objects (?)
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
List<RefCountChangeInfo> freeInfo = rchi.getFreeRefCountInfo(address);
assertEquals(null, freeInfo); // no freeRefCountInfo calls yet
rchi.freeRefCountInfo(address); // when freed, moved to FreeRefCountInfo list
freeInfo = rchi.getFreeRefCountInfo(address);
assertEquals(null, freeInfo); // the inc/dec info moved to freeRefCountInfo list
}
@Test
public void doRefCountChangedWithOwnerWithTrackRefsTrueAndTrackFreesFalse() {
rchi = getTrueFalse();
Long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
Object owner = rchi.createReferenceCountOwner();
assertFalse(owner == null);
AtomicInteger ai = rchi.getReenterCount();
assertEquals(1, ai.get());
owner = null;
rchi.setReferenceCountOwner(owner);
ai = rchi.getReenterCount();
assertEquals(0, ai.get());
assertEquals(rchi.getReferenceCountOwner(), null);
owner = rchi.createReferenceCountOwner();
assertFalse(owner == null);
ai = rchi.getReenterCount();
assertEquals(1, ai.get());
rchi.refCountChanged(address, decRefCount, rc);
List<RefCountChangeInfo> list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
RefCountChangeInfo rcci = list.get(0);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(1, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
decRefCount = true;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size()); // inc and dec are tracked in different changeinfo objects (?)
rcci = list.get(0);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(0, list.size());
}
@Test
public void doGetRefCountInfoWithTrackRefsTrueAndTrackFreesTrue() {
rchi = getTrueTrue();
long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
List<RefCountChangeInfo> list = null;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
RefCountChangeInfo rcci = list.get(0);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(1, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
List<RefCountChangeInfo> info = rchi.getRefCountInfo(address); // now getRefCountInfo
assertEquals(1, info.size());
rcci = info.get(0);
assertEquals(1, rcci.getUseCount());
list = rchi.peekRefCountInfo(address);
assertEquals(0, list.size()); // getRefCountInfo leaves list LOCKED (i.e. empty)
}
@Test
public void doRefCountChangedAfterGetRefCountInfoWithTrackRefsTrueAndTrackFreesTrue()
throws Exception {
rchi = getTrueTrue();
long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
List<RefCountChangeInfo> list = null;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
RefCountChangeInfo rcci = list.get(0);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(1, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
List<RefCountChangeInfo> info = rchi.getRefCountInfo(address); // now getRefCountInfo
assertEquals(1, info.size());
rcci = info.get(0);
assertEquals(1, rcci.getUseCount());
list = rchi.peekRefCountInfo(address);
assertEquals(0, list.size()); // getRefCountInfo leaves list LOCKED (i.e. empty)
sor.mute(); // Mute system out
PowerMockito.spy(MemoryAllocatorImpl.class); // Watch the impl for invocation of debugLog
rchi.refCountChanged(address, decRefCount, rc); // this line should fail. no inc after getInfo
// allowed
PowerMockito.verifyStatic(MemoryAllocatorImpl.class);
MemoryAllocatorImpl.debugLog("refCount inced after orphan detected for @1000", true);
decRefCount = true;
rchi.refCountChanged(address, decRefCount, rc); // this line should fail. no inc after getInfo
// allowed
PowerMockito.verifyStatic(MemoryAllocatorImpl.class);
MemoryAllocatorImpl.debugLog("refCount deced after orphan detected for @1000", true);
rchi.freeRefCountInfo(address); // this line should fail. no free after getInfo allowed
PowerMockito.verifyStatic(MemoryAllocatorImpl.class);
MemoryAllocatorImpl.debugLog("freed after orphan detected for @1000", true);
}
@Test
public void doGetRefCountInfoWithTrackRefsFalseAndTrackFreesTrue() {
rchi = getFalseTrue();
long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
List<RefCountChangeInfo> list = rchi.getRefCountInfo(address);
assertEquals(null, list);
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
List<RefCountChangeInfo> info = rchi.getRefCountInfo(address);
assertEquals(null, info);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
rchi.refCountChanged(address, decRefCount, rc); // this will be ignored.
decRefCount = true;
rchi.refCountChanged(address, decRefCount, rc); // this will be ignored.
rchi.freeRefCountInfo(address); // this will be ignored.
}
@Test
public void doGetRefCountInfoWithTrackRefsFalseAndTrackFreesFalse() {
rchi = getFalseFalse();
long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
List<RefCountChangeInfo> list = rchi.getRefCountInfo(address);
assertEquals(null, list);
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
List<RefCountChangeInfo> info = rchi.getRefCountInfo(address);
assertEquals(null, info);
list = rchi.peekRefCountInfo(address);
assertEquals(null, list);
}
@Test
public void doGetRefCountInfoWithTrackRefsTrueAndTrackFreesFalse() {
rchi = getTrueFalse();
long address = (long) 0x1000;
boolean decRefCount = false;
int rc = 1;
List<RefCountChangeInfo> list = null;
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
RefCountChangeInfo rcci = list.get(0);
assertEquals(0, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
rchi.refCountChanged(address, decRefCount, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(1, rcci.getUseCount()); // line 258 of ref cnt helper does not set useCount = 1
// when adding new entry?
List<RefCountChangeInfo> info = rchi.getRefCountInfo(address); // now getRefCountInfo
assertEquals(1, info.size());
rcci = info.get(0);
assertEquals(1, rcci.getUseCount());
list = rchi.peekRefCountInfo(address);
assertEquals(0, list.size()); // getRefCountInfo leaves list LOCKED (i.e. empty)
}
private ReferenceCountHelperImpl getTrueTrue() {
return new ReferenceCountHelperImpl(true, true);
}
private ReferenceCountHelperImpl getTrueFalse() {
return new ReferenceCountHelperImpl(true, false);
}
private ReferenceCountHelperImpl getFalseTrue() {
return new ReferenceCountHelperImpl(false, true);
}
private ReferenceCountHelperImpl getFalseFalse() {
return new ReferenceCountHelperImpl(false, false);
}
private ReferenceCountHelperImpl getHookedImpl() {
return new HookedReferenceCountHelperImpl(true, true);
}
@Test
public void doGetRefCountInfoNonRegionEntryConcurrencyTest() {
rchi = getHookedImpl();
long address = (long) 0x1000;
int rc = 1;
RefCountChangeInfo rcci;
List<RefCountChangeInfo> list = null;
rchi.setReferenceCountOwner("TestOwner"); // assume test identity
rchi.refCountChanged(address, false, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(1, rcci.getUseCount()); // hooked impl simulates a concurrent update, so cnt is >
// expected
rchi.setReferenceCountOwner(null); // sets owner to null and resets count
rchi.setReferenceCountOwner(null); // sets owner to null and resets count
rchi.setReferenceCountOwner("TestOwner2"); // assume new identity
rchi.refCountChanged(address, false, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(2, rcci.getUseCount()); // list is not null, so hook not used
rchi.refCountChanged(address, true, rc); // dec ref count
list = rchi.peekRefCountInfo(address);
assertEquals(2, list.size()); // dec adds new list of stack traces
rcci = list.get(1);
assertEquals(0, rcci.getUseCount()); // cnt starts at 0 for new entries
List<RefCountChangeInfo> info = rchi.getRefCountInfo(address); // now getRefCountInfo
assertEquals(3, info.size()); // hooked impl added one to list
rcci = info.get(2);
assertEquals(0, rcci.getUseCount()); // count starts at 0 for new entries
list = rchi.peekRefCountInfo(address);
assertEquals(0, list.size()); // getRefCountInfo leaves list LOCKED (i.e. empty)
}
@Test
public void doGetRefCountInfoRegionEntryConcurrencyTest() {
rchi = getHookedImpl();
long address = (long) 0x1000;
int rc = 1;
RefCountChangeInfo rcci;
List<RefCountChangeInfo> list = null;
RegionEntry re = mock(RegionEntry.class);
rchi.setReferenceCountOwner(re); // set owner to region entry type
rchi.refCountChanged(address, false, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(1, rcci.getUseCount()); // hooked impl simulates a concurrent update, so cnt is >
// expected
rchi.setReferenceCountOwner(null); // sets owner to null and resets count
rchi.setReferenceCountOwner(null); // sets owner to null and resets count
RegionEntry re2 = mock(RegionEntry.class);
rchi.setReferenceCountOwner(re2); // set owner to region entry type
rchi.refCountChanged(address, false, rc);
list = rchi.peekRefCountInfo(address);
assertEquals(1, list.size());
rcci = list.get(0);
assertEquals(2, rcci.getUseCount()); // list is not null, so hook not used
rchi.refCountChanged(address, true, rc); // dec ref count
list = rchi.peekRefCountInfo(address);
assertEquals(2, list.size()); // dec adds new list of stack traces
rcci = list.get(1);
assertEquals(0, rcci.getUseCount()); // cnt starts at 0 for new entries
List<RefCountChangeInfo> info = rchi.getRefCountInfo(address); // now getRefCountInfo
assertEquals(3, info.size()); // hooked impl added one to list
rcci = info.get(2);
assertEquals(0, rcci.getUseCount()); // count starts at 0 for new entries
list = rchi.peekRefCountInfo(address);
assertEquals(0, list.size()); // getRefCountInfo leaves list LOCKED (i.e. empty)
}
private class HookedReferenceCountHelperImpl extends ReferenceCountHelperImpl {
HookedReferenceCountHelperImpl(boolean trackRefCounts, boolean trackFreedRefCounts) {
super(trackRefCounts, trackFreedRefCounts);
}
protected int refCountChangedTestHookCount = 0;
/*
* Update list of stack traces for address. Hooked SUT should see that the list changed.
*/
@Override
protected void getReferenceCountInfoTestHook(
ConcurrentMap<Long, List<RefCountChangeInfo>> stacktraces, long address) {
List<RefCountChangeInfo> updatedList =
new ArrayList<RefCountChangeInfo>(stacktraces.get(address));
RefCountChangeInfo rcci = new RefCountChangeInfo(false, 0, "TestOwner");
updatedList.add(rcci);
stacktraces.put(address, updatedList);
}
/*
* Reinvoke refCountChanged to update reference count. Hooked SUT should see that the count has
* changed.
*/
@Override
protected void refCountChangedTestHook(Long address, boolean decRefCount, int rc) {
if (refCountChangedTestHookCount == 0) {
refCountChangedTestHookCount++;
refCountChanged(address, decRefCount, rc);
} else {
refCountChangedTestHookCount--;
}
}
}
}