/akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala

https://github.com/amir343/akka · Scala · 235 lines · 189 code · 26 blank · 20 comment · 4 complexity · d5a67364095b5e900ed1547b1f518e53 MD5 · raw file

  1. /**
  2. * Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
  3. */
  4. package akka.actor
  5. import language.postfixOps
  6. import akka.testkit.{ AkkaSpec, EventFilter }
  7. //#import
  8. import akka.actor.ActorDSL._
  9. //#import
  10. import akka.event.Logging.Warning
  11. import scala.concurrent.{ Await, Future }
  12. import scala.concurrent.duration._
  13. import java.util.concurrent.TimeoutException
  14. class ActorDSLSpec extends AkkaSpec {
  15. val echo = system.actorOf(Props(new Actor {
  16. def receive = {
  17. case x sender ! x
  18. }
  19. }))
  20. "An Inbox" must {
  21. "function as implicit sender" in {
  22. implicit val i = inbox()
  23. echo ! "hello"
  24. i.receive() must be("hello")
  25. }
  26. "support queueing multiple queries" in {
  27. val i = inbox()
  28. import system.dispatcher
  29. val res = Future.sequence(Seq(
  30. Future { i.receive() } recover { case x x },
  31. Future { Thread.sleep(100); i.select() { case "world" 1 } } recover { case x x },
  32. Future { Thread.sleep(200); i.select() { case "hello" 2 } } recover { case x x }))
  33. Thread.sleep(1000)
  34. res.isCompleted must be(false)
  35. i.receiver ! 42
  36. i.receiver ! "hello"
  37. i.receiver ! "world"
  38. Await.result(res, 5 second) must be(Seq(42, 1, 2))
  39. }
  40. "support selective receives" in {
  41. val i = inbox()
  42. i.receiver ! "hello"
  43. i.receiver ! "world"
  44. val result = i.select() {
  45. case "world" true
  46. }
  47. result must be(true)
  48. i.receive() must be("hello")
  49. }
  50. "have a maximum queue size" in {
  51. val i = inbox()
  52. system.eventStream.subscribe(testActor, classOf[Warning])
  53. for (_ 1 to 1000) i.receiver ! 0
  54. expectNoMsg(1 second)
  55. EventFilter.warning(start = "dropping message", occurrences = 1) intercept {
  56. i.receiver ! 42
  57. }
  58. expectMsgType[Warning]
  59. i.receiver ! 42
  60. expectNoMsg(1 second)
  61. val gotit = for (_ 1 to 1000) yield i.receive()
  62. gotit must be((1 to 1000) map (_ 0))
  63. intercept[TimeoutException] {
  64. i.receive(1 second)
  65. }
  66. }
  67. "have a default and custom timeouts" in {
  68. val i = inbox()
  69. within(5 seconds, 6 seconds) {
  70. intercept[TimeoutException](i.receive())
  71. }
  72. within(1 second) {
  73. intercept[TimeoutException](i.receive(100 millis))
  74. }
  75. }
  76. }
  77. "A lightweight creator" must {
  78. "support creating regular actors" in {
  79. //#simple-actor
  80. val a = actor(new Act {
  81. become {
  82. case "hello" sender ! "hi"
  83. }
  84. })
  85. //#simple-actor
  86. implicit val i = inbox()
  87. a ! "hello"
  88. i.receive() must be("hi")
  89. }
  90. "support becomeStacked" in {
  91. //#becomeStacked
  92. val a = actor(new Act {
  93. become { // this will replace the initial (empty) behavior
  94. case "info" sender ! "A"
  95. case "switch"
  96. becomeStacked { // this will stack upon the "A" behavior
  97. case "info" sender ! "B"
  98. case "switch" unbecome() // return to the "A" behavior
  99. }
  100. case "lobotomize" unbecome() // OH NOES: Actor.emptyBehavior
  101. }
  102. })
  103. //#becomeStacked
  104. implicit def sender = testActor
  105. a ! "info"
  106. expectMsg("A")
  107. a ! "switch"
  108. a ! "info"
  109. expectMsg("B")
  110. a ! "switch"
  111. a ! "info"
  112. expectMsg("A")
  113. }
  114. "support setup/teardown" in {
  115. //#simple-start-stop
  116. val a = actor(new Act {
  117. whenStarting { testActor ! "started" }
  118. whenStopping { testActor ! "stopped" }
  119. })
  120. //#simple-start-stop
  121. system stop a
  122. expectMsg("started")
  123. expectMsg("stopped")
  124. }
  125. "support restart" in {
  126. //#failing-actor
  127. val a = actor(new Act {
  128. become {
  129. case "die" throw new Exception
  130. }
  131. whenFailing { (cause, msg) testActor ! (cause, msg) }
  132. whenRestarted { cause testActor ! cause }
  133. })
  134. //#failing-actor
  135. EventFilter[Exception](occurrences = 1) intercept {
  136. a ! "die"
  137. }
  138. expectMsgPF() { case (x: Exception, Some("die")) }
  139. expectMsgPF() { case _: Exception }
  140. }
  141. "support superviseWith" in {
  142. val a = actor(new Act {
  143. val system = null // shadow the implicit system
  144. //#supervise-with
  145. superviseWith(OneForOneStrategy() {
  146. case e: Exception if e.getMessage == "hello" Stop
  147. case _: Exception Resume
  148. })
  149. //#supervise-with
  150. val child = actor("child")(new Act {
  151. whenFailing { (_, _) }
  152. become {
  153. case ref: ActorRef whenStopping(ref ! "stopped")
  154. case ex: Exception throw ex
  155. }
  156. })
  157. become {
  158. case x child ! x
  159. }
  160. })
  161. a ! testActor
  162. EventFilter[Exception](occurrences = 1) intercept {
  163. a ! new Exception
  164. }
  165. expectNoMsg(1 second)
  166. EventFilter[Exception]("hello", occurrences = 1) intercept {
  167. a ! new Exception("hello")
  168. }
  169. expectMsg("stopped")
  170. }
  171. "supported nested declaration" in {
  172. val system = this.system
  173. //#nested-actor
  174. // here we pass in the ActorRefFactory explicitly as an example
  175. val a = actor(system, "fred")(new Act {
  176. val b = actor("barney")(new Act {
  177. whenStarting { context.parent ! ("hello from " + self) }
  178. })
  179. become {
  180. case x testActor ! x
  181. }
  182. })
  183. //#nested-actor
  184. expectMsg("hello from Actor[akka://ActorDSLSpec/user/fred/barney]")
  185. lastSender must be(a)
  186. }
  187. "support Stash" in {
  188. //#act-with-stash
  189. val a = actor(new ActWithStash {
  190. become {
  191. case 1 stash()
  192. case 2
  193. testActor ! 2; unstashAll(); becomeStacked {
  194. case 1 testActor ! 1; unbecome()
  195. }
  196. }
  197. })
  198. //#act-with-stash
  199. a ! 1
  200. a ! 2
  201. expectMsg(2)
  202. expectMsg(1)
  203. a ! 1
  204. a ! 2
  205. expectMsg(2)
  206. expectMsg(1)
  207. }
  208. }
  209. }