/* * Copyright (c) 2014 by Michael Berlin, Zuse Institute Berlin * * Licensed under the BSD License, see LICENSE file for details. * */ package org.xtreemfs.foundation.buffer; import static org.junit.Assert.*; import org.junit.Test; /** * Tests different sequences of {@link BufferPool#allocate(int)} and {@link BufferPool#free(ReusableBuffer)} * operations, some also regarding view buffers. * * Please note that {@link BufferPool} is a singleton and therefore the pool size increases as the number of * run tests does. Therefore, each test has to evaluate changes in the pool size relative to the pool size at * the start of test. * */ public class BufferPoolTest { public static final int TEST_BUFFER_SIZE = 8192; @Test public final void testSimpleAllocateAndFree() { ReusableBuffer buf = null; // There may be already a buffer pooled. If not, the pool size will stay 0 after an allocate(). int currentPoolSize = Math.max(0, BufferPool.getPoolSize(TEST_BUFFER_SIZE) - 1); buf = BufferPool.allocate(TEST_BUFFER_SIZE); assertEquals("BufferPool must be empty because a buffer was only allocated but not returned so far.", currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); BufferPool.free(buf); assertEquals("One buffer must have been returned and pooled.", currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); buf = BufferPool.allocate(TEST_BUFFER_SIZE); assertEquals("Pooled buffer must have been re-allocated.", currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); BufferPool.free(buf); assertEquals("One buffer must have been returned and pooled again.", currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); } @Test public final void testReusableViewBuffers() { ReusableBuffer buf = null; // There may be already a buffer pooled. If not, the pool size will stay 0 after an allocate(). int currentPoolSize = Math.max(0, BufferPool.getPoolSize(TEST_BUFFER_SIZE) - 1); buf = BufferPool.allocate(TEST_BUFFER_SIZE); assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); BufferPool.free(buf); assertEquals(currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); buf = BufferPool.allocate(TEST_BUFFER_SIZE); assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); ReusableBuffer viewBuffer = buf.createViewBuffer(); BufferPool.free(viewBuffer); assertEquals("Buffer not returned to pool yet since one reference is left.", currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); BufferPool.free(buf); assertEquals("Buffer must have been returned to pool since no reference is left.", currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); } @Test public final void testReusableViewBuffersOfReusableViewBuffers() { ReusableBuffer buf = null; // There may be already a buffer pooled. If not, the pool size will stay 0 after an allocate(). int currentPoolSize = Math.max(0, BufferPool.getPoolSize(TEST_BUFFER_SIZE) - 1); buf = BufferPool.allocate(TEST_BUFFER_SIZE); assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); BufferPool.free(buf); assertEquals(currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); buf = BufferPool.allocate(TEST_BUFFER_SIZE); assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); ReusableBuffer viewBuffer = buf.createViewBuffer(); // Create a view buffer of a view buffer. ReusableBuffer viewBuffer2 = viewBuffer.createViewBuffer(); BufferPool.free(viewBuffer2); assertEquals("Buffer not returned to pool yet since two references are left.", currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); BufferPool.free(viewBuffer); assertEquals("Buffer not returned to pool yet since one reference is left.", currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); BufferPool.free(buf); assertEquals("Buffer must have been returned to pool since no reference is left.", currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); } private void assertThatAssertionsAreEnabled() { boolean assertOn = false; // *assigns* true if assertions are on. assert assertOn = true; assertTrue("Enable assertions or this test won't work correctly.", assertOn); } @Test(expected = AssertionError.class) public final void testDoubleFreeThrows() { assertThatAssertionsAreEnabled(); ReusableBuffer buf = null; // There may be already a buffer pooled. If not, the pool size will stay 0 after an allocate(). int currentPoolSize = Math.max(0, BufferPool.getPoolSize(TEST_BUFFER_SIZE) - 1); buf = BufferPool.allocate(TEST_BUFFER_SIZE); assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); BufferPool.free(buf); assertEquals(currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); // Double free will trigger assertion. BufferPool.free(buf); } @Test(expected = AssertionError.class) public final void testDoubleFreeOfRecursiveViewBuffersThrows() { assertThatAssertionsAreEnabled(); ReusableBuffer buf = null; // There may be already a buffer pooled. If not, the pool size will stay 0 after an allocate(). int currentPoolSize = Math.max(0, BufferPool.getPoolSize(TEST_BUFFER_SIZE) - 1); buf = BufferPool.allocate(TEST_BUFFER_SIZE); assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); BufferPool.free(buf); assertEquals(currentPoolSize + 1, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); buf = BufferPool.allocate(TEST_BUFFER_SIZE); assertEquals(currentPoolSize, BufferPool.getPoolSize(TEST_BUFFER_SIZE)); ReusableBuffer viewBuffer = buf.createViewBuffer(); // Create a view buffer of a view buffer. ReusableBuffer viewBuffer2 = viewBuffer.createViewBuffer(); BufferPool.free(viewBuffer2); BufferPool.free(viewBuffer); BufferPool.free(buf); // Double free will trigger assertion. BufferPool.free(viewBuffer2); } }