Fix BehaviorTestKit.signal false alarm in thread check #29779
This commit is contained in:
parent
dab8f3b642
commit
3ba5e89433
2 changed files with 87 additions and 67 deletions
|
|
@ -145,9 +145,13 @@ private[akka] final class BehaviorTestKitImpl[T](_path: ActorPath, _initialBehav
|
|||
|
||||
override def signal(signal: Signal): Unit = {
|
||||
try {
|
||||
context.setCurrentActorThread()
|
||||
currentUncanonical = Behavior.interpretSignal(current, context, signal)
|
||||
current = Behavior.canonicalize(currentUncanonical, current, context)
|
||||
} catch handleException
|
||||
finally {
|
||||
context.clearCurrentActorThread()
|
||||
}
|
||||
}
|
||||
|
||||
override def hasEffects(): Boolean = !context.effectQueue.isEmpty
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import akka.actor.testkit.typed.{ CapturedLogEvent, Effect }
|
|||
import akka.actor.testkit.typed.Effect._
|
||||
import akka.actor.testkit.typed.scaladsl.BehaviorTestKitSpec.{ Child, Parent }
|
||||
import akka.actor.testkit.typed.scaladsl.BehaviorTestKitSpec.Parent._
|
||||
import akka.actor.typed.{ ActorRef, Behavior, Props }
|
||||
import akka.actor.typed.{ ActorRef, Behavior, Props, Terminated }
|
||||
import akka.actor.typed.receptionist.{ Receptionist, ServiceKey }
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
|
||||
|
|
@ -43,75 +43,81 @@ object BehaviorTestKitSpec {
|
|||
case class Log(what: String) extends Command
|
||||
case class RegisterWithReceptionist(name: String) extends Command
|
||||
|
||||
val init: Behavior[Command] = Behaviors.receive[Command] { (context, message) =>
|
||||
message match {
|
||||
case SpawnChild =>
|
||||
context.spawn(Child.initial, "child")
|
||||
Behaviors.same
|
||||
case SpawnChildren(numberOfChildren) if numberOfChildren > 0 =>
|
||||
0.until(numberOfChildren).foreach { i =>
|
||||
context.spawn(Child.initial, s"child$i")
|
||||
}
|
||||
Behaviors.same
|
||||
case SpawnChildrenWithProps(numberOfChildren, props) if numberOfChildren > 0 =>
|
||||
0.until(numberOfChildren).foreach { i =>
|
||||
context.spawn(Child.initial, s"child$i", props)
|
||||
}
|
||||
Behaviors.same
|
||||
case SpawnAnonymous(numberOfChildren) if numberOfChildren > 0 =>
|
||||
0.until(numberOfChildren).foreach { _ =>
|
||||
context.spawnAnonymous(Child.initial)
|
||||
}
|
||||
Behaviors.same
|
||||
case SpawnAnonymousWithProps(numberOfChildren, props) if numberOfChildren > 0 =>
|
||||
0.until(numberOfChildren).foreach { _ =>
|
||||
context.spawnAnonymous(Child.initial, props)
|
||||
}
|
||||
Behaviors.same
|
||||
case StopChild(child) =>
|
||||
context.stop(child)
|
||||
Behaviors.same
|
||||
case SpawnAdapter =>
|
||||
context.spawnMessageAdapter { (r: Reproduce) =>
|
||||
SpawnAnonymous(r.times)
|
||||
}
|
||||
Behaviors.same
|
||||
case SpawnAdapterWithName(name) =>
|
||||
context.spawnMessageAdapter({ (r: Reproduce) =>
|
||||
SpawnAnonymous(r.times)
|
||||
}, name)
|
||||
Behaviors.same
|
||||
case SpawnAndWatchUnwatch(name) =>
|
||||
val c = context.spawn(Child.initial, name)
|
||||
context.watch(c)
|
||||
context.unwatch(c)
|
||||
Behaviors.same
|
||||
case m @ SpawnAndWatchWith(name) =>
|
||||
val c = context.spawn(Child.initial, name)
|
||||
context.watchWith(c, m)
|
||||
Behaviors.same
|
||||
case SpawnSession(replyTo, sessionHandler) =>
|
||||
val session = context.spawnAnonymous[String](Behaviors.receiveMessage { message =>
|
||||
sessionHandler ! message
|
||||
val init: Behavior[Command] = Behaviors
|
||||
.receive[Command] { (context, message) =>
|
||||
message match {
|
||||
case SpawnChild =>
|
||||
context.spawn(Child.initial, "child")
|
||||
Behaviors.same
|
||||
})
|
||||
replyTo ! session
|
||||
Behaviors.same
|
||||
case KillSession(session, replyTo) =>
|
||||
context.stop(session)
|
||||
replyTo ! Done
|
||||
Behaviors.same
|
||||
case CreateMessageAdapter(messageClass, f) =>
|
||||
context.messageAdapter(f)(ClassTag(messageClass))
|
||||
Behaviors.same
|
||||
case Log(what) =>
|
||||
context.log.info(what)
|
||||
Behaviors.same
|
||||
case RegisterWithReceptionist(name: String) =>
|
||||
context.system.receptionist ! Receptionist.Register(ServiceKey[Command](name), context.self)
|
||||
case SpawnChildren(numberOfChildren) if numberOfChildren > 0 =>
|
||||
0.until(numberOfChildren).foreach { i =>
|
||||
context.spawn(Child.initial, s"child$i")
|
||||
}
|
||||
Behaviors.same
|
||||
case SpawnChildrenWithProps(numberOfChildren, props) if numberOfChildren > 0 =>
|
||||
0.until(numberOfChildren).foreach { i =>
|
||||
context.spawn(Child.initial, s"child$i", props)
|
||||
}
|
||||
Behaviors.same
|
||||
case SpawnAnonymous(numberOfChildren) if numberOfChildren > 0 =>
|
||||
0.until(numberOfChildren).foreach { _ =>
|
||||
context.spawnAnonymous(Child.initial)
|
||||
}
|
||||
Behaviors.same
|
||||
case SpawnAnonymousWithProps(numberOfChildren, props) if numberOfChildren > 0 =>
|
||||
0.until(numberOfChildren).foreach { _ =>
|
||||
context.spawnAnonymous(Child.initial, props)
|
||||
}
|
||||
Behaviors.same
|
||||
case StopChild(child) =>
|
||||
context.stop(child)
|
||||
Behaviors.same
|
||||
case SpawnAdapter =>
|
||||
context.spawnMessageAdapter { (r: Reproduce) =>
|
||||
SpawnAnonymous(r.times)
|
||||
}
|
||||
Behaviors.same
|
||||
case SpawnAdapterWithName(name) =>
|
||||
context.spawnMessageAdapter({ (r: Reproduce) =>
|
||||
SpawnAnonymous(r.times)
|
||||
}, name)
|
||||
Behaviors.same
|
||||
case SpawnAndWatchUnwatch(name) =>
|
||||
val c = context.spawn(Child.initial, name)
|
||||
context.watch(c)
|
||||
context.unwatch(c)
|
||||
Behaviors.same
|
||||
case m @ SpawnAndWatchWith(name) =>
|
||||
val c = context.spawn(Child.initial, name)
|
||||
context.watchWith(c, m)
|
||||
Behaviors.same
|
||||
case SpawnSession(replyTo, sessionHandler) =>
|
||||
val session = context.spawnAnonymous[String](Behaviors.receiveMessage { message =>
|
||||
sessionHandler ! message
|
||||
Behaviors.same
|
||||
})
|
||||
replyTo ! session
|
||||
Behaviors.same
|
||||
case KillSession(session, replyTo) =>
|
||||
context.stop(session)
|
||||
replyTo ! Done
|
||||
Behaviors.same
|
||||
case CreateMessageAdapter(messageClass, f) =>
|
||||
context.messageAdapter(f)(ClassTag(messageClass))
|
||||
Behaviors.same
|
||||
case Log(what) =>
|
||||
context.log.info(what)
|
||||
Behaviors.same
|
||||
case RegisterWithReceptionist(name: String) =>
|
||||
context.system.receptionist ! Receptionist.Register(ServiceKey[Command](name), context.self)
|
||||
Behaviors.same
|
||||
}
|
||||
}
|
||||
.receiveSignal {
|
||||
case (context, Terminated(_)) =>
|
||||
context.log.debug("Terminated")
|
||||
Behaviors.same
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Child {
|
||||
|
|
@ -277,6 +283,16 @@ class BehaviorTestKitSpec extends AnyWordSpec with Matchers with LogCapturing {
|
|||
}
|
||||
}
|
||||
|
||||
"BehaviorTestKit's signal" must {
|
||||
"not throw thread validation errors when context log is accessed" in {
|
||||
val other = TestInbox[String]()
|
||||
val testkit = BehaviorTestKit[Parent.Command](Parent.init)
|
||||
noException should be thrownBy {
|
||||
testkit.signal(Terminated(other.ref))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"BehaviorTestKit’s watch" must {
|
||||
"record effects for watching and unwatching" in {
|
||||
val testkit = BehaviorTestKit(Parent.init)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue