From c6b7ba6a01e7c1af3fcd65c3bd377af1b4a9d8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bon=C3=A9r?= Date: Mon, 28 Jun 2010 22:22:41 +0200 Subject: [PATCH] Added Java tests as Scala tests --- .../se/scalablesolutions/akka/actor/Bar.java | 6 + .../scalablesolutions/akka/actor/BarImpl.java | 13 ++ .../se/scalablesolutions/akka/actor/Ext.java | 6 + .../scalablesolutions/akka/actor/ExtImpl.java | 6 + .../se/scalablesolutions/akka/actor/Foo.java | 34 ++++ .../akka/actor/InMemFailer.java | 7 + .../akka/actor/InMemStateful.java | 91 ++++++++++ .../akka/actor/InMemStatefulNested.java | 85 ++++++++++ .../akka/actor/SimpleJavaPojo.java | 36 ++++ akka-core/src/test/resources/META-INF/aop.xml | 7 + .../ActiveObjectGuiceConfiguratorSpec.scala | 129 ++++++++++++++ .../src/test/scala/InMemNestedStateSpec.scala | 160 ++++++++++++++++++ .../src/test/scala/InMemoryStateSpec.scala | 110 ++++++++++++ .../test/scala/RemoteInMemoryStateSpec.scala | 93 ++++++++++ akka-core/src/test/scala/TestClasses.bak | 102 +++++++++++ 15 files changed, 885 insertions(+) create mode 100644 akka-core/src/test/java/se/scalablesolutions/akka/actor/Bar.java create mode 100644 akka-core/src/test/java/se/scalablesolutions/akka/actor/BarImpl.java create mode 100644 akka-core/src/test/java/se/scalablesolutions/akka/actor/Ext.java create mode 100644 akka-core/src/test/java/se/scalablesolutions/akka/actor/ExtImpl.java create mode 100644 akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java create mode 100644 akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemFailer.java create mode 100644 akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStateful.java create mode 100644 akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStatefulNested.java create mode 100644 akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojo.java create mode 100644 akka-core/src/test/resources/META-INF/aop.xml create mode 100644 akka-core/src/test/scala/ActiveObjectGuiceConfiguratorSpec.scala create mode 100644 akka-core/src/test/scala/InMemNestedStateSpec.scala create mode 100644 akka-core/src/test/scala/InMemoryStateSpec.scala create mode 100644 akka-core/src/test/scala/RemoteInMemoryStateSpec.scala create mode 100644 akka-core/src/test/scala/TestClasses.bak diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/Bar.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/Bar.java new file mode 100644 index 0000000000..906476b789 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/Bar.java @@ -0,0 +1,6 @@ +package se.scalablesolutions.akka.actor; + +public interface Bar { + void bar(String msg); + Ext getExt(); +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/BarImpl.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/BarImpl.java new file mode 100644 index 0000000000..09b50a7347 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/BarImpl.java @@ -0,0 +1,13 @@ +package se.scalablesolutions.akka.actor; + +import com.google.inject.Inject; + +public class BarImpl implements Bar { + @Inject + private Ext ext; + public Ext getExt() { + return ext; + } + public void bar(String msg) { + } +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/Ext.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/Ext.java new file mode 100644 index 0000000000..c37219cf00 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/Ext.java @@ -0,0 +1,6 @@ +package se.scalablesolutions.akka.actor; + +public interface Ext { + void ext(); +} + diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/ExtImpl.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/ExtImpl.java new file mode 100644 index 0000000000..dd8ca55089 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/ExtImpl.java @@ -0,0 +1,6 @@ +package se.scalablesolutions.akka.actor; + +public class ExtImpl implements Ext { + public void ext() { + } +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java new file mode 100644 index 0000000000..7382cb6aef --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java @@ -0,0 +1,34 @@ +package se.scalablesolutions.akka.actor; + +import com.google.inject.Inject; + +public class Foo extends se.scalablesolutions.akka.serialization.Serializable.JavaJSON { + @Inject + private Bar bar; + public Foo body() { return this; } + public Bar getBar() { + return bar; + } + public String foo(String msg) { + return msg + "return_foo "; + } + public void bar(String msg) { + bar.bar(msg); + } + public String longRunning() { + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + } + return "test"; + } + public String throwsException() { + if (true) throw new RuntimeException("expected"); + return "test"; + } + + public int $tag() throws java.rmi.RemoteException + { + return 0; + } +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemFailer.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemFailer.java new file mode 100644 index 0000000000..6239c64402 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemFailer.java @@ -0,0 +1,7 @@ +package se.scalablesolutions.akka.actor; + +public class InMemFailer implements java.io.Serializable { + public int fail() { + throw new RuntimeException("expected"); + } +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStateful.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStateful.java new file mode 100644 index 0000000000..928692ce07 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStateful.java @@ -0,0 +1,91 @@ +package se.scalablesolutions.akka.actor; + +import se.scalablesolutions.akka.actor.annotation.transactionrequired; +import se.scalablesolutions.akka.actor.annotation.prerestart; +import se.scalablesolutions.akka.actor.annotation.postrestart; +import se.scalablesolutions.akka.actor.annotation.inittransactionalstate; +import se.scalablesolutions.akka.stm.*; + +@transactionrequired +public class InMemStateful { + private TransactionalMap mapState; + private TransactionalVector vectorState; + private Ref refState; + private boolean isInitialized = false; + + public void init() { + if (!isInitialized) { + mapState = new TransactionalMap(); + vectorState = new TransactionalVector(); + refState = new Ref(); + isInitialized = true; + } + } + + public String getMapState(String key) { + return (String)mapState.get(key).get(); + } + + public String getVectorState() { + return (String)vectorState.last(); + } + + public String getRefState() { + return (String)refState.get().get(); + } + + public void setMapState(String key, String msg) { + mapState.put(key, msg); + } + + public void setVectorState(String msg) { + vectorState.add(msg); + } + + public void setRefState(String msg) { + refState.swap(msg); + } + + public void success(String key, String msg) { + mapState.put(key, msg); + vectorState.add(msg); + refState.swap(msg); + } + + public void success(String key, String msg, InMemStatefulNested nested) { + mapState.put(key, msg); + vectorState.add(msg); + refState.swap(msg); + nested.success(key, msg); + } + + public String failure(String key, String msg, InMemFailer failer) { + mapState.put(key, msg); + vectorState.add(msg); + refState.swap(msg); + failer.fail(); + return msg; + } + + public String failure(String key, String msg, InMemStatefulNested nested, InMemFailer failer) { + mapState.put(key, msg); + vectorState.add(msg); + refState.swap(msg); + nested.failure(key, msg, failer); + return msg; + } + + public void thisMethodHangs(String key, String msg, InMemFailer failer) { + setMapState(key, msg); + } + + @prerestart + public void preRestart() { + System.out.println("################ PRE RESTART"); + } + + @postrestart + public void postRestart() { + System.out.println("################ POST RESTART"); + } +} diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStatefulNested.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStatefulNested.java new file mode 100644 index 0000000000..0b484c1178 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStatefulNested.java @@ -0,0 +1,85 @@ +package se.scalablesolutions.akka.actor; + +import se.scalablesolutions.akka.actor.annotation.transactionrequired; +import se.scalablesolutions.akka.actor.annotation.inittransactionalstate; +import se.scalablesolutions.akka.stm.*; + +@transactionrequired +public class InMemStatefulNested { + private TransactionalMap mapState; + private TransactionalVector vectorState; + private Ref refState; + private boolean isInitialized = false; + + public void init() { + if (!isInitialized) { + mapState = new TransactionalMap(); + vectorState = new TransactionalVector(); + refState = new Ref(); + isInitialized = true; + } + } + + public String getMapState(String key) { + return (String) mapState.get(key).get(); + } + + + public String getVectorState() { + return (String) vectorState.last(); + } + + + public String getRefState() { + return (String) refState.get().get(); + } + + + public void setMapState(String key, String msg) { + mapState.put(key, msg); + } + + + public void setVectorState(String msg) { + vectorState.add(msg); + } + + + public void setRefState(String msg) { + refState.swap(msg); + } + + + public void success(String key, String msg) { + mapState.put(key, msg); + vectorState.add(msg); + refState.swap(msg); + } + + + public String failure(String key, String msg, InMemFailer failer) { + mapState.put(key, msg); + vectorState.add(msg); + refState.swap(msg); + failer.fail(); + return msg; + } + + + public void thisMethodHangs(String key, String msg, InMemFailer failer) { + setMapState(key, msg); + } + + /* + public void clashOk(String key, String msg, InMemClasher clasher) { + mapState.put(key, msg); + clasher.clash(); + } + + public void clashNotOk(String key, String msg, InMemClasher clasher) { + mapState.put(key, msg); + clasher.clash(); + this.success("clash", "clash"); + } + */ +} \ No newline at end of file diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojo.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojo.java new file mode 100644 index 0000000000..4cb6abd301 --- /dev/null +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SimpleJavaPojo.java @@ -0,0 +1,36 @@ +package se.scalablesolutions.akka.actor; + +import se.scalablesolutions.akka.actor.annotation.prerestart; +import se.scalablesolutions.akka.actor.annotation.postrestart; + +public class SimpleJavaPojo { + + public boolean pre = false; + public boolean post = false; + + private String name; + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + @prerestart + public void pre() { + System.out.println("** pre()"); + pre = true; + } + + @postrestart + public void post() { + System.out.println("** post()"); + post = true; + } + + public void throwException() { + throw new RuntimeException(); + } +} diff --git a/akka-core/src/test/resources/META-INF/aop.xml b/akka-core/src/test/resources/META-INF/aop.xml new file mode 100644 index 0000000000..2f8d5159a8 --- /dev/null +++ b/akka-core/src/test/resources/META-INF/aop.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/akka-core/src/test/scala/ActiveObjectGuiceConfiguratorSpec.scala b/akka-core/src/test/scala/ActiveObjectGuiceConfiguratorSpec.scala new file mode 100644 index 0000000000..c8fd436e1c --- /dev/null +++ b/akka-core/src/test/scala/ActiveObjectGuiceConfiguratorSpec.scala @@ -0,0 +1,129 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package se.scalablesolutions.akka.actor + +import com.google.inject.AbstractModule +import com.google.inject.Scopes + +import org.scalatest.Spec +import org.scalatest.Assertions +import org.scalatest.matchers.ShouldMatchers +import org.scalatest.BeforeAndAfterAll +import org.scalatest.junit.JUnitRunner +import org.junit.runner.RunWith + +import se.scalablesolutions.akka.config.Config +import se.scalablesolutions.akka.config.ActiveObjectConfigurator +import se.scalablesolutions.akka.config.JavaConfig._ +import se.scalablesolutions.akka.dispatch._ +import se.scalablesolutions.akka.dispatch.FutureTimeoutException + +@RunWith(classOf[JUnitRunner]) +class ActiveObjectGuiceConfiguratorSpec extends + Spec with + ShouldMatchers with + BeforeAndAfterAll { + + private val conf = new ActiveObjectConfigurator + private var messageLog = "" + + override def beforeAll { + Config.config + val dispatcher = Dispatchers.newExecutorBasedEventDrivenDispatcher("test") + + conf.addExternalGuiceModule(new AbstractModule { + def configure = bind(classOf[Ext]).to(classOf[ExtImpl]).in(Scopes.SINGLETON) + }).configure( + new RestartStrategy(new AllForOne, 3, 5000, List(classOf[Exception]).toArray), + List( + new Component( + classOf[Foo], + new LifeCycle(new Permanent), + 1000, + dispatcher), + new Component( + classOf[Bar], + classOf[BarImpl], + new LifeCycle(new Permanent), + 1000, + dispatcher) + ).toArray).inject.supervise + + } + + override def afterAll = conf.stop + + describe("ActiveObjectGuiceConfigurator") { + + it("should inject active object using guice") { + messageLog = "" + val foo = conf.getInstance(classOf[Foo]) + val bar = conf.getInstance(classOf[Bar]) + bar should equal(foo.getBar) + } + + it("should inject external dependency using guice") { + messageLog = "" + val bar = conf.getInstance(classOf[Bar]) + val ext = conf.getExternalDependency(classOf[Ext]) + ext.toString should equal(bar.getExt.toString) + } + + it("should lookup non-supervised instance") { + try { + val str = conf.getInstance(classOf[String]) + fail("exception should have been thrown") + } catch { + case e: Exception => + classOf[IllegalStateException] should equal(e.getClass) + } + } + + it("should be able to invoke active object") { + messageLog = "" + val foo = conf.getInstance(classOf[Foo]) + messageLog += foo.foo("foo ") + foo.bar("bar ") + messageLog += "before_bar " + Thread.sleep(500) + messageLog should equal("foo return_foo before_bar ") + } + + it("should be able to invoke active object's invocation") { + messageLog = "" + val foo = conf.getInstance(classOf[Foo]) + val bar = conf.getInstance(classOf[Bar]) + messageLog += foo.foo("foo ") + foo.bar("bar ") + messageLog += "before_bar " + Thread.sleep(500) + messageLog should equal("foo return_foo before_bar ") + } + + it("should throw FutureTimeoutException on time-out") { + messageLog = "" + val foo = conf.getInstance(classOf[Foo]) + try { + foo.longRunning + fail("exception should have been thrown") + } catch { + case e: FutureTimeoutException => + classOf[FutureTimeoutException] should equal(e.getClass) + } + } + + it("should propagate exception") { + messageLog = "" + val foo = conf.getInstance(classOf[Foo]) + try { + foo.throwsException + fail("exception should have been thrown") + } catch { + case e: RuntimeException => + classOf[RuntimeException] should equal(e.getClass) + } + } + } +} diff --git a/akka-core/src/test/scala/InMemNestedStateSpec.scala b/akka-core/src/test/scala/InMemNestedStateSpec.scala new file mode 100644 index 0000000000..3f1aca7049 --- /dev/null +++ b/akka-core/src/test/scala/InMemNestedStateSpec.scala @@ -0,0 +1,160 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package se.scalablesolutions.akka.actor + +import org.scalatest.Spec +import org.scalatest.Assertions +import org.scalatest.matchers.ShouldMatchers +import org.scalatest.BeforeAndAfterAll +import org.scalatest.junit.JUnitRunner +import org.junit.runner.RunWith + +import se.scalablesolutions.akka.config.Config +import se.scalablesolutions.akka.config._ +import se.scalablesolutions.akka.config.ActiveObjectConfigurator +import se.scalablesolutions.akka.config.JavaConfig._ +import se.scalablesolutions.akka.actor._ + +@RunWith(classOf[JUnitRunner]) +class InMemoryNestedStateSpec extends + Spec with + ShouldMatchers with + BeforeAndAfterAll { + + private val conf = new ActiveObjectConfigurator + private var messageLog = "" + + override def beforeAll { + Config.config + conf.configure( + new RestartStrategy(new AllForOne, 3, 5000, List(classOf[Exception]).toArray), + List( + new Component(classOf[InMemStateful], + new LifeCycle(new Permanent), + 10000), + new Component(classOf[InMemStatefulNested], + new LifeCycle(new Permanent), + 10000), + new Component(classOf[InMemFailer], + new LifeCycle(new Permanent), + 10000) + ).toArray).supervise + } + + override def afterAll { + conf.stop + } + + describe("Transactional nested in-memory Active Object") { + + it("map should not rollback state for stateful server in case of success") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") // set init state + Thread.sleep(100) + val nested = conf.getInstance(classOf[InMemStatefulNested]) + nested.init + nested.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") // set init state + Thread.sleep(100) + stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state", nested) // transactionrequired + Thread.sleep(100) + stateful.getMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess") should equal("new state") + nested.getMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess") should equal("new state") + } + + it("map should rollback state for stateful server in case of failure") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state + Thread.sleep(100) + val nested = conf.getInstance(classOf[InMemStatefulNested]) + nested.init + nested.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state + Thread.sleep(100) + val failer = conf.getInstance(classOf[InMemFailer]) + try { + stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) + Thread.sleep(100) + fail("should have thrown an exception") + } catch { case e => {} } + stateful.getMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure") should equal("init") + Thread.sleep(100) + nested.getMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure") should equal("init") + } + + it("vector should not rollback state for stateful server in case of success") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + stateful.setVectorState("init") // set init state + Thread.sleep(100) + val nested = conf.getInstance(classOf[InMemStatefulNested]) + nested.init + Thread.sleep(100) + nested.setVectorState("init") // set init state + Thread.sleep(100) + stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state", nested) // transactionrequired + Thread.sleep(100) + stateful.getVectorState should equal("new state") + Thread.sleep(100) + nested.getVectorState should equal("new state") + } + + it("vector should rollback state for stateful server in case of failure") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + stateful.setVectorState("init") // set init state + Thread.sleep(100) + val nested = conf.getInstance(classOf[InMemStatefulNested]) + nested.init + nested.setVectorState("init") // set init state + Thread.sleep(100) + val failer = conf.getInstance(classOf[InMemFailer]) + try { + stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) + Thread.sleep(100) + fail("should have thrown an exception") + } catch { case e => {} } + stateful.getVectorState should equal("init") + Thread.sleep(100) + nested.getVectorState should equal("init") + } + + it("ref should not rollback state for stateful server in case of success") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + val nested = conf.getInstance(classOf[InMemStatefulNested]) + nested.init + stateful.setRefState("init") // set init state + Thread.sleep(100) + nested.setRefState("init") // set init state + Thread.sleep(100) + stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state", nested) + Thread.sleep(100) + stateful.getRefState should equal("new state") + Thread.sleep(100) + nested.getRefState should equal("new state") + } + + it("ref should rollback state for stateful server in case of failure") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + val nested = conf.getInstance(classOf[InMemStatefulNested]) + nested.init + stateful.setRefState("init") // set init state + Thread.sleep(100) + nested.setRefState("init") // set init state + Thread.sleep(100) + val failer = conf.getInstance(classOf[InMemFailer]) + try { + stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) + Thread.sleep(100) + fail("should have thrown an exception") + } catch { case e => {} } + stateful.getRefState should equal("init") + Thread.sleep(100) + nested.getRefState should equal("init") + } + } +} diff --git a/akka-core/src/test/scala/InMemoryStateSpec.scala b/akka-core/src/test/scala/InMemoryStateSpec.scala new file mode 100644 index 0000000000..d4f92c9759 --- /dev/null +++ b/akka-core/src/test/scala/InMemoryStateSpec.scala @@ -0,0 +1,110 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package se.scalablesolutions.akka.actor + +import org.scalatest.Spec +import org.scalatest.Assertions +import org.scalatest.matchers.ShouldMatchers +import org.scalatest.BeforeAndAfterAll +import org.scalatest.junit.JUnitRunner +import org.junit.runner.RunWith + +import se.scalablesolutions.akka.config.Config +import se.scalablesolutions.akka.config._ +import se.scalablesolutions.akka.config.ActiveObjectConfigurator +import se.scalablesolutions.akka.config.JavaConfig._ +import se.scalablesolutions.akka.actor._ + +@RunWith(classOf[JUnitRunner]) +class InMemoryStateSpec extends + Spec with + ShouldMatchers with + BeforeAndAfterAll { + + private val conf = new ActiveObjectConfigurator + private var messageLog = "" + + override def beforeAll { + Config.config + conf.configure( + new RestartStrategy(new AllForOne, 3, 5000, List(classOf[Exception]).toArray), + List( + new Component(classOf[InMemStateful], + new LifeCycle(new Permanent), + //new RestartCallbacks("preRestart", "postRestart")), + 10000), + new Component(classOf[InMemFailer], + new LifeCycle(new Permanent), + 10000)).toArray + ).supervise + } + + override def afterAll { + conf.stop + } + + describe("Transactional in-memory Active Object ") { + + it("map should not rollback state for stateful server in case of success") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") + stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") + stateful.getMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess") should equal("new state") + } + + it("map should rollback state for stateful server in case of failure") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") + val failer = conf.getInstance(classOf[InMemFailer]) + try { + stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) + fail("should have thrown an exception") + } catch { case e => {} } + stateful.getMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure") should equal("init") + } + + it("vector should rollback state for stateful server in case of failure") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + stateful.setVectorState("init") // set init state + val failer = conf.getInstance(classOf[InMemFailer]) + try { + stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) + fail("should have thrown an exception") + } catch { case e => {} } + stateful.getVectorState should equal("init") + } + + it("vector should not rollback state for stateful server in case of success") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + stateful.setVectorState("init") // set init state + stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") + stateful.getVectorState should equal("new state") + } + + it("ref should rollback state for stateful server in case of failure") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + stateful.setRefState("init") // set init state + val failer = conf.getInstance(classOf[InMemFailer]) + try { + stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) + fail("should have thrown an exception") + } catch { case e => {} } + stateful.getRefState should equal("init") + } + + it("ref should not rollback state for stateful server in case of success") { + val stateful = conf.getInstance(classOf[InMemStateful]) + stateful.init + stateful.setRefState("init") // set init state + stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") + stateful.getRefState should equal("new state") + } + } +} diff --git a/akka-core/src/test/scala/RemoteInMemoryStateSpec.scala b/akka-core/src/test/scala/RemoteInMemoryStateSpec.scala new file mode 100644 index 0000000000..57e4efb827 --- /dev/null +++ b/akka-core/src/test/scala/RemoteInMemoryStateSpec.scala @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package se.scalablesolutions.akka.actor + +import org.scalatest.Spec +import org.scalatest.Assertions +import org.scalatest.matchers.ShouldMatchers +import org.scalatest.BeforeAndAfterAll +import org.scalatest.junit.JUnitRunner +import org.junit.runner.RunWith + +import se.scalablesolutions.akka.config.Config +import se.scalablesolutions.akka.config.ActiveObjectConfigurator +import se.scalablesolutions.akka.remote.RemoteNode + +@RunWith(classOf[JUnitRunner]) +class RemoteInMemoryStateSpec extends + Spec with + ShouldMatchers with + BeforeAndAfterAll { + + private val conf = new ActiveObjectConfigurator + private var messageLog = "" + + override def beforeAll = { + Config.config + new Thread(new Runnable { + def run = RemoteNode.start + }).start + Thread.sleep(1000) + } + + override def afterAll = conf.stop + + describe("Remote transactional in-memory Active Object ") { + + it("map should not rollback state for stateful server in case of success") { + val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") // set init state + stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired + stateful.getMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess") should equal("new state") + } + + it("map should rollback state for stateful server in case of failure") { + val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state + val failer =ActiveObject.newRemoteInstance(classOf[InMemFailer], 1000, "localhost", 9999) //conf.getInstance(classOf[InMemFailer]) + try { + stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method + fail("should have thrown an exception") + } catch { case e => {} } + stateful.getMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure") should equal("init") + } + + it("vector should not rollback state for stateful server in case of success") { + val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + stateful.setVectorState("init") // set init state + stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired + stateful.getVectorState should equal("new state") + } + + it("vector should rollback state for stateful server in case of failure") { + val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + stateful.setVectorState("init") // set init state + val failer =ActiveObject.newRemoteInstance(classOf[InMemFailer], 1000, "localhost", 9999) //conf.getInstance(classOf[InMemFailer]) + try { + stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method + fail("should have thrown an exception") + } catch { case e => {} } + stateful.getVectorState should equal("init") + } + + it("ref should not rollback state for stateful server in case of success") { + val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + stateful.setRefState("init") // set init state + stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired + stateful.getRefState should equal("new state") + } + + it("ref should rollback state for stateful server in case of failure") { + val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + stateful.setRefState("init") // set init state + val failer =ActiveObject.newRemoteInstance(classOf[InMemFailer], 1000, "localhost", 9999) //conf.getInstance(classOf[InMemFailer]) + try { + stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method + fail("should have thrown an exception") + } catch { case e => {} } + stateful.getRefState should equal("init") + } + } +} diff --git a/akka-core/src/test/scala/TestClasses.bak b/akka-core/src/test/scala/TestClasses.bak new file mode 100644 index 0000000000..673cf6e4ac --- /dev/null +++ b/akka-core/src/test/scala/TestClasses.bak @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2009-2010 Scalable Solutions AB + */ + +package se.scalablesolutions.akka.actor + +import se.scalablesolutions.akka.serialization.Serializable +import se.scalablesolutions.akka.actor.annotation.transactionrequired +import se.scalablesolutions.akka.actor.annotation.prerestart +import se.scalablesolutions.akka.actor.annotation.postrestart +import se.scalablesolutions.akka.actor.annotation.inittransactionalstate +import se.scalablesolutions.akka.actor.annotation.oneway +import se.scalablesolutions.akka.stm._ + +import com.google.inject.Inject + +trait Bar { + @oneway + def bar(msg: String): String + def getExt: Ext +} + +class BarImpl extends Bar { + @Inject private var ext: Ext = _ + def getExt: Ext = ext + def bar(msg: String) = msg +} + +trait Ext +class ExtImpl extends Ext + +class Foo extends Serializable.JavaJSON { + @Inject + private var bar: Bar = _ + def body = this + def getBar = bar + def foo(msg: String): String = msg + "_foo " + def bar(msg: String): String = bar.bar(msg) + def longRunning = { + Thread.sleep(10000) + "test" + } + def throwsException: String = { + if (true) throw new RuntimeException("expected") + "test" + } +} + +@serializable class InMemFailer { + def fail = throw new RuntimeException("expected") +} + +@transactionrequired +class InMemStateful { + private lazy val mapState = TransactionalState.newMap[String, String] + private lazy val vectorState = TransactionalState.newVector[String] + private lazy val refState = TransactionalState.newRef[String] + + def getMapState(key: String): String = mapState.get(key).get + def getVectorState: String = vectorState.last + def getRefState: String = refState.get.get + def setMapState(key: String, msg: String): Unit = mapState.put(key, msg) + def setVectorState(msg: String): Unit = vectorState.add(msg) + def setRefState(msg: String): Unit = refState.swap(msg) + def success(key: String, msg: String): Unit = { + mapState.put(key, msg) + vectorState.add(msg) + refState.swap(msg) + } + + def success(key: String, msg: String, nested: InMemStatefulNested): Unit = { + mapState.put(key, msg) + vectorState.add(msg) + refState.swap(msg) + nested.success(key, msg) + } + + def failure(key: String, msg: String, failer: InMemFailer): String = { + mapState.put(key, msg) + vectorState.add(msg) + refState.swap(msg) + failer.fail + msg + } + + def failure(key: String, msg: String, nested: InMemStatefulNested, failer: InMemFailer): String = { + mapState.put(key, msg) + vectorState.add(msg) + refState.swap(msg) + nested.failure(key, msg, failer) + msg + } + + def thisMethodHangs(key: String, msg: String, failer: InMemFailer) = setMapState(key, msg) + + @prerestart def preRestart = println("################ PRE RESTART") + @postrestart def postRestart = println("################ POST RESTART") +} + +@transactionrequired +class InMemStatefulNested extends InMemStateful +