use of org.apache.geode.internal.offheap.StoredObject in project geode by apache.
the class EntryEventImplTest method verifyExternalReadMethodsBlockedByRelease.
@Test
public void verifyExternalReadMethodsBlockedByRelease() throws InterruptedException {
LocalRegion region = mock(LocalRegion.class);
when(region.getOffHeap()).thenReturn(true);
StoredObject newValue = mock(StoredObject.class);
when(newValue.hasRefCount()).thenReturn(true);
when(newValue.isSerialized()).thenReturn(true);
when(newValue.retain()).thenReturn(true);
when(newValue.getDeserializedValue(any(), any())).thenReturn("newValue");
final byte[] serializedNewValue = new byte[] { (byte) 'n', (byte) 'e', (byte) 'w' };
when(newValue.getSerializedValue()).thenReturn(serializedNewValue);
StoredObject oldValue = mock(StoredObject.class);
when(oldValue.hasRefCount()).thenReturn(true);
when(oldValue.isSerialized()).thenReturn(true);
when(oldValue.retain()).thenReturn(true);
when(oldValue.getDeserializedValue(any(), any())).thenReturn("oldValue");
final byte[] serializedOldValue = new byte[] { (byte) 'o', (byte) 'l', (byte) 'd' };
when(oldValue.getSerializedValue()).thenReturn(serializedOldValue);
final CountDownLatch releaseCountDown = new CountDownLatch(1);
final TestableEntryEventImpl e = new TestableEntryEventImpl(region, key, newValue, releaseCountDown);
e.setOldValue(oldValue);
assertEquals("newValue", e.getNewValue());
assertEquals("oldValue", e.getOldValue());
final SerializedCacheValue<?> serializableNewValue = e.getSerializedNewValue();
assertEquals(serializedNewValue, serializableNewValue.getSerializedValue());
assertEquals("newValue", serializableNewValue.getDeserializedValue());
final SerializedCacheValue<?> serializableOldValue = e.getSerializedOldValue();
assertEquals(serializedOldValue, serializableOldValue.getSerializedValue());
assertEquals("oldValue", serializableOldValue.getDeserializedValue());
Thread doRelease = new Thread(() -> {
e.release();
});
// release thread will be stuck until releaseCountDown changes
doRelease.start();
Awaitility.await().pollInterval(1, TimeUnit.MILLISECONDS).pollDelay(1, TimeUnit.MILLISECONDS).timeout(15, TimeUnit.SECONDS).until(() -> assertEquals(true, e.isWaitingOnRelease()));
assertEquals(true, e.offHeapOk);
assertEquals(true, doRelease.isAlive());
// Now start a getNewValue. It should block on the release.
Thread doGetNewValue = new Thread(() -> {
e.getAndCacheNewValue();
});
doGetNewValue.start();
// Now start a getOldValue. It should block on the release.
Thread doGetOldValue = new Thread(() -> {
e.getAndCacheOldValue();
});
doGetOldValue.start();
// Now start a getSerializedValue on serializableNewValue. It should block on the release.
Thread doSNVgetSerializedValue = new Thread(() -> {
e.getAndCacheSerializedNew(serializableNewValue);
});
doSNVgetSerializedValue.start();
// Now start a getDeserializedValue on serializableNewValue. It should block on the release.
Thread doSNVgetDeserializedValue = new Thread(() -> {
e.getAndCachDeserializedNew(serializableNewValue);
});
doSNVgetDeserializedValue.start();
// Now start a getSerializedValue on serializableOldValue. It should block on the release.
Thread doSOVgetSerializedValue = new Thread(() -> {
e.getAndCacheSerializedOld(serializableOldValue);
});
doSOVgetSerializedValue.start();
// Now start a getDeserializedValue on serializableOldValue. It should block on the release.
Thread doSOVgetDeserializedValue = new Thread(() -> {
e.getAndCachDeserializedOld(serializableOldValue);
});
doSOVgetDeserializedValue.start();
Awaitility.await().pollInterval(1, TimeUnit.MILLISECONDS).pollDelay(1, TimeUnit.MILLISECONDS).timeout(15, TimeUnit.SECONDS).until(() -> assertEquals(true, e.isAboutToCallGetNewValue() && e.isAboutToCallGetOldValue() && e.isAboutToCallSerializedNew() && e.isAboutToCallDeserializedNew() && e.isAboutToCallSerializedOld() && e.isAboutToCallDeserializedOld()));
// all the threads should now be hung waiting on release; so just wait for a little bit for it
// to improperly finish
doGetNewValue.join(50);
if (e.hasFinishedCallOfGetNewValue()) {
fail("expected doGetNewValue thread to be hung. It completed with " + e.getCachedNewValue());
}
if (e.hasFinishedCallOfGetOldValue()) {
fail("expected doGetOldValue thread to be hung. It completed with " + e.getCachedOldValue());
}
if (e.hasFinishedCallOfSerializedNew()) {
fail("expected doSNVgetSerializedValue thread to be hung. It completed with " + e.getTestCachedSerializedNew());
}
if (e.hasFinishedCallOfDeserializedNew()) {
fail("expected doSNVgetDeserializedValue thread to be hung. It completed with " + e.getCachedDeserializedNew());
}
if (e.hasFinishedCallOfSerializedOld()) {
fail("expected doSOVgetSerializedValue thread to be hung. It completed with " + e.getCachedSerializedOld());
}
if (e.hasFinishedCallOfDeserializedOld()) {
fail("expected doSOVgetDeserializedValue thread to be hung. It completed with " + e.getCachedDeserializedOld());
}
// now signal the release to go ahead
releaseCountDown.countDown();
doRelease.join();
assertEquals(false, e.offHeapOk);
// which should allow getNewValue to complete
Awaitility.await().pollInterval(1, TimeUnit.MILLISECONDS).pollDelay(1, TimeUnit.MILLISECONDS).timeout(15, TimeUnit.SECONDS).until(() -> assertEquals(true, e.hasFinishedCallOfGetNewValue()));
doGetNewValue.join();
if (!(e.getCachedNewValue() instanceof IllegalStateException)) {
// since the release happened before getNewValue we expect it to get an exception
fail("unexpected success of getNewValue. It returned " + e.getCachedNewValue());
}
// which should allow getOldValue to complete
Awaitility.await().pollInterval(1, TimeUnit.MILLISECONDS).pollDelay(1, TimeUnit.MILLISECONDS).timeout(15, TimeUnit.SECONDS).until(() -> assertEquals(true, e.hasFinishedCallOfGetOldValue()));
doGetOldValue.join();
if (!(e.getCachedOldValue() instanceof IllegalStateException)) {
fail("unexpected success of getOldValue. It returned " + e.getCachedOldValue());
}
// which should allow doSNVgetSerializedValue to complete
Awaitility.await().pollInterval(1, TimeUnit.MILLISECONDS).pollDelay(1, TimeUnit.MILLISECONDS).timeout(15, TimeUnit.SECONDS).until(() -> assertEquals(true, e.hasFinishedCallOfSerializedNew()));
doSNVgetSerializedValue.join();
if (!(e.getTestCachedSerializedNew() instanceof IllegalStateException)) {
fail("unexpected success of new getSerializedValue. It returned " + e.getTestCachedSerializedNew());
}
// which should allow doSNVgetDeserializedValue to complete
Awaitility.await().pollInterval(1, TimeUnit.MILLISECONDS).pollDelay(1, TimeUnit.MILLISECONDS).timeout(15, TimeUnit.SECONDS).until(() -> assertEquals(true, e.hasFinishedCallOfDeserializedNew()));
doSNVgetDeserializedValue.join();
if (!(e.getCachedDeserializedNew() instanceof IllegalStateException)) {
fail("unexpected success of new getDeserializedValue. It returned " + e.getCachedDeserializedNew());
}
// which should allow doSOVgetSerializedValue to complete
Awaitility.await().pollInterval(1, TimeUnit.MILLISECONDS).pollDelay(1, TimeUnit.MILLISECONDS).timeout(15, TimeUnit.SECONDS).until(() -> assertEquals(true, e.hasFinishedCallOfSerializedOld()));
doSOVgetSerializedValue.join();
if (!(e.getCachedSerializedOld() instanceof IllegalStateException)) {
fail("unexpected success of old getSerializedValue. It returned " + e.getCachedSerializedOld());
}
// which should allow doSOVgetDeserializedValue to complete
Awaitility.await().pollInterval(1, TimeUnit.MILLISECONDS).pollDelay(1, TimeUnit.MILLISECONDS).timeout(15, TimeUnit.SECONDS).until(() -> assertEquals(true, e.hasFinishedCallOfDeserializedOld()));
doSOVgetDeserializedValue.join();
if (!(e.getCachedDeserializedOld() instanceof IllegalStateException)) {
fail("unexpected success of old getDeserializedValue. It returned " + e.getCachedDeserializedOld());
}
}
use of org.apache.geode.internal.offheap.StoredObject in project geode by apache.
the class EntryEventImplTest method verifyExportNewValueWithUnserializedStoredObject.
@Test
public void verifyExportNewValueWithUnserializedStoredObject() {
LocalRegion region = mock(LocalRegion.class);
when(region.getOffHeap()).thenReturn(true);
StoredObject newValue = mock(StoredObject.class);
byte[] newValueBytes = new byte[] { 1, 2, 3 };
when(newValue.getValueAsHeapByteArray()).thenReturn(newValueBytes);
NewValueImporter nvImporter = mock(NewValueImporter.class);
EntryEventImpl e = createEntryEvent(region, newValue);
e.exportNewValue(nvImporter);
verify(nvImporter).importNewBytes(newValueBytes, false);
}
use of org.apache.geode.internal.offheap.StoredObject in project geode by apache.
the class SearchLoadAndWriteProcessorTest method verifyThatOffHeapReleaseIsCalledAfterNetWrite.
/**
* This test verifies the fix for GEODE-1199. It verifies that when doNetWrite is called with an
* event that has a StoredObject value that it will have "release" called on it.
*/
@Test
public void verifyThatOffHeapReleaseIsCalledAfterNetWrite() {
// setup
SearchLoadAndWriteProcessor processor = SearchLoadAndWriteProcessor.getProcessor();
LocalRegion lr = mock(LocalRegion.class);
when(lr.getOffHeap()).thenReturn(true);
when(lr.getScope()).thenReturn(Scope.DISTRIBUTED_ACK);
Object key = "key";
StoredObject value = mock(StoredObject.class);
when(value.hasRefCount()).thenReturn(true);
when(value.retain()).thenReturn(true);
Object cbArg = null;
KeyInfo keyInfo = new KeyInfo(key, value, cbArg);
when(lr.getKeyInfo(any(), any(), any())).thenReturn(keyInfo);
processor.region = lr;
EntryEventImpl event = EntryEventImpl.create(lr, Operation.REPLACE, key, value, cbArg, false, null);
try {
// the test
processor.doNetWrite(event, null, null, 0);
// verification
verify(value, times(2)).retain();
verify(value, times(1)).release();
} finally {
processor.release();
}
}
use of org.apache.geode.internal.offheap.StoredObject in project geode by apache.
the class EntryEventImplTest method verifyExportNewValueWithSerializedStoredObjectAndImporterPrefersSerialized.
@Test
public void verifyExportNewValueWithSerializedStoredObjectAndImporterPrefersSerialized() {
LocalRegion region = mock(LocalRegion.class);
when(region.getOffHeap()).thenReturn(true);
StoredObject newValue = mock(StoredObject.class);
when(newValue.isSerialized()).thenReturn(true);
byte[] newValueBytes = new byte[] { 1, 2, 3 };
when(newValue.getValueAsHeapByteArray()).thenReturn(newValueBytes);
NewValueImporter nvImporter = mock(NewValueImporter.class);
when(nvImporter.prefersNewSerialized()).thenReturn(true);
EntryEventImpl e = createEntryEvent(region, newValue);
e.exportNewValue(nvImporter);
verify(nvImporter).importNewBytes(newValueBytes, true);
}
use of org.apache.geode.internal.offheap.StoredObject in project geode by apache.
the class EntryEventImplTest method verifyExportNewValueWithSerializedStoredObjectAndUnretainedNewReferenceOk.
@Test
public void verifyExportNewValueWithSerializedStoredObjectAndUnretainedNewReferenceOk() {
LocalRegion region = mock(LocalRegion.class);
when(region.getOffHeap()).thenReturn(true);
StoredObject newValue = mock(StoredObject.class);
when(newValue.isSerialized()).thenReturn(true);
Object newValueDeserialized = "newValueDeserialized";
when(newValue.getValueAsDeserializedHeapObject()).thenReturn(newValueDeserialized);
NewValueImporter nvImporter = mock(NewValueImporter.class);
when(nvImporter.isUnretainedNewReferenceOk()).thenReturn(true);
EntryEventImpl e = createEntryEvent(region, newValue);
e.exportNewValue(nvImporter);
verify(nvImporter).importNewObject(newValue, true);
}
Aggregations