Add unit tests for FileChannel#lock #tryLock
The change adds more test for FileChannel #lock and #tryLock.
The change also includes test for overlapping lock using different file
channels.
Bug: 27186422
(cherry-picked from commit fb376ca44c4c3ed1d53b93f32712c4efc9490a76)
Change-Id: Ib040bb28d8ce8417d2cd8fb2c81a9d50519e8fde
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java
index f3b5f8b..d6dacb4 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/channels/FileChannelTest.java
@@ -46,6 +46,8 @@
import junit.framework.TestCase;
+import libcore.io.IoUtils;
+
public class FileChannelTest extends TestCase {
private static final int CAPACITY = 100;
@@ -76,8 +78,12 @@
private FileChannel readOnlyFileChannel;
+ private FileChannel readOnlyFileChannel2;
+
private FileChannel writeOnlyFileChannel;
+ private FileChannel writeOnlyFileChannel2;
+
private FileChannel readWriteFileChannel;
private File fileOfReadOnlyFileChannel;
@@ -121,41 +127,23 @@
fileLock = null;
readOnlyFileChannel = new FileInputStream(fileOfReadOnlyFileChannel)
.getChannel();
+ readOnlyFileChannel2 = new FileInputStream(fileOfReadOnlyFileChannel)
+ .getChannel();
writeOnlyFileChannel = new FileOutputStream(fileOfWriteOnlyFileChannel)
.getChannel();
+ writeOnlyFileChannel2 = new FileOutputStream(fileOfWriteOnlyFileChannel)
+ .getChannel();
readWriteFileChannel = new RandomAccessFile(fileOfReadWriteFileChannel,
"rw").getChannel();
}
protected void tearDown() {
- if (null != readOnlyFileChannel) {
- try {
- readOnlyFileChannel.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != writeOnlyFileChannel) {
- try {
- writeOnlyFileChannel.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != readWriteFileChannel) {
- try {
- readWriteFileChannel.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != fis) {
- try {
- fis.close();
- } catch (IOException e) {
- // do nothing
- }
- }
+ IoUtils.closeQuietly(readOnlyFileChannel);
+ IoUtils.closeQuietly(readOnlyFileChannel2);
+ IoUtils.closeQuietly(writeOnlyFileChannel);
+ IoUtils.closeQuietly(writeOnlyFileChannel2);
+ IoUtils.closeQuietly(readWriteFileChannel);
+ IoUtils.closeQuietly(fis);
if (null != fileLock) {
try {
@@ -174,56 +162,15 @@
if (null != fileOfReadWriteFileChannel) {
fileOfReadWriteFileChannel.delete();
}
- if (null != datagramChannelSender) {
- try {
- datagramChannelSender.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != datagramChannelReceiver) {
- try {
- datagramChannelReceiver.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != serverSocketChannel) {
- try {
- serverSocketChannel.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != socketChannelSender) {
- try {
- socketChannelSender.close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != socketChannelReceiver) {
- try {
- socketChannelReceiver.close();
- } catch (IOException e) {
- // do nothing
- }
- }
+
+ IoUtils.closeQuietly(datagramChannelSender);
+ IoUtils.closeQuietly(datagramChannelReceiver);
+ IoUtils.closeQuietly(serverSocketChannel);
+ IoUtils.closeQuietly(socketChannelSender);
+ IoUtils.closeQuietly(socketChannelReceiver);
if (null != pipe) {
- if (null != pipe.source()) {
- try {
- pipe.source().close();
- } catch (IOException e) {
- // do nothing
- }
- }
- if (null != pipe.sink()) {
- try {
- pipe.sink().close();
- } catch (IOException e) {
- // do nothing
- }
- }
+ IoUtils.closeQuietly(pipe.source());
+ IoUtils.closeQuietly(pipe.sink());
}
}
@@ -653,14 +600,81 @@
/**
* @tests java.nio.channels.FileChannel#lock()
*/
+ public void test_lock_Closed() throws Exception {
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.lock();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException expected) {}
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.lock();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException expected) {}
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.lock();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException expected) {}
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock()
+ */
+ public void test_lock_NonWritable() throws Exception {
+ try {
+ readOnlyFileChannel.lock();
+ fail("should throw NonWritableChannelException");
+ } catch (NonWritableChannelException expected) {}
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock()
+ */
public void test_lock() throws Exception {
- MockFileChannel mockFileChannel = new MockFileChannel();
- // Verify that calling lock() leads to the method
- // lock(long, long, boolean) being called with a 0 for the
- // first parameter, Long.MAX_VALUE as the second parameter and false
- // as the third parameter.
- mockFileChannel.lock();
- assertTrue(mockFileChannel.isLockCalled);
+ fileLock = writeOnlyFileChannel.lock();
+ assertTrue(fileLock.isValid());
+ assertFalse(fileLock.isShared());
+ assertSame(writeOnlyFileChannel, fileLock.channel());
+ assertEquals(Long.MAX_VALUE, fileLock.size());
+ assertEquals(0, fileLock.position());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock()
+ */
+ public void test_lock_OverlappingException() throws Exception {
+ fileLock = writeOnlyFileChannel.lock();
+ assertTrue(fileLock.isValid());
+
+ // Test the same channel cannot be locked twice.
+ try {
+ writeOnlyFileChannel.lock();
+ fail("should throw OverlappingFileLockException");
+ } catch (OverlappingFileLockException expected) {}
+
+ // Test that a different channel on the same file also cannot be locked.
+ try {
+ writeOnlyFileChannel2.lock();
+ fail("should throw OverlappingFileLockException");
+ } catch (OverlappingFileLockException expected) {}
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#lock()
+ */
+ public void test_lock_After_Release() throws Exception {
+ fileLock = writeOnlyFileChannel.lock();
+ fileLock.release();
+ // After release file lock can be obtained again.
+ fileLock = writeOnlyFileChannel.lock();
+ assertTrue(fileLock.isValid());
+
+ // A different channel should be able to obtain a lock after it has been released
+ fileLock.release();
+ assertTrue(writeOnlyFileChannel2.lock().isValid());
}
/**
@@ -826,12 +840,17 @@
fileLock = writeOnlyFileChannel.lock(POSITION, SIZE, false);
assertTrue(fileLock.isValid());
+ // Test the same channel cannot be locked twice.
try {
writeOnlyFileChannel.lock(POSITION + 1, SIZE, false);
fail("should throw OverlappingFileLockException");
- } catch (OverlappingFileLockException e) {
- // expected
- }
+ } catch (OverlappingFileLockException expected) {}
+
+ // Test that a different channel on the same file also cannot be locked.
+ try {
+ writeOnlyFileChannel2.lock(POSITION + 1, SIZE, false);
+ fail("should throw OverlappingFileLockException");
+ } catch (OverlappingFileLockException expected) {}
}
/**
@@ -861,14 +880,88 @@
/**
* @tests java.nio.channels.FileChannel#tryLock()
*/
+ public void test_tryLock_Closed() throws Exception {
+ readOnlyFileChannel.close();
+ try {
+ readOnlyFileChannel.tryLock();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException expected) {}
+
+ writeOnlyFileChannel.close();
+ try {
+ writeOnlyFileChannel.tryLock();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException expected) {}
+
+ readWriteFileChannel.close();
+ try {
+ readWriteFileChannel.tryLock();
+ fail("should throw ClosedChannelException");
+ } catch (ClosedChannelException expected) {}
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock()
+ */
+ public void test_tryLock_NonWritable() throws Exception {
+ try {
+ readOnlyFileChannel.tryLock();
+ fail("should throw NonWritableChannelException");
+ } catch (NonWritableChannelException expected) {}
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock()
+ */
public void test_tryLock() throws Exception {
- MockFileChannel mockFileChannel = new MockFileChannel();
- // Verify that calling tryLock() leads to the method
- // tryLock(long, long, boolean) being called with a 0 for the
- // first parameter, Long.MAX_VALUE as the second parameter and false
- // as the third parameter.
- mockFileChannel.tryLock();
- assertTrue(mockFileChannel.isTryLockCalled);
+ fileLock = writeOnlyFileChannel.tryLock();
+ assertTrue(fileLock.isValid());
+ assertFalse(fileLock.isShared());
+ assertSame(writeOnlyFileChannel, fileLock.channel());
+ assertEquals(0, fileLock.position());
+ assertEquals(Long.MAX_VALUE, fileLock.size());
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock()
+ */
+ public void test_tryLock_Overlapping() throws Exception {
+ fileLock = writeOnlyFileChannel.tryLock();
+ assertTrue(fileLock.isValid());
+
+ // Test the same channel cannot be locked twice.
+ try {
+ writeOnlyFileChannel.tryLock();
+ fail("should throw OverlappingFileLockException");
+ } catch (OverlappingFileLockException expected) {}
+
+ // Test that a different channel on the same file also cannot be locked.
+ try {
+ writeOnlyFileChannel2.tryLock();
+ fail("should throw OverlappingFileLockException");
+ } catch (OverlappingFileLockException expected) {}
+ }
+
+ /**
+ * @tests java.nio.channels.FileChannel#tryLock()
+ */
+ public void test_tryLock_After_Release() throws Exception {
+ fileLock = writeOnlyFileChannel.tryLock();
+ fileLock.release();
+
+ // After release file lock can be obtained again.
+ fileLock = writeOnlyFileChannel.tryLock();
+ assertTrue(fileLock.isValid());
+
+ // Test that the same channel can acquire the lock after it has been released
+ fileLock.release();
+ fileLock = writeOnlyFileChannel.tryLock();
+ assertTrue(fileLock.isValid());
+
+ // Test that a different channel can acquire the lock after it has been released
+ fileLock.release();
+ fileLock = writeOnlyFileChannel2.tryLock();
+ assertTrue(fileLock.isValid());
}
/**
@@ -1034,12 +1127,17 @@
fileLock = writeOnlyFileChannel.lock(POSITION, SIZE, false);
assertTrue(fileLock.isValid());
+ // Test the same channel cannot be locked twice.
try {
- writeOnlyFileChannel.lock(POSITION + 1, SIZE, false);
+ writeOnlyFileChannel.tryLock(POSITION + 1, SIZE, false);
fail("should throw OverlappingFileLockException");
- } catch (OverlappingFileLockException e) {
- // expected
- }
+ } catch (OverlappingFileLockException expected) {}
+
+ // Test that a different channel on the same file also cannot be locked.
+ try {
+ writeOnlyFileChannel2.tryLock(POSITION + 1, SIZE, false);
+ fail("should throw OverlappingFileLockException");
+ } catch (OverlappingFileLockException expected) {}
}
/**