Merge pull request #27701 from akka/wip-occurence0-patriknw
wait for async excess events when occurrences 0
This commit is contained in:
commit
ae32f1431a
4 changed files with 69 additions and 5 deletions
|
|
@ -75,17 +75,29 @@ import org.slf4j.event.Level
|
||||||
todo == Int.MaxValue || todo == 0
|
todo == Int.MaxValue || todo == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def awaitNoExcess(max: Duration): Boolean = {
|
||||||
|
if (todo == 0)
|
||||||
|
!TestKit.awaitCond(todo < 0, max, noThrow = true)
|
||||||
|
else
|
||||||
|
todo > 0
|
||||||
|
}
|
||||||
|
|
||||||
override def intercept[T](code: => T)(implicit system: ActorSystem[_]): T = {
|
override def intercept[T](code: => T)(implicit system: ActorSystem[_]): T = {
|
||||||
val effectiveLoggerName = loggerName.getOrElse("")
|
val effectiveLoggerName = loggerName.getOrElse("")
|
||||||
checkLogback(system)
|
checkLogback(system)
|
||||||
TestAppender.setupTestAppender(effectiveLoggerName)
|
TestAppender.setupTestAppender(effectiveLoggerName)
|
||||||
TestAppender.addFilter(effectiveLoggerName, this)
|
TestAppender.addFilter(effectiveLoggerName, this)
|
||||||
val leeway = TestKitSettings(system).FilterLeeway
|
val settings = TestKitSettings(system)
|
||||||
try {
|
try {
|
||||||
val result = code
|
val result = code
|
||||||
if (!awaitDone(leeway))
|
|
||||||
|
// wait some more when occurrences=0 to find asynchronous exceess messages
|
||||||
|
if (occurrences == 0)
|
||||||
|
awaitNoExcess(settings.ExpectNoMessageDefaultTimeout)
|
||||||
|
|
||||||
|
if (!awaitDone(settings.FilterLeeway))
|
||||||
if (todo > 0)
|
if (todo > 0)
|
||||||
throw new AssertionError(s"Timeout ($leeway) waiting for $todo messages on $this.")
|
throw new AssertionError(s"Timeout (${settings.FilterLeeway}) waiting for $todo messages on $this.")
|
||||||
else
|
else
|
||||||
throw new AssertionError(s"Received ${-todo} excess messages on $this.")
|
throw new AssertionError(s"Received ${-todo} excess messages on $this.")
|
||||||
result
|
result
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,13 @@ import org.slf4j.event.Level
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of events the filter is supposed to match. By default 1.
|
* Number of events the filter is supposed to match. By default 1.
|
||||||
|
*
|
||||||
|
* When occurrences > 0 it will not look for excess messages that are logged asynchronously
|
||||||
|
* outside (after) the `intercept` thunk and it has already found expected number.
|
||||||
|
*
|
||||||
|
* When occurrences is 0 it will look for unexpected matching events, and then it will
|
||||||
|
* also look for excess messages during the configured `akka.actor.testkit.typed.expect-no-message-default`
|
||||||
|
* duration.
|
||||||
*/
|
*/
|
||||||
def withOccurrences(newOccurrences: Int): LoggingEventFilter
|
def withOccurrences(newOccurrences: Int): LoggingEventFilter
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,13 @@ import org.slf4j.event.Level
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of events the filter is supposed to match. By default 1.
|
* Number of events the filter is supposed to match. By default 1.
|
||||||
|
*
|
||||||
|
* When occurrences > 0 it will not look for excess messages that are logged asynchronously
|
||||||
|
* outside (after) the `intercept` thunk and it has already found expected number.
|
||||||
|
*
|
||||||
|
* When occurrences is 0 it will look for unexpected matching events, and then it will
|
||||||
|
* also look for excess messages during the configured `akka.actor.testkit.typed.expect-no-message-default`
|
||||||
|
* duration.
|
||||||
*/
|
*/
|
||||||
def withOccurrences(newOccurrences: Int): LoggingEventFilter
|
def withOccurrences(newOccurrences: Int): LoggingEventFilter
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,20 @@ package akka.actor.testkit.typed.scaladsl
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
|
import scala.concurrent.Future
|
||||||
|
|
||||||
import akka.actor.testkit.typed.TestException
|
import akka.actor.testkit.typed.TestException
|
||||||
import org.scalatest.WordSpecLike
|
import org.scalatest.WordSpecLike
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
class TestAppenderSpec extends ScalaTestWithActorTestKit with WordSpecLike with LogCapturing {
|
class TestAppenderSpec
|
||||||
|
extends ScalaTestWithActorTestKit(
|
||||||
|
"""
|
||||||
|
# increase to avoid spurious failures in "find unexpected async events withOccurrences(0)"
|
||||||
|
akka.actor.testkit.typed.expect-no-message-default = 1000 ms
|
||||||
|
""")
|
||||||
|
with WordSpecLike
|
||||||
|
with LogCapturing {
|
||||||
|
|
||||||
class AnotherLoggerClass
|
class AnotherLoggerClass
|
||||||
|
|
||||||
|
|
@ -39,6 +48,21 @@ class TestAppenderSpec extends ScalaTestWithActorTestKit with WordSpecLike with
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"find excess messages" in {
|
||||||
|
intercept[AssertionError] {
|
||||||
|
LoggingEventFilter.warn("a warning").withOccurrences(2).intercept {
|
||||||
|
log.error("an error")
|
||||||
|
log.warn("a warning")
|
||||||
|
log.warn("a warning")
|
||||||
|
log.error("an error")
|
||||||
|
// since this logging is synchronous it will notice 3 occurrences but expecting 2,
|
||||||
|
// but note that it will not look for asynchronous excess messages when occurrences > 0 and it has
|
||||||
|
// already found expected number
|
||||||
|
log.warn("a warning") // 3rd
|
||||||
|
}
|
||||||
|
}.getMessage should include("Received 1 excess messages")
|
||||||
|
}
|
||||||
|
|
||||||
"only filter events for given logger name" in {
|
"only filter events for given logger name" in {
|
||||||
val count = new AtomicInteger
|
val count = new AtomicInteger
|
||||||
LoggingEventFilter
|
LoggingEventFilter
|
||||||
|
|
@ -57,7 +81,7 @@ class TestAppenderSpec extends ScalaTestWithActorTestKit with WordSpecLike with
|
||||||
count.get should ===(2)
|
count.get should ===(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
"find unexpected events withOccurences(0)" in {
|
"find unexpected events withOccurrences(0)" in {
|
||||||
LoggingEventFilter.warn("a warning").withOccurrences(0).intercept {
|
LoggingEventFilter.warn("a warning").withOccurrences(0).intercept {
|
||||||
log.error("an error")
|
log.error("an error")
|
||||||
log.warn("another warning")
|
log.warn("another warning")
|
||||||
|
|
@ -77,6 +101,20 @@ class TestAppenderSpec extends ScalaTestWithActorTestKit with WordSpecLike with
|
||||||
log.warn("a warning")
|
log.warn("a warning")
|
||||||
}
|
}
|
||||||
}.getMessage should include("Received 2 excess messages")
|
}.getMessage should include("Received 2 excess messages")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
"find unexpected async events withOccurrences(0)" in {
|
||||||
|
// expect-no-message-default = 1000 ms
|
||||||
|
intercept[AssertionError] {
|
||||||
|
LoggingEventFilter.warn("a warning").withOccurrences(0).intercept {
|
||||||
|
Future {
|
||||||
|
Thread.sleep(20)
|
||||||
|
log.warn("a warning")
|
||||||
|
log.warn("a warning")
|
||||||
|
}(system.executionContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue