pekko/akka-core/src/test/scala/StmSpec.scala

173 lines
4.6 KiB
Scala
Raw Normal View History

package se.scalablesolutions.akka.actor
import se.scalablesolutions.akka.stm._
2010-05-01 12:59:24 +02:00
import 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
@RunWith(classOf[JUnitRunner])
class StmSpec extends
Spec with
ShouldMatchers with
BeforeAndAfterAll {
describe("Transaction.Local") {
it("should be able to do multiple consecutive atomic {..} statements") {
import Transaction.Local._
lazy val ref = TransactionalState.newRef[Int]
def increment = atomic {
ref.swap(ref.get.getOrElse(0) + 1)
}
def total: Int = atomic {
ref.get.getOrElse(0)
}
increment
increment
increment
total should equal(3)
}
it("should be able to do nested atomic {..} statements") {
import Transaction.Local._
lazy val ref = TransactionalState.newRef[Int]
def increment = atomic {
ref.swap(ref.get.getOrElse(0) + 1)
}
def total: Int = atomic {
ref.get.getOrElse(0)
}
atomic {
increment
increment
}
atomic {
increment
total should equal(3)
}
}
it("should roll back failing nested atomic {..} statements") {
import Transaction.Local._
lazy val ref = TransactionalState.newRef[Int]
def increment = atomic {
ref.swap(ref.get.getOrElse(0) + 1)
}
def total: Int = atomic {
ref.get.getOrElse(0)
}
try {
atomic {
increment
increment
throw new Exception
}
} catch {
case e => {}
}
total should equal(0)
}
}
2010-05-24 12:31:04 +02:00
describe("Transaction.Global") {
it("should be able to initialize with atomic {..} block inside actor constructor") {
import GlobalTransactionVectorTestActor._
2010-05-24 12:31:04 +02:00
try {
val actor = actorOf[GlobalTransactionVectorTestActor].start
actor !! Add(5)
val size1: Int = (actor !! Size).getOrElse(fail("Could not get Vector::size"))
size1 should equal(2)
actor !! Add(2)
val size2: Int = (actor !! Size).getOrElse(fail("Could not get Vector::size"))
size2 should equal(3)
2010-05-24 12:31:04 +02:00
} catch {
case e =>
e.printStackTrace
fail(e.toString)
2010-05-24 12:31:04 +02:00
}
}
}
/*
describe("Multiverse API") {
it("should blablabla") {
import org.multiverse.api.programmatic._
// import org.multiverse.api._
import org.multiverse.templates._
import java.util.concurrent.atomic._
import se.scalablesolutions.akka.stm.Ref
import org.multiverse.api.{GlobalStmInstance, ThreadLocalTransaction, Transaction => MultiverseTransaction}
import org.multiverse.api.lifecycle.{TransactionLifecycleListener, TransactionLifecycleEvent}
import org.multiverse.commitbarriers._
def createRef[T]: ProgrammaticReference[T] = GlobalStmInstance
.getGlobalStmInstance
.getProgrammaticReferenceFactoryBuilder
.build
.atomicCreateReference(null.asInstanceOf[T])
val ref1 = Ref(0)//createRef[Int]
val ref2 = Ref(0)//createRef[Int]
val committedCount = new AtomicInteger
val abortedCount = new AtomicInteger
val barrierHolder = new AtomicReference[CountDownCommitBarrier]
val template = new TransactionTemplate[Int]() {
override def onStart(tx: MultiverseTransaction) = barrierHolder.set(new CountDownCommitBarrier(1))
override def execute(tx: MultiverseTransaction): Int = {
ref1.swap(ref1.get.get + 1)
ref2.swap(ref2.get.get + 1)
barrierHolder.get.joinCommit(tx)
null.asInstanceOf[Int]
}
override def onPostCommit = committedCount.incrementAndGet
override def onPostAbort = abortedCount.incrementAndGet
}
template.execute
ref1.get.get should equal(1)
ref2.get.get should equal(1)
committedCount.get should equal(1)
abortedCount.get should equal(2)
}
}
*/
2010-05-24 12:31:04 +02:00
}
object GlobalTransactionVectorTestActor {
case class Add(value: Int)
case object Size
case object Success
}
class GlobalTransactionVectorTestActor extends Actor {
import GlobalTransactionVectorTestActor._
2010-05-24 12:31:04 +02:00
import se.scalablesolutions.akka.stm.Transaction.Global
private var vector: TransactionalVector[Int] = Global.atomic { TransactionalVector(1) }
def receive = {
case Add(value) =>
Global.atomic { vector + value}
self.reply(Success)
2010-05-24 12:31:04 +02:00
case Size =>
val size = Global.atomic { vector.size }
self.reply(size)
}
}