diff --git a/akka-camel/src/test/scala/ConsumerMethodRegisteredTest.scala b/akka-camel/src/test/scala/ConsumerMethodRegisteredTest.scala index 493030fa4a..7c28c7d8ee 100644 --- a/akka-camel/src/test/scala/ConsumerMethodRegisteredTest.scala +++ b/akka-camel/src/test/scala/ConsumerMethodRegisteredTest.scala @@ -2,21 +2,19 @@ package se.scalablesolutions.akka.camel import java.net.InetSocketAddress -import org.junit.Test import org.scalatest.junit.JUnitSuite import se.scalablesolutions.akka.actor.{AspectInit, ActiveObject} import se.scalablesolutions.akka.camel.ConsumerMethodRegistered._ +import org.junit.{AfterClass, Test} class ConsumerMethodRegisteredTest extends JUnitSuite { + import ConsumerMethodRegisteredTest._ + val remoteAddress = new InetSocketAddress("localhost", 8888); val remoteAspectInit = AspectInit(classOf[String], null, Some(remoteAddress), 1000) val localAspectInit = AspectInit(classOf[String], null, None, 1000) - val activePojoBase = ActiveObject.newInstance(classOf[PojoBase]) - val activePojoSub = ActiveObject.newInstance(classOf[PojoSub]) - val activePojoIntf = ActiveObject.newInstance(classOf[PojoIntf], new PojoImpl) - val ascendingMethodName = (r1: ConsumerMethodRegistered, r2: ConsumerMethodRegistered) => r1.method.getName < r2.method.getName @@ -44,3 +42,16 @@ class ConsumerMethodRegisteredTest extends JUnitSuite { } } + +object ConsumerMethodRegisteredTest { + val activePojoBase = ActiveObject.newInstance(classOf[PojoBase]) + val activePojoSub = ActiveObject.newInstance(classOf[PojoSub]) + val activePojoIntf = ActiveObject.newInstance(classOf[PojoIntf], new PojoImpl) + + @AfterClass + def afterClass = { + ActiveObject.stop(activePojoBase) + ActiveObject.stop(activePojoSub) + ActiveObject.stop(activePojoIntf) + } +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojo.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojo.java new file mode 100644 index 0000000000..50f3e43221 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojo.java @@ -0,0 +1,37 @@ +package se.scalablesolutions.akka.actor; + +import java.util.concurrent.CountDownLatch; + +public class SamplePojo { + + private CountDownLatch latch; + + public boolean _pre = false; + public boolean _post = false; + public boolean _down = false; + + public CountDownLatch newCountdownLatch(int count) { + latch = new CountDownLatch(count); + return latch; + } + + public String fail() { + throw new RuntimeException("expected"); + } + + public void pre() { + _pre = true; + latch.countDown(); + } + + public void post() { + _post = true; + latch.countDown(); + } + + public void down() { + _down = true; + latch.countDown(); + } + +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojoAnnotated.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojoAnnotated.java new file mode 100644 index 0000000000..8bf4ba36d3 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SamplePojoAnnotated.java @@ -0,0 +1,52 @@ +package se.scalablesolutions.akka.actor; + +import se.scalablesolutions.akka.actor.annotation.postrestart; +import se.scalablesolutions.akka.actor.annotation.prerestart; +import se.scalablesolutions.akka.actor.annotation.shutdown; + +import java.util.concurrent.CountDownLatch; + +public class SamplePojoAnnotated { + + private CountDownLatch latch; + + public boolean _pre = false; + public boolean _post = false; + public boolean _down = false; + + public SamplePojoAnnotated() { + latch = new CountDownLatch(1); + } + + public CountDownLatch newCountdownLatch(int count) { + latch = new CountDownLatch(count); + return latch; + } + + public String greet(String s) { + return "hello " + s; + } + + public String fail() { + throw new RuntimeException("expected"); + } + + @prerestart + public void pre() { + _pre = true; + latch.countDown(); + } + + @postrestart + public void post() { + _post = true; + latch.countDown(); + } + + @shutdown + public void down() { + _down = true; + latch.countDown(); + } + +} \ No newline at end of file diff --git a/akka-core/src/test/scala/ActiveObjectLifecycleSpec.scala b/akka-core/src/test/scala/ActiveObjectLifecycleSpec.scala new file mode 100644 index 0000000000..d6fd5e795e --- /dev/null +++ b/akka-core/src/test/scala/ActiveObjectLifecycleSpec.scala @@ -0,0 +1,145 @@ +package se.scalablesolutions.akka.actor + +import org.junit.runner.RunWith +import org.scalatest.{BeforeAndAfterAll, Spec} +import org.scalatest.junit.JUnitRunner +import org.scalatest.matchers.ShouldMatchers + +import se.scalablesolutions.akka.config.ActiveObjectConfigurator +import se.scalablesolutions.akka.config.JavaConfig._ + +/** + * @author Martin Krasser + */ +@RunWith(classOf[JUnitRunner]) +class ActiveObjectLifecycleSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { + var conf1: ActiveObjectConfigurator = _ + var conf2: ActiveObjectConfigurator = _ + var conf3: ActiveObjectConfigurator = _ + var conf4: ActiveObjectConfigurator = _ + + override protected def beforeAll() = { + val strategy = new RestartStrategy(new AllForOne(), 3, 1000, Array(classOf[Exception])) + val comp1 = new Component(classOf[SamplePojoAnnotated], new LifeCycle(new Permanent()), 1000) + val comp2 = new Component(classOf[SamplePojoAnnotated], new LifeCycle(new Temporary()), 1000) + val comp3 = new Component(classOf[SamplePojo], new LifeCycle(new Permanent(), new RestartCallbacks("pre", "post")), 1000) + val comp4 = new Component(classOf[SamplePojo], new LifeCycle(new Temporary(), new ShutdownCallback("down")), 1000) + conf1 = new ActiveObjectConfigurator().configure(strategy, Array(comp1)).supervise + conf2 = new ActiveObjectConfigurator().configure(strategy, Array(comp2)).supervise + conf3 = new ActiveObjectConfigurator().configure(strategy, Array(comp3)).supervise + conf4 = new ActiveObjectConfigurator().configure(strategy, Array(comp4)).supervise + } + + override protected def afterAll() = { + conf1.stop + conf2.stop + conf3.stop + conf4.stop + } + + it("should restart supervised, annotated active object on failure") { + val obj = conf1.getInstance[SamplePojoAnnotated](classOf[SamplePojoAnnotated]) + val cdl = obj.newCountdownLatch(2) + assert(AspectInitRegistry.initFor(obj) ne null) + try { + obj.fail + fail("expected exception not thrown") + } catch { + case e: RuntimeException => { + cdl.await + assert(obj._pre) + assert(obj._post) + assert(!obj._down) + assert(AspectInitRegistry.initFor(obj) ne null) + } + } + } + + it("should shutdown supervised, annotated active object on failure") { + val obj = conf2.getInstance[SamplePojoAnnotated](classOf[SamplePojoAnnotated]) + val cdl = obj.newCountdownLatch(1) + assert(AspectInitRegistry.initFor(obj) ne null) + try { + obj.fail + fail("expected exception not thrown") + } catch { + case e: RuntimeException => { + cdl.await + assert(!obj._pre) + assert(!obj._post) + assert(obj._down) + assert(AspectInitRegistry.initFor(obj) eq null) + } + } + } + + it("should restart supervised, non-annotated active object on failure") { + val obj = conf3.getInstance[SamplePojo](classOf[SamplePojo]) + val cdl = obj.newCountdownLatch(2) + assert(AspectInitRegistry.initFor(obj) ne null) + try { + obj.fail + fail("expected exception not thrown") + } catch { + case e: RuntimeException => { + cdl.await + assert(obj._pre) + assert(obj._post) + assert(!obj._down) + assert(AspectInitRegistry.initFor(obj) ne null) + } + } + } + + it("should shutdown supervised, non-annotated active object on failure") { + val obj = conf4.getInstance[SamplePojo](classOf[SamplePojo]) + val cdl = obj.newCountdownLatch(1) + assert(AspectInitRegistry.initFor(obj) ne null) + try { + obj.fail + fail("expected exception not thrown") + } catch { + case e: RuntimeException => { + cdl.await + assert(!obj._pre) + assert(!obj._post) + assert(obj._down) + assert(AspectInitRegistry.initFor(obj) eq null) + } + } + } + + it("should shutdown non-supervised, annotated active object on ActiveObject.stop") { + val obj = ActiveObject.newInstance(classOf[SamplePojoAnnotated]) + assert(AspectInitRegistry.initFor(obj) ne null) + assert("hello akka" === obj.greet("akka")) + ActiveObject.stop(obj) + assert(AspectInitRegistry.initFor(obj) eq null) + assert(!obj._pre) + assert(!obj._post) + assert(obj._down) + try { + obj.greet("akka") + fail("access to stopped active object") + } catch { + case e: Exception => { /* test passed */ } + } + } + + it("should shutdown non-supervised, annotated active object on ActorRegistry.shutdownAll") { + val obj = ActiveObject.newInstance(classOf[SamplePojoAnnotated]) + assert(AspectInitRegistry.initFor(obj) ne null) + assert("hello akka" === obj.greet("akka")) + ActorRegistry.shutdownAll + assert(AspectInitRegistry.initFor(obj) eq null) + assert(!obj._pre) + assert(!obj._post) + assert(obj._down) + try { + obj.greet("akka") + fail("access to stopped active object") + } catch { + case e: Exception => { /* test passed */ } + } + } +} \ No newline at end of file