/* * 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.*; import static org.mockito.Mockito.mock; import java.nio.ByteBuffer; import org.assertj.core.api.JUnitSoftAssertions; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.rules.ExpectedException; import org.apache.geode.internal.cache.EntryEventImpl; import org.apache.geode.internal.offheap.MemoryBlock.State; import org.apache.geode.test.junit.categories.UnitTest; @Category(UnitTest.class) public class TinyMemoryBlockJUnitTest { private MemoryAllocatorImpl ma; private OutOfOffHeapMemoryListener ooohml; private OffHeapMemoryStats stats; private Slab[] slabs; @Rule public ExpectedException expectedException = ExpectedException.none(); @Rule public JUnitSoftAssertions softly = new JUnitSoftAssertions(); @Before public void setUp() throws Exception { slabs = new Slab[] {new SlabImpl((int) OffHeapStorage.MIN_SLAB_SIZE), new SlabImpl((int) OffHeapStorage.MIN_SLAB_SIZE), new SlabImpl((int) OffHeapStorage.MIN_SLAB_SIZE)}; ooohml = mock(OutOfOffHeapMemoryListener.class); stats = mock(OffHeapMemoryStats.class); ma = (MemoryAllocatorImpl) MemoryAllocatorImpl.createForUnitTest(ooohml, stats, slabs); } @After public void tearDown() throws Exception { MemoryAllocatorImpl.freeOffHeapMemory(); } protected Object getValue() { return Long.valueOf(Long.MAX_VALUE); } private StoredObject createChunk(byte[] v, boolean isSerialized, boolean isCompressed) { StoredObject chunk = (StoredObject) ma.allocateAndInitialize(v, isSerialized, isCompressed); return chunk; } private StoredObject createValueAsSerializedStoredObject(Object value, boolean isCompressed) { byte[] valueInSerializedByteArray = EntryEventImpl.serialize(value); boolean isSerialized = true; StoredObject createdObject = createChunk(valueInSerializedByteArray, isSerialized, isCompressed); return createdObject; } private byte[] convertValueToByteArray(Object value) { return ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong((Long) value).array(); } private StoredObject createValueAsUnserializedStoredObject(Object value, boolean isCompressed) { byte[] valueInByteArray; if (value instanceof Long) { valueInByteArray = convertValueToByteArray(value); } else { valueInByteArray = (byte[]) value; } boolean isSerialized = false; StoredObject createdObject = createChunk(valueInByteArray, isSerialized, isCompressed); return createdObject; } @Test public void constructorReturnsNonNullMemoryBlock() { MemoryBlock mb = new TestableFreeListManager.TinyMemoryBlock(slabs[0].getMemoryAddress(), 0); softly.assertThat(mb).isNotNull(); } @Test public void stateAlwaysEqualsDeallocated() { MemoryBlock mb = new TestableFreeListManager.TinyMemoryBlock(slabs[0].getMemoryAddress(), 0); softly.assertThat(mb.getState()).isEqualTo(State.DEALLOCATED); } @Test public void getMemoryAddressReturnsAddressBlockWasContructedFrom() { MemoryBlock mb = new TestableFreeListManager.TinyMemoryBlock(slabs[0].getMemoryAddress(), 0); softly.assertThat(mb.getAddress()).isEqualTo(slabs[0].getMemoryAddress()); } @Test public void getBlockSizeReturnsReturnsSizeOfUnderlyingChunk() { MemoryBlock mb = new TestableFreeListManager.TinyMemoryBlock( new OffHeapStoredObject(slabs[0].getMemoryAddress(), slabs[0].getSize()).getAddress(), 0); softly.assertThat(mb.getBlockSize()).isEqualTo(slabs[0].getSize()); } @Test public void getNextBlockThrowsUnsupportedOperationException() { expectedException.expect(UnsupportedOperationException.class); MemoryBlock mb = new TestableFreeListManager.TinyMemoryBlock( new OffHeapStoredObject(slabs[0].getMemoryAddress(), slabs[0].getSize()).getAddress(), 0); mb.getNextBlock(); fail("getNextBlock failed to throw UnsupportedOperationException"); } @Test public void getSlabIdThrowsUnsupportedOperationException() { expectedException.expect(UnsupportedOperationException.class); MemoryBlock mb = new TestableFreeListManager.TinyMemoryBlock( new OffHeapStoredObject(slabs[0].getMemoryAddress(), slabs[0].getSize()).getAddress(), 0); mb.getSlabId(); fail("getSlabId failed to throw UnsupportedOperationException"); } @Test public void getFreeListIdReturnsIdBlockWasConstructedWith() { MemoryBlock mb0 = new TestableFreeListManager.TinyMemoryBlock( new OffHeapStoredObject(slabs[0].getMemoryAddress(), slabs[0].getSize()).getAddress(), 0); MemoryBlock mb1 = new TestableFreeListManager.TinyMemoryBlock( new OffHeapStoredObject(slabs[1].getMemoryAddress(), slabs[1].getSize()).getAddress(), 1); softly.assertThat(mb0.getFreeListId()).isEqualTo(0); softly.assertThat(mb1.getFreeListId()).isEqualTo(1); } @Test public void getRefCountReturnsZero() { MemoryBlock mb0 = new TestableFreeListManager.TinyMemoryBlock( new OffHeapStoredObject(slabs[0].getMemoryAddress(), slabs[0].getSize()).getAddress(), 0); MemoryBlock mb1 = new TestableFreeListManager.TinyMemoryBlock( new OffHeapStoredObject(slabs[1].getMemoryAddress(), slabs[1].getSize()).getAddress(), 1); softly.assertThat(mb0.getRefCount()).isEqualTo(0); softly.assertThat(mb1.getRefCount()).isEqualTo(0); } @Test public void getDataTypeReturnsNA() { Object obj = getValue(); boolean compressed = false; StoredObject storedObject0 = createValueAsSerializedStoredObject(obj, compressed); MemoryBlock mb = new TestableFreeListManager.TinyMemoryBlock(((MemoryBlock) storedObject0).getAddress(), 0); softly.assertThat(mb.getDataType()).isEqualTo("N/A"); } @Test public void getDataValueReturnsNull() { Object obj = getValue(); boolean compressed = false; StoredObject storedObject0 = createValueAsSerializedStoredObject(obj, compressed); MemoryBlock mb = new TestableFreeListManager.TinyMemoryBlock(((MemoryBlock) storedObject0).getAddress(), 0); softly.assertThat(mb.getDataValue()).isNull(); } @Test public void isSerializedReturnsFalse() { Object obj = getValue(); boolean compressed = false; StoredObject storedObject0 = createValueAsSerializedStoredObject(obj, compressed); StoredObject storedObject1 = createValueAsUnserializedStoredObject(obj, compressed); MemoryBlock mb0 = new TestableFreeListManager.TinyMemoryBlock(((MemoryBlock) storedObject0).getAddress(), 0); MemoryBlock mb1 = new TestableFreeListManager.TinyMemoryBlock(((MemoryBlock) storedObject1).getAddress(), 0); softly.assertThat(mb0.isSerialized()).isFalse(); softly.assertThat(mb1.isSerialized()).isFalse(); } @Test public void isCompressedReturnsFalse() { Object obj = getValue(); boolean compressed = false; StoredObject storedObject0 = createValueAsUnserializedStoredObject(obj, compressed); StoredObject storedObject1 = createValueAsUnserializedStoredObject(obj, compressed = true); MemoryBlock mb0 = new TestableFreeListManager.TinyMemoryBlock(((MemoryBlock) storedObject0).getAddress(), 0); MemoryBlock mb1 = new TestableFreeListManager.TinyMemoryBlock(((MemoryBlock) storedObject1).getAddress(), 0); softly.assertThat(mb0.isCompressed()).isFalse(); softly.assertThat(mb1.isCompressed()).isFalse(); } @Test public void equalsComparesAddressesOfTinyMemoryBlocks() { MemoryBlock mb0 = new TestableFreeListManager.TinyMemoryBlock(slabs[0].getMemoryAddress(), 0); MemoryBlock mb1 = new TestableFreeListManager.TinyMemoryBlock(slabs[0].getMemoryAddress(), 0); MemoryBlock mb2 = new TestableFreeListManager.TinyMemoryBlock(slabs[1].getMemoryAddress(), 0); softly.assertThat(mb0.equals(mb1)).isTrue(); softly.assertThat(mb0.equals(mb2)).isFalse(); } @Test public void equalsNotTinyMemoryBlockReturnsFalse() { MemoryBlock mb = new TestableFreeListManager.TinyMemoryBlock(slabs[0].getMemoryAddress(), 0); softly.assertThat(mb.equals(slabs[0])).isFalse(); } @Test public void hashCodeReturnsHashOfUnderlyingMemory() { MemoryBlock mb = new TestableFreeListManager.TinyMemoryBlock(slabs[0].getMemoryAddress(), 0); softly.assertThat(mb.hashCode()).isEqualTo( new OffHeapStoredObject(slabs[0].getMemoryAddress(), slabs[0].getSize()).hashCode()); } private static class TestableFreeListManager extends FreeListManager { TestableFreeListManager(MemoryAllocatorImpl ma, final Slab[] slabs) { super(ma, slabs); } } }