@Test public void testBufferCallbackUniqueBuffers() throws Exception { controller = new AsynchronousFileImpl(executor, pollerExecutor); final int NUMBER_LINES = 1000; final int SIZE = 512; controller.open(fileName, 1000); controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j'); final ArrayList<ByteBuffer> buffers = new ArrayList<ByteBuffer>(); BufferCallback bufferCallback = new BufferCallback() { public void bufferDone(final ByteBuffer buffer) { buffers.add(buffer); } }; controller.setBufferCallback(bufferCallback); CountDownLatch latch = new CountDownLatch(NUMBER_LINES); ArrayList<Integer> result = new ArrayList<Integer>(); for (int i = 0; i < NUMBER_LINES; i++) { ByteBuffer buffer1 = AsynchronousFileImpl.newBuffer(SIZE); buffer1.rewind(); for (int j = 0; j < SIZE; j++) { buffer1.put((byte) (j % Byte.MAX_VALUE)); } CountDownCallback aio = new CountDownCallback(latch, null, result, i); controller.write(i * SIZE, SIZE, buffer1, aio); } // The buffer callback is only called after the complete callback was // called. // Because of that a race could happen on the assertions to // buffers.size what would invalidate the test // We close the file and that would guarantee the buffer callback was // called for all the elements controller.close(); CountDownCallback.checkResults(NUMBER_LINES, result); // Make sure all the buffers are unique ByteBuffer lineOne = null; for (ByteBuffer bufferTmp : buffers) { if (lineOne == null) { lineOne = bufferTmp; } else { Assert.assertTrue(lineOne != bufferTmp); } } for (ByteBuffer bufferTmp : buffers) { destroy(bufferTmp); } buffers.clear(); }
/** * This test will call file.close() when there are still callbacks being processed. This could * cause a crash or callbacks missing and this test is validating both situations. The file is * also read after being written to validate its correctness */ @Test public void testConcurrentClose() throws Exception { controller = new AsynchronousFileImpl(executor, pollerExecutor); final int NUMBER_LINES = 1000; CountDownLatch readLatch = new CountDownLatch(NUMBER_LINES); final int SIZE = 1024; controller.open(fileName, 10000); controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j'); controller.setBufferCallback(bufferCallbackDestroy); for (int i = 0; i < NUMBER_LINES; i++) { ByteBuffer buffer = AsynchronousFileImpl.newBuffer(SIZE); buffer.clear(); addString("Str value " + i + "\n", buffer); for (int j = buffer.position(); j < buffer.capacity() - 1; j++) { buffer.put((byte) ' '); } buffer.put((byte) '\n'); CountDownCallback aio = new CountDownCallback(readLatch, null, null, 0); controller.write(i * SIZE, SIZE, buffer, aio); } // If you call close you're supposed to wait events to finish before // closing it controller.close(); controller.setBufferCallback(null); Assert.assertEquals(0, readLatch.getCount()); waitForLatch(readLatch); controller.open(fileName, 10); ByteBuffer newBuffer = AsynchronousFileImpl.newBuffer(SIZE); ByteBuffer buffer = AsynchronousFileImpl.newBuffer(SIZE); for (int i = 0; i < NUMBER_LINES; i++) { newBuffer.clear(); addString("Str value " + i + "\n", newBuffer); for (int j = newBuffer.position(); j < newBuffer.capacity() - 1; j++) { newBuffer.put((byte) ' '); } newBuffer.put((byte) '\n'); CountDownLatch latch = new CountDownLatch(1); CountDownCallback aio = new CountDownCallback(latch, null, null, 0); controller.read(i * SIZE, SIZE, buffer, aio); waitForLatch(latch); Assert.assertEquals(0, aio.errorCalled); Assert.assertTrue(aio.doneCalled); byte bytesRead[] = new byte[SIZE]; byte bytesCompare[] = new byte[SIZE]; newBuffer.rewind(); newBuffer.get(bytesCompare); buffer.rewind(); buffer.get(bytesRead); for (int count = 0; count < SIZE; count++) { Assert.assertEquals( "byte position " + count + " differs on line " + i, bytesCompare[count], bytesRead[count]); } Assert.assertTrue(buffer.equals(newBuffer)); } destroy(newBuffer); }
@Test public void testRead() throws Exception { controller = new AsynchronousFileImpl(executor, pollerExecutor); controller.setBufferCallback(bufferCallbackDestroy); final int NUMBER_LINES = 1000; final int SIZE = 1024; controller.open(fileName, 1000); controller.fill(0, 1, NUMBER_LINES * SIZE, (byte) 'j'); { CountDownLatch latch = new CountDownLatch(NUMBER_LINES); ArrayList<Integer> result = new ArrayList<Integer>(); AtomicInteger errors = new AtomicInteger(0); for (int i = 0; i < NUMBER_LINES; i++) { if (i % 100 == 0) { System.out.println("Wrote " + i + " lines"); } final ByteBuffer buffer0 = AsynchronousFileImpl.newBuffer(SIZE); for (int j = 0; j < SIZE; j++) { buffer0.put(UnitTestCase.getSamplebyte(j)); } CountDownCallback aio = new CountDownCallback(latch, errors, result, i); controller.write(i * SIZE, SIZE, buffer0, aio); } waitForLatch(latch); Assert.assertEquals(0, errors.get()); CountDownCallback.checkResults(NUMBER_LINES, result); } // If you call close you're supposed to wait events to finish before // closing it controller.close(); controller.setBufferCallback(null); controller.open(fileName, 10); buffer = AsynchronousFileImpl.newBuffer(SIZE); for (int i = 0; i < NUMBER_LINES; i++) { if (i % 100 == 0) { System.out.println("Read " + i + " lines"); } AsynchronousFileImpl.clearBuffer(buffer); CountDownLatch latch = new CountDownLatch(1); AtomicInteger errors = new AtomicInteger(0); CountDownCallback aio = new CountDownCallback(latch, errors, null, 0); controller.read(i * SIZE, SIZE, buffer, aio); waitForLatch(latch); Assert.assertEquals(0, errors.get()); Assert.assertTrue(aio.doneCalled); byte bytesRead[] = new byte[SIZE]; buffer.get(bytesRead); for (int count = 0; count < SIZE; count++) { Assert.assertEquals( "byte position " + count + " differs on line " + i + " position = " + count, UnitTestCase.getSamplebyte(count), bytesRead[count]); } } }