aboutsummaryrefslogtreecommitdiff
path: root/jimfs/src/test/java
diff options
context:
space:
mode:
authorcgdecker <cgdecker@google.com>2015-04-17 13:31:08 -0700
committerColin Decker <cgdecker@google.com>2015-04-17 17:26:16 -0400
commit5ce1143d312382df61b0f98e31d5870b94b2470f (patch)
treec3949b9956a98bfd4dd194c8403c21c255dd0f1b /jimfs/src/test/java
parentc1a7fcd013ea594762e1d348a7e2f6bafd783411 (diff)
downloadjimfs-5ce1143d312382df61b0f98e31d5870b94b2470f.tar.gz
Several changes to JimfsFileChannel.
- Update it to handle thread interruption for all methods that handle interruption in the default FileChannel implementation (with the exception of map(), for which we always throw UOE). For most methods that weren't already handling interruption, this mostly just means that if they're called on a thread that's already interrupted they'll throw ClosedByInterruptException and close the channel. Requested in GitHub issue #21. Also add tests for this. - Make it possible for FileChannel methods that don't use the channel's position (they have a parameter for a specific file position) to proceed concurrently with other FileChannel methods, which is specified as legal in the FileChannel docs: "Other operations, in particular those that take an explicit position, may proceed concurrently". ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=91435386
Diffstat (limited to 'jimfs/src/test/java')
-rw-r--r--jimfs/src/test/java/com/google/common/jimfs/JimfsFileChannelTest.java127
1 files changed, 127 insertions, 0 deletions
diff --git a/jimfs/src/test/java/com/google/common/jimfs/JimfsFileChannelTest.java b/jimfs/src/test/java/com/google/common/jimfs/JimfsFileChannelTest.java
index 2eb0743..756364a 100644
--- a/jimfs/src/test/java/com/google/common/jimfs/JimfsFileChannelTest.java
+++ b/jimfs/src/test/java/com/google/common/jimfs/JimfsFileChannelTest.java
@@ -871,4 +871,131 @@ public class JimfsFileChannelTest {
return futures;
}
+
+ /**
+ * Tests that the methods on the default FileChannel that support InterruptibleChannel behavior
+ * also support it on JimfsFileChannel, by just interrupting the thread before calling the
+ * method.
+ */
+ @Test
+ public void testInterruptedThreads() throws IOException {
+ final ByteBuffer buf = ByteBuffer.allocate(10);
+ final ByteBuffer[] bufArray = { buf };
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.size();
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.position();
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.position(0);
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.write(buf);
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.write(bufArray, 0, 1);
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.read(buf);
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.read(bufArray, 0, 1);
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.write(buf, 0);
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.read(buf, 0);
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.transferTo(0, 1, channel(regularFile(10), READ, WRITE));
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.transferFrom(channel(regularFile(10), READ, WRITE), 0, 1);
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.force(true);
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.truncate(0);
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.lock(0, 1, true);
+ }
+ });
+
+ assertClosedByInterrupt(new FileChannelMethod() {
+ @Override public void call(FileChannel channel) throws IOException {
+ channel.tryLock(0, 1, true);
+ }
+ });
+
+ // the map() method always throws UnsupportedOperationException; it doesn't make sense for it
+ // to try to handle thread interruption
+ }
+
+ private interface FileChannelMethod {
+ void call(FileChannel channel) throws IOException;
+ }
+
+ /**
+ * Asserts that when the given operation is run on an interrupted thread,
+ * {@code ClosedByInterruptException} is thrown, the channel is closed and the thread is no
+ * longer interrupted.
+ */
+ private static void assertClosedByInterrupt(FileChannelMethod method) throws IOException {
+ FileChannel channel = channel(regularFile(10), READ, WRITE);
+ Thread.currentThread().interrupt();
+ try {
+ method.call(channel);
+ fail("expected the method to throw ClosedByInterruptException");
+ } catch (ClosedByInterruptException expected) {
+ assertFalse("expected the channel to be closed", channel.isOpen());
+ assertTrue("expected the thread to still be interrupted", Thread.interrupted());
+ } finally {
+ Thread.interrupted(); // ensure the thread isn't interrupted when this method returns
+ }
+ }
}