2011-12-08 5 views
0

J'ai quelques échecs de test sporadiques et je n'arrive pas à comprendre pourquoi. J'ai un tas d'acteurs qui pour le travail que je veux tester. Au début du test je passe dans une référence d'acteur que je reçois d'une TestProbe(). Plus tard, le groupe d'acteurs fait un travail et envoie le résultat à la référence de l'acteur de la sonde de test donnée. Ensuite, je vérifie le résultat avec TestProbe():L'envoi d'un message à TestProbe() échoue parfois avec ActorInitializationException

class MyCaseSpec extends Spec with ShouldMatchers{ 
    describe("The Thingy"){ 
     it("should work"){ 
      val eventListener = TestProbe() 

      val myStuffUnderTest = Actor.actorOf(new ComplexActor(eventListener.ref)).start(); 
      myStuffUnderTest ! "Start" 

      val eventMessage = eventListener.receiveOne(10.seconds).asInstanceOf[SomeEventMessage] 
      eventMessage.data should be ("Result") 
     } 

    } 
} 

De temps à autre, le test échoue. Et quand je regarde à travers la trace de la pile, je vois que j'ai une 'ActorInitializationException' lors de l'envoi d'un message à l'acteur de la sonde de test. Cependant, à aucun moment j'arrête l'acteur TestProbe.

est ici l'exception:

[akka:event-driven:dispatcher:global-11] [LocalActorRef] Actor has not been started, you need to invoke 'actor.start()' before using it 
akka.actor.ActorInitializationException: Actor has not been started, you need to invoke 'actor.start()' before using it 
[Gamlor-Laptop_c15fdca0-219e-11e1-9579-001b7744104e] 
at akka.actor.ScalaActorRef$class.$bang(ActorRef.scala:1399) 
at akka.actor.LocalActorRef.$bang(ActorRef.scala:605) 
at akka.mobile.client.RemoteMessaging$RemoteMessagingSupervision$$anonfun$receive$1.apply(RemoteMessaging.scala:125) 
at akka.mobile.client.RemoteMessaging$RemoteMessagingSupervision$$anonfun$receive$1.apply(RemoteMessaging.scala:121) 
at akka.actor.Actor$class.apply(Actor.scala:545) 
.... 

Je me demande si je me manque quelque chose d'évident ou suis-je faire une erreur subtile? Ou peut-être que quelque chose ne va vraiment pas dans mon code et que je ne peux pas le voir?

Je suis sur Akka 1.2.

Mise à jour pour Vitores-Comment. A la ligne 125, j'envoie un message à un acteur avec le! -operator. Maintenant dans le test-setup c'est la référence d'acteur TestProbe. Et je ne peux pas comprendre pourquoi parfois l'acteur TestProbe semble être arrêté.

protected def receive = { 
     case msg: MaximumNumberOfRestartsWithinTimeRangeReached => { 
     val lastException = msg.getLastExceptionCausingRestart 
     faultHandling ! ConnectionError(lastException, messages.toList, self) // < Line 125. The faultHandling is the TestProbe actor 
     become({ 
      // Change to failure-state behavior 
      } 
    // Snip 

De toute façon, j'essaie d'isoler le problème pour le moment. Merci pour tout indice/idée.

+0

Pourquoi ne vous inclus la section la plus intéressante? atkka.mobile.client.RemoteMessaging $ RemoteMessagingSupervision $$ anonfun $ receive $ 1.apply (RemoteMessaging.scala: 125) –

+0

À 125 j'envoie un message à mon acteur TestProbe(): Je n'arrive pas à comprendre pourquoi la sonde de test l'acteur ne court pas parfois et je reçois l'exception. – Gamlor

Répondre

1

Ok, presque certainement trouvé la question =). Les TestProbes ont un timeout: Quand rien ne se passe après 5 secondes, ils s'arrêtent.

Malheureusement, le test ne dure qu'un peu plus de 5 secondes: pendant ce temps, la sonde de test peut s'arrêter d'elle-même, ce qui fait échouer le test.

Fixing il est facile, augmenter le délai d'attente sur le TESTPOINTE DE TOUCHE:

val errorHandler = ignoreConnectionMsgProbe() 
    errorHandler.setTestActorTimeout(20.seconds) 
+0

Oui, c'est exactement ce qui se passe et la façon de le gérer (vous pouvez aussi le désactiver complètement en utilisant 'Duration.Inf'). J'ai aussi trouvé que c'était déroutant (cela m'a coûté quelques heures pour blâmer la cause réelle il y a quelques semaines), et j'aurais dû le savoir. Quoi qu'il en soit, le problème est passé en 2.0, où tous les acteurs sont arrêtés de façon ordonnée après le test sans aucun délai (si vous arrêtez le ActorSystem, c'est-à-dire). –

1

Vous ne démarrez pas votre acteur ici. Je ne sais pas pourquoi votre test fonctionne de temps en temps. Le code ci-dessus doit avoir la ligne suivante modifiée avec un .start()

val myStuffUnderTest = Actor.actorOf(new ComplexActor(eventListener.ref)).start(); 
+0

Oh. C'est une erreur dans l'exemple ci-dessus. Dans le test actuel, il est démarré. Correction de l'exemple. – Gamlor

Questions connexes