我的Actor
样子
import akka.actor.Status.Failure
import akka.actor.{Actor, ActorLogging, Props}
import akka.event.LoggingReceive
object Runner {
def props(race: Race) = Props(classOf[Runner], race)
}
class Runner(race: Race) extends Actor with ActorLogging {
override def receive: Receive = LoggingReceive {
case Start =>
sender ! "OK"
log.debug("running...")
Thread.sleep(10)
throw new RuntimeException("MarathonRunner is tired")
case Failure(throwable) => throw throwable
case Stop =>
log.debug("stopping runner")
context.stop(self)
}
}
我的测试看起来像
import akka.actor.{Terminated, ActorSystem}
import akka.testkit.{ImplicitSender, TestActorRef, TestKit}
import org.scalatest._
import scala.concurrent.duration._
class RunnerSpec extends TestKit(ActorSystem("testSystem"))
with WordSpecLike
with MustMatchers
with ImplicitSender {
"must fail with exception" in {
val runnerRef = TestActorRef(new Runner(new Marathon), "testRunnerException")
runnerRef ! Start
expectMsg("OK")
watch(runnerRef)
expectMsg(20 millis, Terminated)
}
}
- 但是,我在日志中看到它失败了,因为一旦
RuntimeException
发生,Actor
就会重新启动。 - 如您所见, my
Actor
没有定义 anysupervisorStrategy
,其父级为
class Coach() extends Actor with ActorLogging { val runner = context.actorOf(Runner.props(new Marathon).withDispatcher("my-pinned-dispatcher"), "runner") override def supervisorStrategy: SupervisorStrategy = OneForOneStrategy(maxNrOfRetries = 2, withinTimeRange = 5 seconds) { case _: RuntimeException => sender ! Start Restart }
但我不是supervisor
在这里测试,事实上主管甚至不是测试的一部分。
这里出了什么问题?
日志
Testing started at 11:48 AM ...
[DEBUG] [06/02/2015 11:48:08.068] [ScalaTest-run] [EventStream(akka://testSystem)] logger log1-Logging$DefaultLogger started
[DEBUG] [06/02/2015 11:48:08.069] [ScalaTest-run] [EventStream(akka://testSystem)] Default Loggers started
[DEBUG] [06/02/2015 11:48:08.072] [testSystem-akka.actor.default-dispatcher-4] [akka://testSystem/system] now supervising Actor[akka://testSystem/system/deadLetterListener#58458639]
[DEBUG] [06/02/2015 11:48:08.075] [testSystem-akka.actor.default-dispatcher-4] [akka://testSystem/system/deadLetterListener] started (akka.event.DeadLetterListener@7b2fe415)
[DEBUG] [06/02/2015 11:48:08.089] [testSystem-akka.actor.default-dispatcher-5] [akka://testSystem/system/testActor1] started (akka.testkit.TestActor@6242009b)
[DEBUG] [06/02/2015 11:48:08.090] [testSystem-akka.actor.default-dispatcher-5] [akka://testSystem/system] now supervising Actor[akka://testSystem/system/testActor1#1776291392][DEBUG] [06/02/2015 11:48:08.249] [testSystem-akka.actor.default-dispatcher-4] [akka://testSystem/user] now supervising TestActor[akka://testSystem/user/testRunnerException]
[DEBUG] [06/02/2015 11:48:08.250] [ScalaTest-run-running-RunnerSpec] [akka://testSystem/user/testRunnerException] started (com.learner.ahka.ruforever.Runner@afdd280)
[DEBUG] [06/02/2015 11:48:08.251] [ScalaTest-run-running-RunnerSpec] [akka://testSystem/user/testRunnerException] received handled message Start
[DEBUG] [06/02/2015 11:48:08.254] [ScalaTest-run-running-RunnerSpec] [akka://testSystem/user/testRunnerException] running...
[DEBUG] [06/02/2015 11:48:08.267] [ScalaTest-run-running-RunnerSpec] [akka://testSystem/user/testRunnerException] now watched by Actor[akka://testSystem/system/testActor1#1776291392]
[ERROR] [06/02/2015 11:48:08.269] [testSystem-akka.actor.default-dispatcher-5] [akka://testSystem/user/testRunnerException] MarathonRunner is tired
java.lang.RuntimeException: MarathonRunner is tired
at com.learner.ahka.ruforever.Runner$$anonfun$receive$1.applyOrElse(Runner.scala:18)
at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36)
at akka.event.LoggingReceive.apply(LoggingReceive.scala:62)
at akka.event.LoggingReceive.apply(LoggingReceive.scala:50)
at scala.PartialFunction$class.applyOrElse(PartialFunction.scala:123)
at akka.event.LoggingReceive.applyOrElse(LoggingReceive.scala:50)
at akka.actor.Actor$class.aroundReceive(Actor.scala:467)
at com.learner.ahka.ruforever.Runner.aroundReceive(Runner.scala:11)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)
at akka.actor.ActorCell.invoke(ActorCell.scala:487)
at akka.testkit.CallingThreadDispatcher.process$1(CallingThreadDispatcher.scala:251)
at akka.testkit.CallingThreadDispatcher.runQueue(CallingThreadDispatcher.scala:284)
at akka.testkit.CallingThreadDispatcher.dispatch(CallingThreadDispatcher.scala:208)
at akka.actor.dungeon.Dispatch$class.sendMessage(Dispatch.scala:123)
at akka.actor.ActorCell.sendMessage(ActorCell.scala:369)
at akka.actor.Cell$class.sendMessage(ActorCell.scala:290)
at akka.actor.ActorCell.sendMessage(ActorCell.scala:369)
at akka.actor.LocalActorRef.$bang(ActorRef.scala:384)
at com.learner.ahka.ruforever.RunnerSpec$$anonfun$1.apply$mcV$sp(RunnerSpec.scala:15)
at com.learner.ahka.ruforever.RunnerSpec$$anonfun$1.apply(RunnerSpec.scala:13)
at com.learner.ahka.ruforever.RunnerSpec$$anonfun$1.apply(RunnerSpec.scala:13)
at org.scalatest.Transformer$$anonfun$apply$1.apply$mcV$sp(Transformer.scala:22)
at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.WordSpecLike$$anon$1.apply(WordSpecLike.scala:953)
at org.scalatest.Suite$class.withFixture(Suite.scala:1122)
at com.learner.ahka.ruforever.RunnerSpec.withFixture(RunnerSpec.scala:9)
at org.scalatest.WordSpecLike$class.invokeWithFixture$1(WordSpecLike.scala:950)
at org.scalatest.WordSpecLike$$anonfun$runTest$1.apply(WordSpecLike.scala:962)
at org.scalatest.WordSpecLike$$anonfun$runTest$1.apply(WordSpecLike.scala:962)
at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306)
at org.scalatest.WordSpecLike$class.runTest(WordSpecLike.scala:962)
at com.learner.ahka.ruforever.RunnerSpec.runTest(RunnerSpec.scala:9)
at org.scalatest.WordSpecLike$$anonfun$runTests$1.apply(WordSpecLike.scala:1021)
at org.scalatest.WordSpecLike$$anonfun$runTests$1.apply(WordSpecLike.scala:1021)
at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:413)
at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:401)
at scala.collection.immutable.List.foreach(List.scala:381)
at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401)
at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:396)
at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:483)
at org.scalatest.WordSpecLike$class.runTests(WordSpecLike.scala:1021)
at com.learner.ahka.ruforever.RunnerSpec.runTests(RunnerSpec.scala:9)
at org.scalatest.Suite$class.run(Suite.scala:1424)
at com.learner.ahka.ruforever.RunnerSpec.org$scalatest$WordSpecLike$$super$run(RunnerSpec.scala:9)
at org.scalatest.WordSpecLike$$anonfun$run$1.apply(WordSpecLike.scala:1067)
at org.scalatest.WordSpecLike$$anonfun$run$1.apply(WordSpecLike.scala:1067)
at org.scalatest.SuperEngine.runImpl(Engine.scala:545)
at org.scalatest.WordSpecLike$class.run(WordSpecLike.scala:1067)
at com.learner.ahka.ruforever.RunnerSpec.run(RunnerSpec.scala:9)
at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:55)
at org.scalatest.tools.Runner$$anonfun$doRunRunRunDaDoRunRun$3.apply(Runner.scala:2563)
at org.scalatest.tools.Runner$$anonfun$doRunRunRunDaDoRunRun$3.apply(Runner.scala:2557)
at scala.collection.immutable.List.foreach(List.scala:381)
at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:2557)
at org.scalatest.tools.Runner$$anonfun$runOptionallyWithPassFailReporter$2.apply(Runner.scala:1044)
at org.scalatest.tools.Runner$$anonfun$runOptionallyWithPassFailReporter$2.apply(Runner.scala:1043)
at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:2722)
at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:1043)
at org.scalatest.tools.Runner$.run(Runner.scala:883)
at org.scalatest.tools.Runner.run(Runner.scala)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2(ScalaTestRunner.java:138)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
[DEBUG] [06/02/2015 11:48:08.269] [testSystem-akka.actor.default-dispatcher-5] [akka://testSystem/user/testRunnerException] restarting
[DEBUG] [06/02/2015 11:48:08.272] [testSystem-akka.actor.default-dispatcher-5] [akka://testSystem/user/testRunnerException] restarted
assertion failed: timeout (20 milliseconds) during expectMsg while waiting for Terminated
java.lang.AssertionError: assertion failed: timeout (20 milliseconds) during expectMsg while waiting for Terminated
at scala.Predef$.assert(Predef.scala:165)
at akka.testkit.TestKitBase$class.expectMsg_internal(TestKit.scala:338)
at akka.testkit.TestKitBase$class.expectMsg(TestKit.scala:324)
at akka.testkit.TestKit.expectMsg(TestKit.scala:718)
at com.learner.ahka.ruforever.RunnerSpec$$anonfun$1.apply$mcV$sp(RunnerSpec.scala:18)
at com.learner.ahka.ruforever.RunnerSpec$$anonfun$1.apply(RunnerSpec.scala:13)
at com.learner.ahka.ruforever.RunnerSpec$$anonfun$1.apply(RunnerSpec.scala:13)
at org.scalatest.Transformer$$anonfun$apply$1.apply$mcV$sp(Transformer.scala:22)
at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.WordSpecLike$$anon$1.apply(WordSpecLike.scala:953)
at org.scalatest.Suite$class.withFixture(Suite.scala:1122)
at com.learner.ahka.ruforever.RunnerSpec.withFixture(RunnerSpec.scala:9)
at org.scalatest.WordSpecLike$class.invokeWithFixture$1(WordSpecLike.scala:950)
at org.scalatest.WordSpecLike$$anonfun$runTest$1.apply(WordSpecLike.scala:962)
at org.scalatest.WordSpecLike$$anonfun$runTest$1.apply(WordSpecLike.scala:962)
at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306)
at org.scalatest.WordSpecLike$class.runTest(WordSpecLike.scala:962)
at com.learner.ahka.ruforever.RunnerSpec.runTest(RunnerSpec.scala:9)
at org.scalatest.WordSpecLike$$anonfun$runTests$1.apply(WordSpecLike.scala:1021)
at org.scalatest.WordSpecLike$$anonfun$runTests$1.apply(WordSpecLike.scala:1021)
at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:413)
at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:401)
at scala.collection.immutable.List.foreach(List.scala:381)
at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401)
at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:396)
at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:483)
at org.scalatest.WordSpecLike$class.runTests(WordSpecLike.scala:1021)
at com.learner.ahka.ruforever.RunnerSpec.runTests(RunnerSpec.scala:9)
at org.scalatest.Suite$class.run(Suite.scala:1424)
at com.learner.ahka.ruforever.RunnerSpec.org$scalatest$WordSpecLike$$super$run(RunnerSpec.scala:9)
at org.scalatest.WordSpecLike$$anonfun$run$1.apply(WordSpecLike.scala:1067)
at org.scalatest.WordSpecLike$$anonfun$run$1.apply(WordSpecLike.scala:1067)
at org.scalatest.SuperEngine.runImpl(Engine.scala:545)
at org.scalatest.WordSpecLike$class.run(WordSpecLike.scala:1067)
at com.learner.ahka.ruforever.RunnerSpec.run(RunnerSpec.scala:9)
at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:55)
at org.scalatest.tools.Runner$$anonfun$doRunRunRunDaDoRunRun$3.apply(Runner.scala:2563)
at org.scalatest.tools.Runner$$anonfun$doRunRunRunDaDoRunRun$3.apply(Runner.scala:2557)
at scala.collection.immutable.List.foreach(List.scala:381)
at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:2557)
at org.scalatest.tools.Runner$$anonfun$runOptionallyWithPassFailReporter$2.apply(Runner.scala:1044)
at org.scalatest.tools.Runner$$anonfun$runOptionallyWithPassFailReporter$2.apply(Runner.scala:1043)
at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:2722)
at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:1043)
at org.scalatest.tools.Runner$.run(Runner.scala:883)
at org.scalatest.tools.Runner.run(Runner.scala)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2(ScalaTestRunner.java:138)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)