From 7aea8653b187b44f6c5ac088b34e37070110b7d9 Mon Sep 17 00:00:00 2001 From: Ceki Gulcu Date: Thu, 11 Feb 2016 23:21:18 +0100 Subject: [PATCH] next release is 1.1.5, fixed LOGBACK-898 --- logback-access/pom.xml | 2 +- logback-classic/pom.xml | 2 +- logback-core/pom.xml | 2 +- .../logback/core/AsyncAppenderBaseTest.java | 508 +++++++++--------- logback-examples/pom.xml | 2 +- logback-site/pom.xml | 2 +- logback-site/src/site/pages/news.html | 11 + pom.xml | 2 +- release.sh | 4 +- 9 files changed, 269 insertions(+), 266 deletions(-) diff --git a/logback-access/pom.xml b/logback-access/pom.xml index ba1802104..422bb0b9f 100755 --- a/logback-access/pom.xml +++ b/logback-access/pom.xml @@ -7,7 +7,7 @@ ch.qos.logback logback-parent - 1.1.4 + 1.1.5-SNAPSHOT logback-access diff --git a/logback-classic/pom.xml b/logback-classic/pom.xml index ca4af6357..bb22539ab 100755 --- a/logback-classic/pom.xml +++ b/logback-classic/pom.xml @@ -7,7 +7,7 @@ ch.qos.logback logback-parent - 1.1.4 + 1.1.5-SNAPSHOT logback-classic diff --git a/logback-core/pom.xml b/logback-core/pom.xml index e7d15c53d..2b8cb5768 100755 --- a/logback-core/pom.xml +++ b/logback-core/pom.xml @@ -7,7 +7,7 @@ ch.qos.logback logback-parent - 1.1.4 + 1.1.5-SNAPSHOT logback-core diff --git a/logback-core/src/test/java/ch/qos/logback/core/AsyncAppenderBaseTest.java b/logback-core/src/test/java/ch/qos/logback/core/AsyncAppenderBaseTest.java index 5306df896..d87d2aafe 100755 --- a/logback-core/src/test/java/ch/qos/logback/core/AsyncAppenderBaseTest.java +++ b/logback-core/src/test/java/ch/qos/logback/core/AsyncAppenderBaseTest.java @@ -13,274 +13,266 @@ */ package ch.qos.logback.core; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; + import ch.qos.logback.core.helpers.NOPAppender; import ch.qos.logback.core.read.ListAppender; -import ch.qos.logback.core.testUtil.DelayingListAppender; import ch.qos.logback.core.status.OnConsoleStatusListener; import ch.qos.logback.core.status.StatusChecker; +import ch.qos.logback.core.testUtil.DelayingListAppender; import ch.qos.logback.core.testUtil.NPEAppender; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - /** * @author Ceki Gülcü * @author Torsten Juergeleit */ public class AsyncAppenderBaseTest { - Context context = new ContextBase(); - AsyncAppenderBase asyncAppenderBase = new AsyncAppenderBase(); - LossyAsyncAppender lossyAsyncAppender = new LossyAsyncAppender(); - DelayingListAppender delayingListAppender = new DelayingListAppender(); - ListAppender listAppender = new ListAppender(); - OnConsoleStatusListener onConsoleStatusListener = new OnConsoleStatusListener(); - StatusChecker statusChecker = new StatusChecker(context); - - @Before - public void setUp() { - onConsoleStatusListener.setContext(context); - context.getStatusManager().add(onConsoleStatusListener); - onConsoleStatusListener.start(); - - asyncAppenderBase.setContext(context); - lossyAsyncAppender.setContext(context); - - listAppender.setContext(context); - listAppender.setName("list"); - listAppender.start(); - - delayingListAppender.setContext(context); - delayingListAppender.setName("list"); - delayingListAppender.start(); - } - - @Test(timeout = 2000) - public void smoke() { - asyncAppenderBase.addAppender(listAppender); - asyncAppenderBase.start(); - asyncAppenderBase.doAppend(0); - asyncAppenderBase.stop(); - verify(listAppender, 1); - } - - @Test - public void exceptionsShouldNotCauseHalting() throws InterruptedException { - NPEAppender npeAppender = new NPEAppender(); - npeAppender.setName("bad"); - npeAppender.setContext(context); - npeAppender.start(); - - asyncAppenderBase.addAppender(npeAppender); - asyncAppenderBase.start(); - assertTrue(asyncAppenderBase.isStarted()); - for (int i = 0; i < 10; i++) - asyncAppenderBase.append(i); - - asyncAppenderBase.stop(); - assertFalse(asyncAppenderBase.isStarted()); - assertEquals(AppenderBase.ALLOWED_REPEATS, - statusChecker - .matchCount("Appender \\[bad\\] failed to append.")); - } - - @Test(timeout = 2000) - public void emptyQueueShouldBeStoppable() { - asyncAppenderBase.addAppender(listAppender); - asyncAppenderBase.start(); - asyncAppenderBase.stop(); - verify(listAppender, 0); - } - - @Test(timeout = 2000) - public void workerShouldStopEvenIfInterruptExceptionConsumedWithinSubappender() { - delayingListAppender.delay = 100; - asyncAppenderBase.addAppender(delayingListAppender); - asyncAppenderBase.start(); - asyncAppenderBase.doAppend(0); - asyncAppenderBase.stop(); - verify(delayingListAppender, 1); - assertTrue(delayingListAppender.interrupted); - } - - @Test(timeout = 2000) - public void noEventLoss() { - int bufferSize = 10; - int loopLen = bufferSize * 2; - asyncAppenderBase.addAppender(delayingListAppender); - asyncAppenderBase.setQueueSize(bufferSize); - asyncAppenderBase.start(); - for (int i = 0; i < loopLen; i++) { - asyncAppenderBase.doAppend(i); - } - asyncAppenderBase.stop(); - verify(delayingListAppender, loopLen); - } - - @Test(timeout = 2000) - public void eventLossIfNeverBlock() { - int bufferSize = 10; - int loopLen = bufferSize * 2; - delayingListAppender.setDelay(5000); // something greater than the test timeout - asyncAppenderBase.addAppender(delayingListAppender); - asyncAppenderBase.setQueueSize(bufferSize); - asyncAppenderBase.setNeverBlock(true); - asyncAppenderBase.start(); - for (int i = 0; i < loopLen; i++) { - asyncAppenderBase.doAppend(i); - } - asyncAppenderBase.stop(); - // ListAppender size isn't a reliable test here, so just make sure we didn't - // have any errors, and that we could complete the test in time. - statusChecker.assertIsErrorFree(); - } - - @Test(timeout = 2000) - public void lossyAppenderShouldOnlyLooseCertainEvents() { - int bufferSize = 5; - int loopLen = bufferSize * 2; - lossyAsyncAppender.addAppender(delayingListAppender); - lossyAsyncAppender.setQueueSize(bufferSize); - lossyAsyncAppender.setDiscardingThreshold(1); - lossyAsyncAppender.start(); - for (int i = 0; i < loopLen; i++) { - lossyAsyncAppender.doAppend(i); - } - lossyAsyncAppender.stop(); - verify(delayingListAppender, loopLen - 2); - } - - @Test(timeout = 2000) - public void lossyAppenderShouldBeNonLossyIfDiscardingThresholdIsZero() { - int bufferSize = 5; - int loopLen = bufferSize * 2; - lossyAsyncAppender.addAppender(delayingListAppender); - lossyAsyncAppender.setQueueSize(bufferSize); - lossyAsyncAppender.setDiscardingThreshold(0); - lossyAsyncAppender.start(); - for (int i = 0; i < loopLen; i++) { - lossyAsyncAppender.doAppend(i); - } - lossyAsyncAppender.stop(); - verify(delayingListAppender, loopLen); - } - - @Test - public void invalidQueueCapacityShouldResultInNonStartedAppender() { - asyncAppenderBase.addAppender(new NOPAppender()); - asyncAppenderBase.setQueueSize(0); - assertEquals(0, asyncAppenderBase.getQueueSize()); - asyncAppenderBase.start(); - assertFalse(asyncAppenderBase.isStarted()); - statusChecker.assertContainsMatch("Invalid queue size"); - } - - @SuppressWarnings("deprecation") - @Test - public void workerThreadFlushesOnStop() { - int loopLen = 5; - int maxRuntime = (loopLen + 1) - * Math.max(1000, delayingListAppender.delay); - ListAppender la = delayingListAppender; - asyncAppenderBase.addAppender(la); - asyncAppenderBase.setDiscardingThreshold(0); - asyncAppenderBase.setMaxFlushTime(maxRuntime); - asyncAppenderBase.start(); - asyncAppenderBase.worker.suspend(); - - for (int i = 0; i < loopLen; i++) { - asyncAppenderBase.doAppend(i); - } - assertEquals(loopLen, asyncAppenderBase.getNumberOfElementsInQueue()); - assertEquals(0, la.list.size()); - - asyncAppenderBase.worker.resume(); - asyncAppenderBase.stop(); - - assertEquals(0, asyncAppenderBase.getNumberOfElementsInQueue()); - verify(la, loopLen); - } - - @SuppressWarnings("deprecation") - @Test - public void stopExitsWhenMaxRuntimeReached() throws InterruptedException { - int maxRuntime = 1; // runtime of 0 means wait forever, so use 1 ms - // instead - int loopLen = 10; - ListAppender la = delayingListAppender; - asyncAppenderBase.addAppender(la); - asyncAppenderBase.setMaxFlushTime(maxRuntime); - asyncAppenderBase.start(); - - for (int i = 0; i < loopLen; i++) { - asyncAppenderBase.doAppend(i); - } - - asyncAppenderBase.stop(); - - // suspend the thread so that we can make the following assertions - // without race conditions - asyncAppenderBase.worker.suspend(); - - // confirms that stop exited when runtime reached - statusChecker.assertContainsMatch("Max queue flush timeout \\(" - + maxRuntime + " ms\\) exceeded."); - - // confirms that the number of events posted are the number of events - // removed from the queue - assertEquals(la.list.size(), - loopLen - asyncAppenderBase.getNumberOfElementsInQueue()); - - // resume the thread to let it finish processing - asyncAppenderBase.worker.resume(); - - asyncAppenderBase.worker.join(); - - // confirms that all entries do end up being flushed if we wait long - // enough - verify(la, loopLen); - } - - - // Interruption of current thread when in doAppend method should not be consumed - // by async appender. See also http://jira.qos.ch/browse/LOGBACK-910 - @Test - public void verifyInterruptionIsNotSwallowed() { - asyncAppenderBase.addAppender(delayingListAppender); - asyncAppenderBase.start(); - Thread.currentThread().interrupt(); - asyncAppenderBase.doAppend(new Integer(0)); - assertTrue(Thread.currentThread().isInterrupted()); - // clear flag for next test - Thread.interrupted(); - } - - @Test - public void verifyInterruptionOfWorkerIsSwallowed() { - asyncAppenderBase.addAppender(delayingListAppender); - asyncAppenderBase.start(); - asyncAppenderBase.stop(); - assertFalse(asyncAppenderBase.worker.isInterrupted()); - } - - - private void verify(ListAppender la, int expectedSize) { - assertFalse(la.isStarted()); - assertEquals(expectedSize, la.list.size()); - statusChecker.assertIsErrorFree(); - statusChecker - .assertContainsMatch("Worker thread will flush remaining events before exiting."); - } - - static class LossyAsyncAppender extends AsyncAppenderBase { - @Override - protected boolean isDiscardable(Integer i) { - return (i % 3 == 0); - } - } + Context context = new ContextBase(); + AsyncAppenderBase asyncAppenderBase = new AsyncAppenderBase(); + LossyAsyncAppender lossyAsyncAppender = new LossyAsyncAppender(); + DelayingListAppender delayingListAppender = new DelayingListAppender(); + ListAppender listAppender = new ListAppender(); + OnConsoleStatusListener onConsoleStatusListener = new OnConsoleStatusListener(); + StatusChecker statusChecker = new StatusChecker(context); + + @Before + public void setUp() { + onConsoleStatusListener.setContext(context); + context.getStatusManager().add(onConsoleStatusListener); + onConsoleStatusListener.start(); + + asyncAppenderBase.setContext(context); + lossyAsyncAppender.setContext(context); + + listAppender.setContext(context); + listAppender.setName("list"); + listAppender.start(); + + delayingListAppender.setContext(context); + delayingListAppender.setName("list"); + delayingListAppender.start(); + } + + @Test(timeout = 2000) + public void smoke() { + asyncAppenderBase.addAppender(listAppender); + asyncAppenderBase.start(); + asyncAppenderBase.doAppend(0); + asyncAppenderBase.stop(); + verify(listAppender, 1); + } + + @Test + public void exceptionsShouldNotCauseHalting() throws InterruptedException { + NPEAppender npeAppender = new NPEAppender(); + npeAppender.setName("bad"); + npeAppender.setContext(context); + npeAppender.start(); + + asyncAppenderBase.addAppender(npeAppender); + asyncAppenderBase.start(); + assertTrue(asyncAppenderBase.isStarted()); + for (int i = 0; i < 10; i++) + asyncAppenderBase.append(i); + + asyncAppenderBase.stop(); + assertFalse(asyncAppenderBase.isStarted()); + assertEquals(AppenderBase.ALLOWED_REPEATS, statusChecker.matchCount("Appender \\[bad\\] failed to append.")); + } + + @Test(timeout = 2000) + public void emptyQueueShouldBeStoppable() { + asyncAppenderBase.addAppender(listAppender); + asyncAppenderBase.start(); + asyncAppenderBase.stop(); + verify(listAppender, 0); + } + + @Test(timeout = 2000) + public void workerShouldStopEvenIfInterruptExceptionConsumedWithinSubappender() { + delayingListAppender.delay = 100; + asyncAppenderBase.addAppender(delayingListAppender); + asyncAppenderBase.start(); + asyncAppenderBase.doAppend(0); + asyncAppenderBase.stop(); + verify(delayingListAppender, 1); + assertTrue(delayingListAppender.interrupted); + } + + @Test(timeout = 2000) + public void noEventLoss() { + int bufferSize = 10; + int loopLen = bufferSize * 2; + asyncAppenderBase.addAppender(delayingListAppender); + asyncAppenderBase.setQueueSize(bufferSize); + asyncAppenderBase.start(); + for (int i = 0; i < loopLen; i++) { + asyncAppenderBase.doAppend(i); + } + asyncAppenderBase.stop(); + verify(delayingListAppender, loopLen); + } + + @Test(timeout = 2000) + public void eventLossIfNeverBlock() { + int bufferSize = 10; + int loopLen = bufferSize * 200; + delayingListAppender.setDelay(5); // (loopLen*delay) much bigger than test timeout + asyncAppenderBase.addAppender(delayingListAppender); + asyncAppenderBase.setQueueSize(bufferSize); + asyncAppenderBase.setNeverBlock(true); + asyncAppenderBase.start(); + for (int i = 0; i < loopLen; i++) { + asyncAppenderBase.doAppend(i); + } + asyncAppenderBase.stop(); + // ListAppender size isn't a reliable test here, so just make sure we didn't + // have any errors, and that we could complete the test in time. + statusChecker.assertIsErrorFree(); + } + + @Test(timeout = 2000) + public void lossyAppenderShouldOnlyLooseCertainEvents() { + int bufferSize = 5; + int loopLen = bufferSize * 2; + lossyAsyncAppender.addAppender(delayingListAppender); + lossyAsyncAppender.setQueueSize(bufferSize); + lossyAsyncAppender.setDiscardingThreshold(1); + lossyAsyncAppender.start(); + for (int i = 0; i < loopLen; i++) { + lossyAsyncAppender.doAppend(i); + } + lossyAsyncAppender.stop(); + verify(delayingListAppender, loopLen - 2); + } + + @Test(timeout = 2000) + public void lossyAppenderShouldBeNonLossyIfDiscardingThresholdIsZero() { + int bufferSize = 5; + int loopLen = bufferSize * 2; + lossyAsyncAppender.addAppender(delayingListAppender); + lossyAsyncAppender.setQueueSize(bufferSize); + lossyAsyncAppender.setDiscardingThreshold(0); + lossyAsyncAppender.start(); + for (int i = 0; i < loopLen; i++) { + lossyAsyncAppender.doAppend(i); + } + lossyAsyncAppender.stop(); + verify(delayingListAppender, loopLen); + } + + @Test + public void invalidQueueCapacityShouldResultInNonStartedAppender() { + asyncAppenderBase.addAppender(new NOPAppender()); + asyncAppenderBase.setQueueSize(0); + assertEquals(0, asyncAppenderBase.getQueueSize()); + asyncAppenderBase.start(); + assertFalse(asyncAppenderBase.isStarted()); + statusChecker.assertContainsMatch("Invalid queue size"); + } + + @SuppressWarnings("deprecation") + @Test + public void workerThreadFlushesOnStop() { + int loopLen = 5; + int maxRuntime = (loopLen + 1) * Math.max(1000, delayingListAppender.delay); + ListAppender la = delayingListAppender; + asyncAppenderBase.addAppender(la); + asyncAppenderBase.setDiscardingThreshold(0); + asyncAppenderBase.setMaxFlushTime(maxRuntime); + asyncAppenderBase.start(); + asyncAppenderBase.worker.suspend(); + + for (int i = 0; i < loopLen; i++) { + asyncAppenderBase.doAppend(i); + } + assertEquals(loopLen, asyncAppenderBase.getNumberOfElementsInQueue()); + assertEquals(0, la.list.size()); + + asyncAppenderBase.worker.resume(); + asyncAppenderBase.stop(); + + assertEquals(0, asyncAppenderBase.getNumberOfElementsInQueue()); + verify(la, loopLen); + } + + @SuppressWarnings("deprecation") + @Test + public void stopExitsWhenMaxRuntimeReached() throws InterruptedException { + int maxRuntime = 1; // runtime of 0 means wait forever, so use 1 ms + // instead + int loopLen = 10; + ListAppender la = delayingListAppender; + asyncAppenderBase.addAppender(la); + asyncAppenderBase.setMaxFlushTime(maxRuntime); + asyncAppenderBase.start(); + + for (int i = 0; i < loopLen; i++) { + asyncAppenderBase.doAppend(i); + } + + asyncAppenderBase.stop(); + + // suspend the thread so that we can make the following assertions + // without race conditions + asyncAppenderBase.worker.suspend(); + + // confirms that stop exited when runtime reached + statusChecker.assertContainsMatch("Max queue flush timeout \\(" + maxRuntime + " ms\\) exceeded."); + + // confirms that the number of events posted are the number of events + // removed from the queue + assertEquals(la.list.size(), loopLen - asyncAppenderBase.getNumberOfElementsInQueue()); + + // resume the thread to let it finish processing + asyncAppenderBase.worker.resume(); + + asyncAppenderBase.worker.join(); + + // confirms that all entries do end up being flushed if we wait long + // enough + verify(la, loopLen); + } + + // Interruption of current thread when in doAppend method should not be + // consumed + // by async appender. See also http://jira.qos.ch/browse/LOGBACK-910 + @Test + public void verifyInterruptionIsNotSwallowed() { + asyncAppenderBase.addAppender(delayingListAppender); + asyncAppenderBase.start(); + Thread.currentThread().interrupt(); + asyncAppenderBase.doAppend(new Integer(0)); + assertTrue(Thread.currentThread().isInterrupted()); + // clear flag for next test + Thread.interrupted(); + } + + @Test + public void verifyInterruptionOfWorkerIsSwallowed() { + asyncAppenderBase.addAppender(delayingListAppender); + asyncAppenderBase.start(); + asyncAppenderBase.stop(); + assertFalse(asyncAppenderBase.worker.isInterrupted()); + } + + private void verify(ListAppender la, int expectedSize) { + assertFalse(la.isStarted()); + assertEquals(expectedSize, la.list.size()); + statusChecker.assertIsErrorFree(); + statusChecker.assertContainsMatch("Worker thread will flush remaining events before exiting."); + } + + static class LossyAsyncAppender extends AsyncAppenderBase { + @Override + protected boolean isDiscardable(Integer i) { + return (i % 3 == 0); + } + } } diff --git a/logback-examples/pom.xml b/logback-examples/pom.xml index 8c86e7e6f..15ac31948 100755 --- a/logback-examples/pom.xml +++ b/logback-examples/pom.xml @@ -7,7 +7,7 @@ ch.qos.logback logback-parent - 1.1.4 + 1.1.5-SNAPSHOT logback-examples diff --git a/logback-site/pom.xml b/logback-site/pom.xml index 1d5b8dc1e..de54b1f2f 100644 --- a/logback-site/pom.xml +++ b/logback-site/pom.xml @@ -7,7 +7,7 @@ ch.qos.logback logback-parent - 1.1.4 + 1.1.5-SNAPSHOT logback-site diff --git a/logback-site/src/site/pages/news.html b/logback-site/src/site/pages/news.html index c449554ef..380ae664f 100755 --- a/logback-site/src/site/pages/news.html +++ b/logback-site/src/site/pages/news.html @@ -29,6 +29,17 @@
+

2016, Release of version 1.1.5

+ + +

AsyncAppender is now configurable to never block. This feature + was requested by Jeff Wartes in LOGBACK-898 with + Jeff Wartes and Gareth Davis providing the relevant patch. +

+ +
+

February 11th, 2016, Release of version 1.1.4

diff --git a/pom.xml b/pom.xml index 872f1845f..fa1cf49e6 100755 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ch.qos.logback logback-parent - 1.1.4 + 1.1.5-SNAPSHOT pom Logback-Parent logback project pom.xml file diff --git a/release.sh b/release.sh index 7685ce783..c6a9c2a2c 100755 --- a/release.sh +++ b/release.sh @@ -1,6 +1,6 @@ # memory aid -mvn versions:set -DnewVersion=${VERSION_NUMBER} -DgenerateBackupPoms=false +mvn versions:set -DgenerateBackupPoms=false -DnewVersion=${VERSION_NUMBER} mvn clean mvn install @@ -14,7 +14,7 @@ mvn deploy -P javadocjar,sign-artifacts #uncomment diffie-hellman support in /etc/ssh/sshd_config mvn site:deploy -N -git tag -a v_${VERSION_NUMBER} +git tag -m "tagging" -a v_${VERSION_NUMBER} git push --tags release version and add next version on jira -- GitLab