This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-io.git
commit 69e3b819a154793128ec7c0336d33623f6cc8a21 Author: Gary Gregory <gardgreg...@gmail.com> AuthorDate: Sun Sep 19 12:15:50 2021 -0400 Method that allocates should release resources. Use try-with-resources with Tailer as an AutoCloseable. All tests now manage its own resource. --- .../java/org/apache/commons/io/input/Tailer.java | 17 +- .../org/apache/commons/io/input/TailerTest.java | 456 +++++++++++---------- 2 files changed, 247 insertions(+), 226 deletions(-) diff --git a/src/main/java/org/apache/commons/io/input/Tailer.java b/src/main/java/org/apache/commons/io/input/Tailer.java index c881f32..349f848 100644 --- a/src/main/java/org/apache/commons/io/input/Tailer.java +++ b/src/main/java/org/apache/commons/io/input/Tailer.java @@ -155,7 +155,7 @@ import org.apache.commons.io.file.attribute.FileTimes; * alternative libraries such as jCIFS or <a href="https://commons.apache.org/proper/commons-vfs/">Apache Commons * VFS</a>. */ -public class Tailer implements Runnable { +public class Tailer implements Runnable, AutoCloseable { /** * Builds a {@link Tailer} with default values. @@ -769,6 +769,14 @@ public class Tailer implements Runnable { } /** + * Requests the tailer to complete its current loop and return. + */ + @Override + public void close() { + this.run = false; + } + + /** * Gets the delay in milliseconds. * * @return the delay in milliseconds. @@ -963,14 +971,17 @@ public class Tailer implements Runnable { } catch (final IOException e) { listener.handle(e); } - stop(); + close(); } } /** * Requests the tailer to complete its current loop and return. + * + * @deprecated Use {@link #close()}. */ + @Deprecated public void stop() { - this.run = false; + close(); } } diff --git a/src/test/java/org/apache/commons/io/input/TailerTest.java b/src/test/java/org/apache/commons/io/input/TailerTest.java index 97f8ea3..6ce918e 100644 --- a/src/test/java/org/apache/commons/io/input/TailerTest.java +++ b/src/test/java/org/apache/commons/io/input/TailerTest.java @@ -45,7 +45,6 @@ import java.util.concurrent.Executor; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import com.google.common.collect.Lists; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.TestResources; @@ -54,6 +53,8 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import com.google.common.collect.Lists; + /** * Test for {@link Tailer}. */ @@ -143,7 +144,7 @@ public class TailerTest { latch = new CountDownLatch(expectedLines); } - public boolean awaitExpectedLines(long timeout, TimeUnit timeUnit) throws InterruptedException { + public boolean awaitExpectedLines(final long timeout, final TimeUnit timeUnit) throws InterruptedException { return latch.await(timeout, timeUnit); } @@ -190,8 +191,6 @@ public class TailerTest { @TempDir public static File temporaryFolder; - private Tailer tailer; - protected void createFile(final File file, final long size) throws IOException { assertTrue(file.getParentFile().exists(), () -> "Cannot create file " + file + " as the parent directory does not exist"); try (final BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) { @@ -215,13 +214,6 @@ public class TailerTest { } } - @AfterEach - public void tearDown() { - if (tailer != null) { - tailer.stop(); - } - } - @Test @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case" public void testBufferBreak() throws Exception { @@ -232,17 +224,17 @@ public class TailerTest { writeString(file, "SBTOURIST\n"); final TestTailerListener listener = new TestTailerListener(); - tailer = new Tailer(file, listener, delay, false, 1); + try (Tailer tailer = new Tailer(file, listener, delay, false, 1)) { + final Thread thread = new Thread(tailer); + thread.start(); - final Thread thread = new Thread(tailer); - thread.start(); + List<String> lines = listener.getLines(); + while (lines.isEmpty() || !lines.get(lines.size() - 1).equals("SBTOURIST")) { + lines = listener.getLines(); + } - List<String> lines = listener.getLines(); - while (lines.isEmpty() || !lines.get(lines.size() - 1).equals("SBTOURIST")) { - lines = listener.getLines(); + listener.clear(); } - - listener.clear(); } @Test @@ -250,9 +242,10 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start-with-reopen-and-buffersize-and-charset.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = new Tailer.Builder(new NonStandardTailable(file), listener).build(); - assertTrue(tailer.getTailable() instanceof NonStandardTailable); - validateTailer(listener, tailer, file); + try (final Tailer tailer = new Tailer.Builder(new NonStandardTailable(file), listener).build()) { + assertTrue(tailer.getTailable() instanceof NonStandardTailable); + validateTailer(listener, tailer, file); + } } @Test @@ -260,8 +253,9 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-create.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = Tailer.create(file, listener); - validateTailer(listener, tailer, file); + try (final Tailer tailer = Tailer.create(file, listener)) { + validateTailer(listener, tailer, file); + } } @Test @@ -269,8 +263,9 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start-with-reopen.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, false); - validateTailer(listener, tailer, file); + try (final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, false)) { + validateTailer(listener, tailer, file); + } } @Test @@ -278,8 +273,9 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-create-with-delay.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS); - validateTailer(listener, tailer, file); + try (final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS)) { + validateTailer(listener, tailer, file); + } } @Test @@ -287,8 +283,9 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false); - validateTailer(listener, tailer, file); + try (final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false)) { + validateTailer(listener, tailer, file); + } } @Test @@ -296,8 +293,9 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start-with-buffersize.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, TEST_BUFFER_SIZE); - validateTailer(listener, tailer, file); + try (final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, TEST_BUFFER_SIZE)) { + validateTailer(listener, tailer, file); + } } @Test @@ -305,8 +303,9 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start-with-reopen-and-buffersize.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE); - validateTailer(listener, tailer, file); + try (final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE)) { + validateTailer(listener, tailer, file); + } } @Test @@ -314,8 +313,9 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start-with-reopen-and-buffersize-and-charset.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = Tailer.create(file, StandardCharsets.UTF_8, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE); - validateTailer(listener, tailer, file); + try (final Tailer tailer = Tailer.create(file, StandardCharsets.UTF_8, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE)) { + validateTailer(listener, tailer, file); + } } /* @@ -329,19 +329,20 @@ public class TailerTest { // Use a long delay to try to make sure the test thread calls interrupt() while the tailer thread is sleeping. final int delay = 1000; final int idle = 50; // allow time for thread to work - tailer = new Tailer(file, listener, delay, false, IOUtils.DEFAULT_BUFFER_SIZE); - final Thread thread = new Thread(tailer); - thread.setDaemon(true); - thread.start(); - TestUtils.sleep(idle); - thread.interrupt(); - TestUtils.sleep(delay + idle); - assertNotNull(listener.exception, "Missing InterruptedException"); - assertTrue(listener.exception instanceof InterruptedException, "Unexpected Exception: " + listener.exception); - assertEquals(1, listener.initialized, "Expected init to be called"); - assertTrue(listener.notFound > 0, "fileNotFound should be called"); - assertEquals(0, listener.rotated, "fileRotated should be not be called"); - assertEquals(0, listener.reachedEndOfFile, "end of file never reached"); + try (Tailer tailer = new Tailer(file, listener, delay, false, IOUtils.DEFAULT_BUFFER_SIZE)) { + final Thread thread = new Thread(tailer); + thread.setDaemon(true); + thread.start(); + TestUtils.sleep(idle); + thread.interrupt(); + TestUtils.sleep(delay + idle); + assertNotNull(listener.exception, "Missing InterruptedException"); + assertTrue(listener.exception instanceof InterruptedException, "Unexpected Exception: " + listener.exception); + assertEquals(1, listener.initialized, "Expected init to be called"); + assertTrue(listener.notFound > 0, "fileNotFound should be called"); + assertEquals(0, listener.rotated, "fileRotated should be not be called"); + assertEquals(0, listener.reachedEndOfFile, "end of file never reached"); + } } @Test @@ -351,20 +352,21 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-testio334.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(); - tailer = new Tailer(file, listener, delayMillis, false); - final Thread thread = new Thread(tailer); - thread.start(); + try (Tailer tailer = new Tailer(file, listener, delayMillis, false)) { + final Thread thread = new Thread(tailer); + thread.start(); - // Write some lines to the file - writeString(file, "CRLF\r\n", "LF\n", "CR\r", "CRCR\r\r", "trail"); - final long testDelayMillis = delayMillis * 10; - TestUtils.sleep(testDelayMillis); - final List<String> lines = listener.getLines(); - assertEquals(4, lines.size(), "line count"); - assertEquals("CRLF", lines.get(0), "line 1"); - assertEquals("LF", lines.get(1), "line 2"); - assertEquals("CR", lines.get(2), "line 3"); - assertEquals("CRCR\r", lines.get(3), "line 4"); + // Write some lines to the file + writeString(file, "CRLF\r\n", "LF\n", "CR\r", "CRCR\r\r", "trail"); + final long testDelayMillis = delayMillis * 10; + TestUtils.sleep(testDelayMillis); + final List<String> lines = listener.getLines(); + assertEquals(4, lines.size(), "line count"); + assertEquals("CRLF", lines.get(0), "line 1"); + assertEquals("LF", lines.get(1), "line 2"); + assertEquals("CR", lines.get(2), "line 3"); + assertEquals("CRCR\r", lines.get(3), "line 4"); + } } @Test @@ -382,20 +384,21 @@ public class TailerTest { } final TestTailerListener listener = new TestTailerListener(); - tailer = new Tailer(file, listener, delay, false); + try (Tailer tailer = new Tailer(file, listener, delay, false)) { - // final long start = System.currentTimeMillis(); + // final long start = System.currentTimeMillis(); - final Thread thread = new Thread(tailer); - thread.start(); + final Thread thread = new Thread(tailer); + thread.start(); - List<String> lines = listener.getLines(); - while (lines.isEmpty() || !lines.get(lines.size() - 1).equals("SBTOURIST")) { - lines = listener.getLines(); - } - // System.out.println("Elapsed: " + (System.currentTimeMillis() - start)); + List<String> lines = listener.getLines(); + while (lines.isEmpty() || !lines.get(lines.size() - 1).equals("SBTOURIST")) { + lines = listener.getLines(); + } + // System.out.println("Elapsed: " + (System.currentTimeMillis() - start)); - listener.clear(); + listener.clear(); + } } @Test @@ -410,30 +413,31 @@ public class TailerTest { final boolean isWindows = osname.startsWith("Windows"); // Need to use UTF-8 to read & write the file otherwise it can be corrupted (depending on the default charset) final Charset charsetUTF8 = StandardCharsets.UTF_8; - tailer = new Tailer(file, charsetUTF8, listener, delay, false, isWindows, IOUtils.DEFAULT_BUFFER_SIZE); - final Thread thread = new Thread(tailer); - thread.start(); - - try (Writer out = new OutputStreamWriter(Files.newOutputStream(file.toPath()), charsetUTF8); - BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(origin.toPath()), charsetUTF8))) { - final List<String> lines = new ArrayList<>(); - String line; - while ((line = reader.readLine()) != null) { - out.write(line); - out.write("\n"); - lines.add(line); - } - out.close(); // ensure data is written - - final long testDelayMillis = delay * 10; - TestUtils.sleep(testDelayMillis); - final List<String> tailerlines = listener.getLines(); - assertEquals(lines.size(), tailerlines.size(), "line count"); - for (int i = 0, len = lines.size(); i < len; i++) { - final String expected = lines.get(i); - final String actual = tailerlines.get(i); - if (!expected.equals(actual)) { - fail("Line: " + i + "\nExp: (" + expected.length() + ") " + expected + "\nAct: (" + actual.length() + ") " + actual); + try (Tailer tailer = new Tailer(file, charsetUTF8, listener, delay, false, isWindows, IOUtils.DEFAULT_BUFFER_SIZE)) { + final Thread thread = new Thread(tailer); + thread.start(); + + try (Writer out = new OutputStreamWriter(Files.newOutputStream(file.toPath()), charsetUTF8); + BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(origin.toPath()), charsetUTF8))) { + final List<String> lines = new ArrayList<>(); + String line; + while ((line = reader.readLine()) != null) { + out.write(line); + out.write("\n"); + lines.add(line); + } + out.close(); // ensure data is written + + final long testDelayMillis = delay * 10; + TestUtils.sleep(testDelayMillis); + final List<String> tailerlines = listener.getLines(); + assertEquals(lines.size(), tailerlines.size(), "line count"); + for (int i = 0, len = lines.size(); i < len; i++) { + final String expected = lines.get(i); + final String actual = tailerlines.get(i); + if (!expected.equals(actual)) { + fail("Line: " + i + "\nExp: (" + expected.length() + ") " + expected + "\nAct: (" + actual.length() + ") " + actual); + } } } } @@ -444,10 +448,11 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-simple-constructor.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = new Tailer(file, listener); - final Thread thread = new Thread(tailer); - thread.start(); - validateTailer(listener, tailer, file); + try (final Tailer tailer = new Tailer(file, listener)) { + final Thread thread = new Thread(tailer); + thread.start(); + validateTailer(listener, tailer, file); + } } @Test @@ -455,10 +460,11 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS); - final Thread thread = new Thread(tailer); - thread.start(); - validateTailer(listener, tailer, file); + try (final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS)) { + final Thread thread = new Thread(tailer); + thread.start(); + validateTailer(listener, tailer, file); + } } @Test @@ -466,10 +472,11 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay-and-from-start.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false); - final Thread thread = new Thread(tailer); - thread.start(); - validateTailer(listener, tailer, file); + try (final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false)) { + final Thread thread = new Thread(tailer); + thread.start(); + validateTailer(listener, tailer, file); + } } @Test @@ -477,10 +484,11 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay-and-from-start-with-buffersize.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, TEST_BUFFER_SIZE); - final Thread thread = new Thread(tailer); - thread.start(); - validateTailer(listener, tailer, file); + try (final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, TEST_BUFFER_SIZE)) { + final Thread thread = new Thread(tailer); + thread.start(); + validateTailer(listener, tailer, file); + } } @Test @@ -488,10 +496,11 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay-and-from-start-with-reopen.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, false); - final Thread thread = new Thread(tailer); - thread.start(); - validateTailer(listener, tailer, file); + try (final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, false)) { + final Thread thread = new Thread(tailer); + thread.start(); + validateTailer(listener, tailer, file); + } } @Test @@ -499,10 +508,11 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay-and-from-start-with-reopen-and-buffersize.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE); - final Thread thread = new Thread(tailer); - thread.start(); - validateTailer(listener, tailer, file); + try (final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE)) { + final Thread thread = new Thread(tailer); + thread.start(); + validateTailer(listener, tailer, file); + } } @Test @@ -510,10 +520,11 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay-and-from-start-with-reopen-and-buffersize-and-charset.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); - final Tailer tailer = new Tailer(file, StandardCharsets.UTF_8, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE); - final Thread thread = new Thread(tailer); - thread.start(); - validateTailer(listener, tailer, file); + try (final Tailer tailer = new Tailer(file, StandardCharsets.UTF_8, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE)) { + final Thread thread = new Thread(tailer); + thread.start(); + validateTailer(listener, tailer, file); + } } @Test @@ -523,9 +534,9 @@ public class TailerTest { final TestTailerListener listener = new TestTailerListener(); final int delay = 100; final int idle = 50; // allow time for thread to work - tailer = Tailer.create(file, listener, delay, false); - TestUtils.sleep(idle); - tailer.stop(); + try (Tailer tailer = Tailer.create(file, listener, delay, false)) { + TestUtils.sleep(idle); + } TestUtils.sleep(delay + idle); assertNull(listener.exception, "Should not generate Exception"); assertEquals(1, listener.initialized, "Expected init to be called"); @@ -541,11 +552,11 @@ public class TailerTest { final TestTailerListener listener = new TestTailerListener(); final int delay = 100; final int idle = 50; // allow time for thread to work - tailer = new Tailer(file, listener, delay, false); - final Executor exec = new ScheduledThreadPoolExecutor(1); - exec.execute(tailer); - TestUtils.sleep(idle); - tailer.stop(); + try (Tailer tailer = new Tailer(file, listener, delay, false)) { + final Executor exec = new ScheduledThreadPoolExecutor(1); + exec.execute(tailer); + TestUtils.sleep(idle); + } TestUtils.sleep(delay + idle); assertNull(listener.exception, "Should not generate Exception"); assertEquals(1, listener.initialized, "Expected init to be called"); @@ -564,61 +575,62 @@ public class TailerTest { final TestTailerListener listener = new TestTailerListener(); final String osname = System.getProperty("os.name"); final boolean isWindows = osname.startsWith("Windows"); - tailer = new Tailer(file, listener, delayMillis, false, isWindows); - final Thread thread = new Thread(tailer); - thread.start(); + try (Tailer tailer = new Tailer(file, listener, delayMillis, false, isWindows)) { + final Thread thread = new Thread(tailer); + thread.start(); - // Write some lines to the file - write(file, "Line one", "Line two"); - final long testDelayMillis = delayMillis * 10; - TestUtils.sleep(testDelayMillis); - List<String> lines = listener.getLines(); - assertEquals(2, lines.size(), "1 line count"); - assertEquals("Line one", lines.get(0), "1 line 1"); - assertEquals("Line two", lines.get(1), "1 line 2"); - listener.clear(); - - // Write another line to the file - write(file, "Line three"); - TestUtils.sleep(testDelayMillis); - lines = listener.getLines(); - assertEquals(1, lines.size(), "2 line count"); - assertEquals("Line three", lines.get(0), "2 line 3"); - listener.clear(); - - // Check file does actually have all the lines - lines = FileUtils.readLines(file, "UTF-8"); - assertEquals(3, lines.size(), "3 line count"); - assertEquals("Line one", lines.get(0), "3 line 1"); - assertEquals("Line two", lines.get(1), "3 line 2"); - assertEquals("Line three", lines.get(2), "3 line 3"); - - // Delete & re-create - file.delete(); - assertFalse(file.exists(), "File should not exist"); - createFile(file, 0); - assertTrue(file.exists(), "File should now exist"); - TestUtils.sleep(testDelayMillis); - - // Write another line - write(file, "Line four"); - TestUtils.sleep(testDelayMillis); - lines = listener.getLines(); - assertEquals(1, lines.size(), "4 line count"); - assertEquals("Line four", lines.get(0), "4 line 3"); - listener.clear(); - - // Stop - thread.interrupt(); - TestUtils.sleep(testDelayMillis * 4); - write(file, "Line five"); - assertEquals(0, listener.getLines().size(), "4 line count"); - assertNotNull(listener.exception, "Missing InterruptedException"); - assertTrue(listener.exception instanceof InterruptedException, "Unexpected Exception: " + listener.exception); - assertEquals(1, listener.initialized, "Expected init to be called"); - // assertEquals(0 , listener.notFound, "fileNotFound should not be called"); // there is a window when it might be - // called - assertEquals(1, listener.rotated, "fileRotated should be be called"); + // Write some lines to the file + write(file, "Line one", "Line two"); + final long testDelayMillis = delayMillis * 10; + TestUtils.sleep(testDelayMillis); + List<String> lines = listener.getLines(); + assertEquals(2, lines.size(), "1 line count"); + assertEquals("Line one", lines.get(0), "1 line 1"); + assertEquals("Line two", lines.get(1), "1 line 2"); + listener.clear(); + + // Write another line to the file + write(file, "Line three"); + TestUtils.sleep(testDelayMillis); + lines = listener.getLines(); + assertEquals(1, lines.size(), "2 line count"); + assertEquals("Line three", lines.get(0), "2 line 3"); + listener.clear(); + + // Check file does actually have all the lines + lines = FileUtils.readLines(file, "UTF-8"); + assertEquals(3, lines.size(), "3 line count"); + assertEquals("Line one", lines.get(0), "3 line 1"); + assertEquals("Line two", lines.get(1), "3 line 2"); + assertEquals("Line three", lines.get(2), "3 line 3"); + + // Delete & re-create + file.delete(); + assertFalse(file.exists(), "File should not exist"); + createFile(file, 0); + assertTrue(file.exists(), "File should now exist"); + TestUtils.sleep(testDelayMillis); + + // Write another line + write(file, "Line four"); + TestUtils.sleep(testDelayMillis); + lines = listener.getLines(); + assertEquals(1, lines.size(), "4 line count"); + assertEquals("Line four", lines.get(0), "4 line 3"); + listener.clear(); + + // Stop + thread.interrupt(); + TestUtils.sleep(testDelayMillis * 4); + write(file, "Line five"); + assertEquals(0, listener.getLines().size(), "4 line count"); + assertNotNull(listener.exception, "Missing InterruptedException"); + assertTrue(listener.exception instanceof InterruptedException, "Unexpected Exception: " + listener.exception); + assertEquals(1, listener.initialized, "Expected init to be called"); + // assertEquals(0 , listener.notFound, "fileNotFound should not be called"); // there is a window when it might be + // called + assertEquals(1, listener.rotated, "fileRotated should be be called"); + } } @Test @@ -631,24 +643,25 @@ public class TailerTest { final TestTailerListener listener = new TestTailerListener(); final String osname = System.getProperty("os.name"); final boolean isWindows = osname.startsWith("Windows"); - tailer = new Tailer(file, listener, delayMillis, false, isWindows); - final Thread thread = new Thread(tailer); - thread.start(); + try (Tailer tailer = new Tailer(file, listener, delayMillis, false, isWindows)) { + final Thread thread = new Thread(tailer); + thread.start(); - // write a few lines - write(file, "line1", "line2", "line3"); - TestUtils.sleep(testDelayMillis); + // write a few lines + write(file, "line1", "line2", "line3"); + TestUtils.sleep(testDelayMillis); - // write a few lines - write(file, "line4", "line5", "line6"); - TestUtils.sleep(testDelayMillis); + // write a few lines + write(file, "line4", "line5", "line6"); + TestUtils.sleep(testDelayMillis); - // write a few lines - write(file, "line7", "line8", "line9"); - TestUtils.sleep(testDelayMillis); + // write a few lines + write(file, "line7", "line8", "line9"); + TestUtils.sleep(testDelayMillis); - // May be > 3 times due to underlying OS behavior wrt streams - assertTrue(listener.reachedEndOfFile >= 3, "end of file reached at least 3 times"); + // May be > 3 times due to underlying OS behavior wrt streams + assertTrue(listener.reachedEndOfFile >= 3, "end of file reached at least 3 times"); + } } @Test @@ -658,37 +671,34 @@ public class TailerTest { final File file = new File(temporaryFolder, "tailer2-test.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(); - tailer = new Tailer(file, listener, delay, false); - final Thread thread = new Thread(tailer); - thread.start(); + try (Tailer tailer = new Tailer(file, listener, delay, false)) { + final Thread thread = new Thread(tailer); + thread.start(); - // Write some lines to the file - writeString(file, "Line"); + // Write some lines to the file + writeString(file, "Line"); - TestUtils.sleep(delay * 2); - List<String> lines = listener.getLines(); - assertEquals(0, lines.size(), "1 line count"); + TestUtils.sleep(delay * 2); + List<String> lines = listener.getLines(); + assertEquals(0, lines.size(), "1 line count"); - writeString(file, " one\n"); - TestUtils.sleep(delay * 2); - lines = listener.getLines(); + writeString(file, " one\n"); + TestUtils.sleep(delay * 2); + lines = listener.getLines(); - assertEquals(1, lines.size(), "1 line count"); - assertEquals("Line one", lines.get(0), "1 line 1"); + assertEquals(1, lines.size(), "1 line count"); + assertEquals("Line one", lines.get(0), "1 line 1"); - listener.clear(); + listener.clear(); + } } private void validateTailer(final TestTailerListener listener, final Tailer tailer, final File file) throws Exception { - try { - write(file, "foo"); - final int timeout = 30; - final TimeUnit timeoutUnit = TimeUnit.SECONDS; - assertTrue(listener.awaitExpectedLines(timeout, timeoutUnit), () -> String.format("await timed out after %s %s", timeout, timeoutUnit)); - assertEquals(listener.getLines(), Lists.newArrayList("foo"), "lines"); - } finally { - tailer.stop(); - } + write(file, "foo"); + final int timeout = 30; + final TimeUnit timeoutUnit = TimeUnit.SECONDS; + assertTrue(listener.awaitExpectedLines(timeout, timeoutUnit), () -> String.format("await timed out after %s %s", timeout, timeoutUnit)); + assertEquals(listener.getLines(), Lists.newArrayList("foo"), "lines"); } /** Appends lines to a file */