Return-Path: Delivered-To: apmail-cassandra-commits-archive@www.apache.org Received: (qmail 4729 invoked from network); 1 Mar 2011 22:44:31 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 1 Mar 2011 22:44:31 -0000 Received: (qmail 81120 invoked by uid 500); 1 Mar 2011 22:44:29 -0000 Delivered-To: apmail-cassandra-commits-archive@cassandra.apache.org Received: (qmail 80461 invoked by uid 500); 1 Mar 2011 22:44:29 -0000 Mailing-List: contact commits-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cassandra.apache.org Delivered-To: mailing list commits@cassandra.apache.org Received: (qmail 80435 invoked by uid 99); 1 Mar 2011 22:44:28 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 01 Mar 2011 22:44:28 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 01 Mar 2011 22:44:27 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id CD5682388A2C; Tue, 1 Mar 2011 22:44:06 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1076041 - /cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/io/util/BufferedRandomAccessFileTest.java Date: Tue, 01 Mar 2011 22:44:06 -0000 To: commits@cassandra.apache.org From: jbellis@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110301224406.CD5682388A2C@eris.apache.org> Author: jbellis Date: Tue Mar 1 22:44:06 2011 New Revision: 1076041 URL: http://svn.apache.org/viewvc?rev=1076041&view=rev Log: improve BufferedRAFTest Modified: cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/io/util/BufferedRandomAccessFileTest.java Modified: cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/io/util/BufferedRandomAccessFileTest.java URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/io/util/BufferedRandomAccessFileTest.java?rev=1076041&r1=1076040&r2=1076041&view=diff ============================================================================== --- cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/io/util/BufferedRandomAccessFileTest.java (original) +++ cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/io/util/BufferedRandomAccessFileTest.java Tue Mar 1 22:44:06 2011 @@ -1,6 +1,4 @@ -package org.apache.cassandra.io.util; -/* - * +/** * 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 @@ -8,32 +6,147 @@ package org.apache.cassandra.io.util; * 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.cassandra.io.util; +import org.apache.cassandra.utils.ByteBufferUtil; import java.io.EOFException; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; import java.util.Arrays; import java.util.concurrent.Callable; -import org.junit.Test; - +import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertEquals; +import org.junit.Test; + public class BufferedRandomAccessFileTest { + @Test + public void testReadAndWrite() throws Exception + { + BufferedRandomAccessFile file = createTempFile("braf"); + + // writting string of data to the file + byte[] data = "Hello".getBytes(); + file.write(data); + assertEquals(file.length(), data.length); + assertEquals(file.getFilePointer(), data.length); + + // reading small amount of data from file, this is handled by initial buffer + file.seek(0); + byte[] buffer = new byte[data.length]; + assertEquals(file.read(buffer), data.length); + assertTrue(Arrays.equals(buffer, data)); // we read exactly what we wrote + assertEquals(file.read(), -1); // nothing more to read EOF + assert file.bytesRemaining() == 0 && file.isEOF(); + + // writing buffer bigger than page size, which will trigger reBuffer() + byte[] bigData = new byte[BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE + 10]; + + for (int i = 0; i < bigData.length; i++) + bigData[i] = 'd'; + + long initialPosition = file.getFilePointer(); + file.write(bigData); // writing data + assertEquals(file.getFilePointer(), initialPosition + bigData.length); + assertEquals(file.length(), initialPosition + bigData.length); // file size should equals to last position + + // reading written buffer + file.seek(initialPosition); // back to initial (before write) position + data = new byte[bigData.length]; + long sizeRead = 0; + for (int i = 0; i < data.length; i++) + { + data[i] = (byte) file.read(); // this will trigger reBuffer() + sizeRead++; + } + + assertEquals(sizeRead, data.length); // read exactly data.length bytes + assertEquals(file.getFilePointer(), initialPosition + data.length); + assertEquals(file.length(), initialPosition + bigData.length); + assertTrue(Arrays.equals(bigData, data)); + assert file.bytesRemaining() == 0 && file.isEOF(); // we are at the of the file + + // test readBytes(int) method + file.seek(0); + ByteBuffer fileContent = file.readBytes((int) file.length()); + assertEquals(fileContent.limit(), file.length()); + assert ByteBufferUtil.string(fileContent).equals("Hello" + new String(bigData)); + + // read the same buffer but using readFully(int) + data = new byte[bigData.length]; + file.seek(initialPosition); + file.readFully(data); + assert file.bytesRemaining() == 0 && file.isEOF(); // we should be at EOF + assertTrue(Arrays.equals(bigData, data)); + + // try to read past mark (all methods should return -1) + data = new byte[10]; + assertEquals(file.read(), -1); + assertEquals(file.read(data), -1); + assertEquals(file.read(data, 0, data.length), -1); + + // test read(byte[], int, int) + file.seek(0); + data = new byte[20]; + assertEquals(file.read(data, 0, 15), 15); + assertTrue(new String(data).contains("Hellodddddddddd")); + for (int i = 16; i < data.length; i++) + { + assert data[i] == 0; + } + + // try to seek past EOF + file.seek(file.length() + 10); // should not throw an exception + assert file.bytesRemaining() == 0 && file.isEOF(); + + file.close(); + } + + @Test + public void testReadsAndWriteOnCapacity() throws IOException + { + File tmpFile = File.createTempFile("readtest", "bin"); + BufferedRandomAccessFile rw = new BufferedRandomAccessFile(tmpFile, "rw"); + + // Fully write the file and sync.. + byte[] in = new byte[BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE]; + rw.write(in); + + // Read it into a same size array. + byte[] out = new byte[BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE]; + rw.read(out); + + // We're really at the end. + long rem = rw.bytesRemaining(); + assert rw.isEOF(); + assert rem == 0 : "BytesRemaining should be 0 but it's " + rem; + + // Cannot read any more. + int negone = rw.read(); + assert negone == -1 : "We read past the end of the file, should have gotten EOF -1. Instead, " + negone; + + // Writing will succeed + rw.write(new byte[BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE]); + // Forcing a rebuffer here + rw.write(42); + } @Test public void testLength() throws IOException @@ -70,59 +183,140 @@ public class BufferedRandomAccessFileTes r.close(); } - @Test - public void testReadsAndWriteOnCapacity() throws IOException + @Test (expected = EOFException.class) + public void testReadBytes() throws IOException { - File tmpFile = File.createTempFile("readtest", "bin"); - BufferedRandomAccessFile rw = new BufferedRandomAccessFile(tmpFile, "rw"); + BufferedRandomAccessFile file = createTempFile("brafReadBytes"); - // Fully write the file and sync.. - byte[] in = new byte[BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE]; - rw.write(in); + byte[] data = new byte[BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE + 10]; - // Read it into a same size array. - byte[] out = new byte[BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE]; - rw.read(out); + for (int i = 0; i < data.length; i++) + { + data[i] = 'c'; + } - // We're really at the end. - long rem = rw.bytesRemaining(); - assert rw.isEOF(); - assert rem == 0 : "BytesRemaining should be 0 but it's " + rem; + file.write(data); - // Cannot read any more. - int negone = rw.read(); - assert negone == -1 : "We read past the end of the file, should have gotten EOF -1. Instead, " + negone; + file.seek(0); + ByteBuffer content = file.readBytes((int) file.length()); - // Writing will succeed - rw.write(new byte[BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE]); - // Forcing a rebuffer here - rw.write(42); + // after reading whole file we should be at EOF + assertEquals(ByteBufferUtil.compare(content, data), 0); + assert file.bytesRemaining() == 0 && file.isEOF(); + + file.seek(0); + content = file.readBytes(10); // reading first 10 bytes + assertEquals(ByteBufferUtil.compare(content, "cccccccccc".getBytes()), 0); + assertEquals(file.bytesRemaining(), file.length() - content.limit()); + + // trying to read more than file has right now + file.readBytes((int) file.length() + 10); // this throws expected EOFException + + file.close(); } - @Test - public void testNotEOF() throws IOException + @Test (expected = IllegalArgumentException.class) + public void testSeek() throws Exception { - assertEquals(1, new BufferedRandomAccessFile(writeTemporaryFile(new byte[1]), "rw").read(new byte[2])); + BufferedRandomAccessFile file = createTempFile("brafSeek"); + byte[] data = new byte[BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE + 20]; + for (int i = 0; i < data.length; i++) + { + data[i] = 'c'; + } + + file.write(data); + assert file.bytesRemaining() == 0 && file.isEOF(); + + file.seek(0); + assertEquals(file.getFilePointer(), 0); + assertEquals(file.bytesRemaining(), file.length()); + + file.seek(20); + assertEquals(file.getFilePointer(), 20); + assertEquals(file.bytesRemaining(), file.length() - 20); + + // trying to seek past the end of the file + file.seek(file.length() + 30); + assertEquals(file.getFilePointer(), data.length + 30); + assertEquals(file.getFilePointer(), file.length()); // length should be at seek position + assert file.bytesRemaining() == 0 && file.isEOF(); + + file.seek(-1); // throws IllegalArgumentException + + file.close(); } + @Test + public void testSkipBytes() throws IOException + { + BufferedRandomAccessFile file = createTempFile("brafSkipBytes"); + byte[] data = new byte[BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE * 2]; + + file.write(data); + assert file.bytesRemaining() == 0 && file.isEOF(); + + file.seek(0); // back to the beginning of the file + assertEquals(file.skipBytes(10), 10); + assertEquals(file.bytesRemaining(), file.length() - 10); + + int initialPosition = (int) file.getFilePointer(); + // can't skip more than file size + assertEquals(file.skipBytes((int) file.length() + 10), file.length() - initialPosition); + assertEquals(file.getFilePointer(), file.length()); + assert file.bytesRemaining() == 0 && file.isEOF(); + + file.seek(0); + + // skipping negative amount should return 0 + assertEquals(file.skipBytes(-1000), 0); + assertEquals(file.getFilePointer(), 0); + assertEquals(file.bytesRemaining(), file.length()); - protected void expectEOF(Callable callable) + file.close(); + } + + @Test (expected = IllegalArgumentException.class) + public void testGetFilePointer() throws IOException { - boolean threw = false; - try - { - callable.call(); - } - catch (Exception e) - { - assert e.getClass().equals(EOFException.class) : e.getClass().getName() + " is not " + EOFException.class.getName(); - threw = true; - } - assert threw : EOFException.class.getName() + " not received"; + BufferedRandomAccessFile file = createTempFile("brafGetFilePointer"); + + assertEquals(file.getFilePointer(), 0); // initial position should be 0 + + file.write(new byte[20]); + assertEquals(file.getFilePointer(), 20); // position 20 after writing 20 bytes + + file.seek(10); + assertEquals(file.getFilePointer(), 10); // after seek to 10 should be 10 + + file.seek(-1); + assertEquals(file.getFilePointer(), 10); + + file.seek(30); // past previous end file + assertEquals(file.getFilePointer(), 30); + + // position should change after skip bytes + file.seek(0); + file.skipBytes(15); + assertEquals(file.getFilePointer(), 15); + + file.read(); + assertEquals(file.getFilePointer(), 16); + file.read(new byte[4]); + assertEquals(file.getFilePointer(), 20); + + file.close(); } @Test - public void testEOF() throws IOException + public void testGetPath() throws IOException + { + BufferedRandomAccessFile file = createTempFile("brafGetPath"); + assert file.getPath().contains("brafGetPath"); + } + + @Test + public void testIsEOF() throws IOException { for (String mode : Arrays.asList("r", "rw")) // read, read+write { @@ -161,20 +355,41 @@ public class BufferedRandomAccessFileTes } } - protected File writeTemporaryFile(byte[] data) throws IOException + @Test + public void testNotEOF() throws IOException { - File f = File.createTempFile("BRAFTestFile", null); - f.deleteOnExit(); - FileOutputStream fout = new FileOutputStream(f); - fout.write(data); - fout.getFD().sync(); - fout.close(); - return f; + assertEquals(1, new BufferedRandomAccessFile(writeTemporaryFile(new byte[1]), "rw").read(new byte[2])); } + @Test + public void testBytesRemaining() throws IOException + { + BufferedRandomAccessFile file = createTempFile("brafBytesRemaining"); + assertEquals(file.bytesRemaining(), 0); + + int toWrite = BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE + 10; + + file.write(new byte[toWrite]); + assertEquals(file.bytesRemaining(), 0); + + file.seek(0); + assertEquals(file.bytesRemaining(), toWrite); - @Test (expected=UnsupportedOperationException.class) - public void testOverflowMark() throws IOException + for (int i = 1; i <= file.length(); i++) + { + file.read(); + assertEquals(file.bytesRemaining(), file.length() - i); + } + + file.seek(0); + file.skipBytes(10); + assertEquals(file.bytesRemaining(), file.length() - 10); + + file.close(); + } + + @Test (expected = UnsupportedOperationException.class) + public void testBytesPastMark() throws IOException { File tmpFile = File.createTempFile("overflowtest", "bin"); tmpFile.deleteOnExit(); @@ -188,35 +403,104 @@ public class BufferedRandomAccessFileTes rw.reset(mark); // Expect this call to succeed. - int bpm = rw.bytesPastMark(mark); + rw.bytesPastMark(mark); // Seek 4gb rw.seek(4L*1024L*1024L*1024L*1024L); - + // Expect this call to fail -- the distance from mark to current file pointer > 2gb. - bpm = rw.bytesPastMark(mark); + rw.bytesPastMark(mark); } - @Test - public void testRead() throws IOException + @Test (expected = ClosedChannelException.class) + public void testClose() throws IOException { - File tmpFile = File.createTempFile("readtest", "bin"); - tmpFile.deleteOnExit(); + BufferedRandomAccessFile file = createTempFile("brafClose"); - BufferedRandomAccessFile rw = new BufferedRandomAccessFile(tmpFile.getPath(), "rw"); - rw.write(new byte[]{ 1 }); - rw.seek(0); + byte[] data = new byte[BufferedRandomAccessFile.DEFAULT_BUFFER_SIZE + 20]; + for (int i = 0; i < data.length; i++) + { + data[i] = 'c'; + } - // test read of buffered-but-not-yet-written data - byte[] buffer = new byte[1]; - assertEquals(1, rw.read(buffer)); - assertEquals(1, buffer[0]); - rw.close(); + file.write(data); + file.close(); + + file.read(); // trying to read throws ClosedChannelException + file.write(new byte[1]); // try to write throws ClosedChannelException + + BufferedRandomAccessFile copy = new BufferedRandomAccessFile(file.getPath(), "r"); + ByteBuffer contents = copy.readBytes((int) copy.length()); - // test read of not-yet-buffered data - rw = new BufferedRandomAccessFile(tmpFile.getPath(), "rw"); - assert rw.read(buffer) == 1; - assert buffer[0] == 1; + assertEquals(contents.limit(), data.length); + assertEquals(ByteBufferUtil.compare(contents, data), 0); } + @Test (expected = AssertionError.class) + public void testMarkAndReset() throws IOException + { + BufferedRandomAccessFile file = createTempFile("brafTestMark"); + file.write(new byte[30]); + + file.seek(10); + FileMark mark = file.mark(); + + file.seek(file.length()); + assertTrue(file.isEOF()); + + file.reset(); + assertEquals(file.bytesRemaining(), 20); + + file.seek(file.length()); + assertTrue(file.isEOF()); + + file.reset(mark); + assertEquals(file.bytesRemaining(), 20); + + file.seek(file.length()); + assertEquals(file.bytesPastMark(), 20); + assertEquals(file.bytesPastMark(mark), 20); + + file.reset(mark); + assertEquals(file.bytesPastMark(), 0); + + file.seek(0); + file.bytesPastMark(); // throws AssertionError + + file.close(); + } + + private void expectEOF(Callable callable) + { + boolean threw = false; + try + { + callable.call(); + } + catch (Exception e) + { + assert e.getClass().equals(EOFException.class) : e.getClass().getName() + " is not " + EOFException.class.getName(); + threw = true; + } + assert threw : EOFException.class.getName() + " not received"; + } + + private BufferedRandomAccessFile createTempFile(String name) throws IOException + { + File tempFile = File.createTempFile(name, null); + tempFile.deleteOnExit(); + + return new BufferedRandomAccessFile(tempFile, "rw"); + } + + private File writeTemporaryFile(byte[] data) throws IOException + { + File f = File.createTempFile("BRAFTestFile", null); + f.deleteOnExit(); + FileOutputStream fout = new FileOutputStream(f); + fout.write(data); + fout.getFD().sync(); + fout.close(); + return f; + } }