Skip to content

Commit b662958

Browse files
committed
Test fix for ReadAheadInputStream now restores the current thread's
interrupt flag when catching InterruptedException.
1 parent ada9744 commit b662958

2 files changed

Lines changed: 30 additions & 2 deletions

File tree

src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,7 @@ public void close() throws IOException {
294294
}
295295
if (shutdownExecutorService) {
296296
try {
297-
executorService.shutdownNow();
298-
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
297+
shutdownAwait();
299298
} catch (final InterruptedException e) {
300299
Thread.currentThread().interrupt();
301300
throw Input.toInterruptedIOException(e);
@@ -464,6 +463,11 @@ private void readAsync() throws IOException {
464463
});
465464
}
466465

466+
boolean shutdownAwait() throws InterruptedException {
467+
executorService.shutdownNow();
468+
return executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
469+
}
470+
467471
private void signalAsyncReadComplete() {
468472
stateChangeLock.lock();
469473
try {

src/test/java/org/apache/commons/io/input/ReadAheadInputStreamTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,24 @@
1818
package org.apache.commons.io.input;
1919

2020
import static org.junit.jupiter.api.Assertions.assertEquals;
21+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
2122
import static org.junit.jupiter.api.Assertions.assertThrows;
23+
import static org.junit.jupiter.api.Assertions.assertTrue;
24+
import static org.mockito.Mockito.spy;
25+
import static org.mockito.Mockito.when;
2226

2327
import java.io.FileInputStream;
2428
import java.io.IOException;
2529
import java.io.InputStream;
30+
import java.io.InterruptedIOException;
2631
import java.nio.file.StandardOpenOption;
2732
import java.util.concurrent.ExecutorService;
2833
import java.util.concurrent.Executors;
34+
import java.util.concurrent.TimeUnit;
2935

3036
import org.junit.jupiter.api.BeforeEach;
3137
import org.junit.jupiter.api.Test;
38+
import org.junit.jupiter.api.Timeout;
3239

3340
/**
3441
* Tests {@link ReadAheadInputStream}. This class was ported and adapted from Apache Spark commit 933dc6cb7b3de1d8ccaf73d124d6eb95b947ed19 where it was called
@@ -64,6 +71,22 @@ void setUpInputStreams() throws IOException {
6471
ReadAheadInputStream.builder().setPath(InputPath).setOpenOptions(StandardOpenOption.READ).get() };
6572
}
6673

74+
@Test
75+
@Timeout(value = 5, unit = TimeUnit.SECONDS)
76+
synchronized void testCloseInterrupt() throws IOException, InterruptedException {
77+
try (ReadAheadInputStream inputStream = ReadAheadInputStream.builder()
78+
// @formatter:off
79+
.setPath(InputPath)
80+
.get()) {
81+
// @formatter:on
82+
final ReadAheadInputStream spy = spy(inputStream);
83+
when(spy.shutdownAwait()).thenThrow(InterruptedException.class);
84+
Thread.currentThread().interrupt();
85+
assertInstanceOf(InterruptedException.class, assertThrows(InterruptedIOException.class, spy::close).getCause());
86+
assertTrue(Thread.interrupted());
87+
}
88+
}
89+
6790
@Test
6891
void testClosePlusExecutorService() throws IOException {
6992
final ExecutorService externalExecutor = Executors.newSingleThreadExecutor();
@@ -82,4 +105,5 @@ void testClosePlusExecutorService() throws IOException {
82105
}
83106
}
84107
}
108+
85109
}

0 commit comments

Comments
 (0)