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;
+ }
}