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
The following commit(s) were added to refs/heads/master by this push: new 8159b8f98 ThresholdingOutputStream: a negative threshold should behave like a zero threshold and trigger the event on the first write (#609) 8159b8f98 is described below commit 8159b8f98d0d707cb17cb3d4cbbd40cafc061cec Author: rproserpio <48475312+rproser...@users.noreply.github.com> AuthorDate: Fri Apr 5 01:47:51 2024 +0200 ThresholdingOutputStream: a negative threshold should behave like a zero threshold and trigger the event on the first write (#609) * add failing test for negative threshold * revert [IO-405] A negative threshold should behave like a threshold of 0. Until the first write the threshold is not reached actually, then the callback is called. * fix typo in comment * if the event has not been triggered, thresholdExceeded should be false. * a negative threshold should behave like a zero behavior. revert other changes * remove stale comment --------- Co-authored-by: r.proserpio <r.proserpio> --- .../io/output/ThresholdingOutputStream.java | 4 +-- .../io/output/DeferredFileOutputStreamTest.java | 22 +++++++++++++ .../io/output/ThresholdingOutputStreamTest.java | 36 +++++++++++++++++++++- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java b/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java index fd7a8614f..c0bf60133 100644 --- a/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java @@ -81,6 +81,7 @@ public class ThresholdingOutputStream extends OutputStream { /** * Constructs an instance of this class which will trigger an event at the specified threshold. + * A negative threshold has no meaning and will be treated as 0 * * @param threshold The number of bytes at which to trigger an event. * @param thresholdConsumer Accepts reaching the threshold. @@ -89,10 +90,9 @@ public class ThresholdingOutputStream extends OutputStream { */ public ThresholdingOutputStream(final int threshold, final IOConsumer<ThresholdingOutputStream> thresholdConsumer, final IOFunction<ThresholdingOutputStream, OutputStream> outputStreamGetter) { - this.threshold = threshold; + this.threshold = threshold < 0 ? 0 : threshold; this.thresholdConsumer = thresholdConsumer == null ? IOConsumer.noop() : thresholdConsumer; this.outputStreamGetter = outputStreamGetter == null ? NOOP_OS_GETTER : outputStreamGetter; - this.thresholdExceeded = threshold < 0; } /** diff --git a/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java b/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java index 08e38c179..d4128455d 100644 --- a/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java +++ b/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java @@ -104,6 +104,28 @@ public class DeferredFileOutputStreamTest extends AbstractTempDirTest { } } + /** + * Tests the case where the threshold is negative, and therefore the data is always written to disk. The actual data + * written to disk is verified, as is the file itself. + */ + @ParameterizedTest(name = "initialBufferSize = {0}") + @MethodSource("data") + public void testThresholdNegative(final int initialBufferSize) throws IOException { + final File testFile = Files.createTempFile(tempDirPath, "testThresholdNegative", "dat").toFile(); + try (DeferredFileOutputStream dfos = DeferredFileOutputStream.builder() + .setThreshold(-1) + .setBufferSize(initialBufferSize) + .setOutputFile(testFile) + .get()) { + dfos.write(testBytes, 0, testBytes.length); + dfos.close(); + assertFalse(dfos.isInMemory()); + assertNull(dfos.getData()); + assertEquals(testFile.length(), dfos.getByteCount()); + verifyResultFile(testFile); + } + } + /** * Tests the case where the amount of data is exactly the same as the threshold. The behavior should be the same as * that for the amount of data being below (i.e. not exceeding) the threshold. diff --git a/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java b/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java index cc03f8da1..43916438d 100644 --- a/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java +++ b/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java @@ -32,13 +32,47 @@ import org.junit.jupiter.api.Test; */ public class ThresholdingOutputStreamTest { + /** + * Tests the case where the threshold is negative. + * The threshold is not reached until something is written to the stream. + */ @Test public void testThresholdLessThanZero() throws IOException { - try (final ThresholdingOutputStream out = new ThresholdingOutputStream(-1)) { + final AtomicBoolean reached = new AtomicBoolean(); + try (final ThresholdingOutputStream out = new ThresholdingOutputStream(-1) { + @Override + protected void thresholdReached() throws IOException { + reached.set(true); + } + }) { + assertFalse(reached.get()); + out.write(89); + assertTrue(reached.get()); assertTrue(out.isThresholdExceeded()); } } + /** + * Tests the case where no bytes are written. + * The threshold is not reached until something is written to the stream. + */ + @Test + public void testThresholdZeroWrite() throws IOException { + final AtomicBoolean reached = new AtomicBoolean(); + try (final ThresholdingOutputStream out = new ThresholdingOutputStream(7) { + @Override + protected void thresholdReached() throws IOException { + reached.set(true); + } + }) { + assertFalse(out.isThresholdExceeded()); + assertFalse(reached.get()); + out.write(new byte[0]); + assertFalse(out.isThresholdExceeded()); + assertFalse(reached.get()); + } + } + @Test public void testThresholdZero() throws IOException { final AtomicBoolean reached = new AtomicBoolean();