| /* |
| * 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.cache; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.fail; |
| |
| import java.io.IOException; |
| import java.nio.ByteBuffer; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import org.apache.geode.internal.cache.entries.DiskEntry.Helper.Flushable; |
| import org.apache.geode.internal.cache.entries.DiskEntry.Helper.OffHeapValueWrapper; |
| import org.apache.geode.internal.offheap.MemoryAllocatorImpl; |
| import org.apache.geode.internal.offheap.NullOffHeapMemoryStats; |
| import org.apache.geode.internal.offheap.NullOutOfOffHeapMemoryListener; |
| import org.apache.geode.internal.offheap.SlabImpl; |
| import org.apache.geode.internal.offheap.StoredObject; |
| |
| public class OffHeapValueWrapperJUnitTest { |
| |
| private OffHeapValueWrapper createChunkValueWrapper(byte[] bytes, boolean isSerialized) { |
| StoredObject c = |
| MemoryAllocatorImpl.getAllocator().allocateAndInitialize(bytes, isSerialized, false); |
| return new OffHeapValueWrapper(c); |
| } |
| |
| @Before |
| public void setUp() throws Exception { |
| MemoryAllocatorImpl.createForUnitTest(new NullOutOfOffHeapMemoryListener(), |
| new NullOffHeapMemoryStats(), new SlabImpl[] {new SlabImpl(1024 * 1024)}); |
| } |
| |
| @After |
| public void tearDown() throws Exception { |
| MemoryAllocatorImpl.freeOffHeapMemory(); |
| } |
| |
| @Test |
| public void testIsSerialized() { |
| assertEquals(true, createChunkValueWrapper(new byte[16], true).isSerialized()); |
| assertEquals(false, createChunkValueWrapper(new byte[16], false).isSerialized()); |
| } |
| |
| @Test |
| public void testGetUserBits() { |
| assertEquals((byte) 1, createChunkValueWrapper(new byte[16], true).getUserBits()); |
| assertEquals((byte) 0, createChunkValueWrapper(new byte[16], false).getUserBits()); |
| } |
| |
| @Test |
| public void testGetLength() { |
| assertEquals(32, createChunkValueWrapper(new byte[32], true).getLength()); |
| assertEquals(17, createChunkValueWrapper(new byte[17], false).getLength()); |
| } |
| |
| @Test |
| public void testGetBytesAsString() { |
| assertEquals("byte[0, 0, 0, 0, 0, 0, 0, 0]", |
| createChunkValueWrapper(new byte[8], false).getBytesAsString()); |
| } |
| |
| @Test |
| public void testSendTo() throws IOException { |
| final ByteBuffer bb = ByteBuffer.allocateDirect(18); |
| bb.limit(8); |
| OffHeapValueWrapper vw = createChunkValueWrapper(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}, false); |
| vw.sendTo(bb, new Flushable() { |
| @Override |
| public void flush() throws IOException { |
| fail("should not have been called"); |
| } |
| |
| @Override |
| public void flush(ByteBuffer bb, ByteBuffer chunkbb) throws IOException { |
| fail("should not have been called"); |
| } |
| }); |
| assertEquals(8, bb.position()); |
| bb.flip(); |
| assertEquals(1, bb.get()); |
| assertEquals(2, bb.get()); |
| assertEquals(3, bb.get()); |
| assertEquals(4, bb.get()); |
| assertEquals(5, bb.get()); |
| assertEquals(6, bb.get()); |
| assertEquals(7, bb.get()); |
| assertEquals(8, bb.get()); |
| |
| bb.clear(); |
| bb.limit(8); |
| vw = createChunkValueWrapper(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}, false); |
| final int[] flushCalls = new int[1]; |
| vw.sendTo(bb, new Flushable() { |
| @Override |
| public void flush() throws IOException { |
| if (flushCalls[0] != 0) { |
| fail("expected flush to only be called once"); |
| } |
| flushCalls[0]++; |
| assertEquals(8, bb.position()); |
| for (int i = 0; i < 8; i++) { |
| assertEquals(i + 1, bb.get(i)); |
| } |
| bb.clear(); |
| bb.limit(8); |
| } |
| |
| @Override |
| public void flush(ByteBuffer bb, ByteBuffer chunkbb) throws IOException { |
| fail("should not have been called"); |
| } |
| }); |
| assertEquals(1, bb.position()); |
| bb.flip(); |
| assertEquals(9, bb.get()); |
| |
| bb.clear(); |
| bb.limit(8); |
| flushCalls[0] = 0; |
| vw = createChunkValueWrapper( |
| new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, false); |
| vw.sendTo(bb, new Flushable() { |
| @Override |
| public void flush() throws IOException { |
| if (flushCalls[0] > 1) { |
| fail("expected flush to only be called twice"); |
| } |
| assertEquals(8, bb.position()); |
| for (int i = 0; i < 8; i++) { |
| assertEquals((flushCalls[0] * 8) + i + 1, bb.get(i)); |
| } |
| flushCalls[0]++; |
| bb.clear(); |
| bb.limit(8); |
| } |
| |
| @Override |
| public void flush(ByteBuffer bb, ByteBuffer chunkbb) throws IOException { |
| fail("should not have been called"); |
| } |
| }); |
| assertEquals(1, bb.position()); |
| bb.flip(); |
| assertEquals(17, bb.get()); |
| |
| // now test with a chunk that will not fit in bb. |
| bb.clear(); |
| flushCalls[0] = 0; |
| bb.put((byte) 0); |
| vw = createChunkValueWrapper( |
| new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, false); |
| vw.sendTo(bb, new Flushable() { |
| @Override |
| public void flush() throws IOException { |
| fail("should not have been called"); |
| } |
| |
| @Override |
| public void flush(ByteBuffer bb, ByteBuffer chunkbb) throws IOException { |
| flushCalls[0]++; |
| assertEquals(1, bb.position()); |
| bb.flip(); |
| assertEquals(0, bb.get()); |
| assertEquals(19, chunkbb.remaining()); |
| for (int i = 1; i <= 19; i++) { |
| assertEquals(i, chunkbb.get()); |
| } |
| } |
| }); |
| assertEquals(1, flushCalls[0]); |
| } |
| } |