Permalink
Browse files

Refactoring to the scala-concurrent-tck.scala

  - there were numerous logical issues with the former implementation
    - failed assertions may not fail the build
  - there was a lot of ceremony and noise
  • Loading branch information...
1 parent da54f34 commit d2c5324cfdc5a06a848d7001963a3f465e34beb8 @viktorklang viktorklang committed Jun 19, 2013
Showing with 153 additions and 409 deletions.
  1. +153 −409 test/files/jvm/scala-concurrent-tck.scala
View
562 test/files/jvm/scala-concurrent-tck.scala
@@ -15,21 +15,17 @@ import scala.reflect.{ classTag, ClassTag }
import scala.tools.partest.TestUtil.intercept
trait TestBase {
-
- def once(body: (() => Unit) => Unit) {
- val sv = new SyncVar[Boolean]
- body(() => sv put true)
- sv.take(2000)
+ trait Done { def apply(proof: => Boolean): Unit }
+ def once(body: Done => Unit) {
+ import java.util.concurrent.{ LinkedBlockingQueue, TimeUnit }
+ val q = new LinkedBlockingQueue[Try[Boolean]]
+ body(new Done {
+ def apply(proof: => Boolean): Unit = q offer Try(proof)
+ })
+ assert(q.poll(2000, TimeUnit.MILLISECONDS).get)
+ // Check that we don't get more than one completion
+ assert(q.poll(50, TimeUnit.MILLISECONDS) eq null)
}
-
- // def assert(cond: => Boolean) {
- // try {
- // Predef.assert(cond)
- // } catch {
- // case e => e.printStackTrace()
- // }
- // }
-
}
@@ -39,99 +35,52 @@ trait FutureCallbacks extends TestBase {
def testOnSuccess(): Unit = once {
done =>
var x = 0
- val f = future {
- x = 1
- }
- f onSuccess {
- case _ =>
- done()
- assert(x == 1)
- }
+ val f = future { x = 1 }
+ f onSuccess { case _ => done(x == 1) }
}
def testOnSuccessWhenCompleted(): Unit = once {
done =>
var x = 0
- val f = future {
- x = 1
- }
+ val f = future { x = 1 }
f onSuccess {
- case _ =>
- assert(x == 1)
+ case _ if x == 1 =>
x = 2
- f onSuccess {
- case _ =>
- assert(x == 2)
- done()
- }
+ f onSuccess { case _ => done(x == 2) }
}
}
def testOnSuccessWhenFailed(): Unit = once {
done =>
- val f = future[Unit] {
- done()
- throw new Exception
- }
- f onSuccess {
- case _ => assert(false)
- }
+ val f = future[Unit] { throw new Exception }
+ f onSuccess { case _ => done(false) }
+ f onFailure { case _ => done(true) }
}
def testOnFailure(): Unit = once {
done =>
- var x = 0
- val f = future[Unit] {
- x = 1
- throw new Exception
- }
- f onSuccess {
- case _ =>
- done()
- assert(false)
- }
- f onFailure {
- case _ =>
- done()
- assert(x == 1)
- }
+ val f = future[Unit] { throw new Exception }
+ f onSuccess { case _ => done(false) }
+ f onFailure { case _ => done(true) }
}
def testOnFailureWhenSpecialThrowable(num: Int, cause: Throwable): Unit = once {
done =>
- val f = future[Unit] {
- throw cause
- }
- f onSuccess {
- case _ =>
- done()
- assert(false)
- }
+ val f = future[Unit] { throw cause }
+ f onSuccess { case _ => done(false) }
f onFailure {
- case e: ExecutionException if (e.getCause == cause) =>
- done()
- case _ =>
- done()
- assert(false)
+ case e: ExecutionException if e.getCause == cause => done(true)
+ case _ => done(false)
}
}
def testOnFailureWhenTimeoutException(): Unit = once {
done =>
- val f = future[Unit] {
- throw new TimeoutException()
- }
- f onSuccess {
- case _ =>
- done()
- assert(false)
- }
+ val f = future[Unit] { throw new TimeoutException() }
+ f onSuccess { case _ => done(false) }
f onFailure {
- case e: TimeoutException =>
- done()
- case other =>
- done()
- assert(false)
+ case e: TimeoutException => done(true)
+ case _ => done(false)
}
}
@@ -151,7 +100,6 @@ trait FutureCallbacks extends TestBase {
//testOnFailureWhenSpecialThrowable(7, new InterruptedException)
testThatNestedCallbacksDoNotYieldStackOverflow()
testOnFailureWhenTimeoutException()
-
}
@@ -162,207 +110,120 @@ trait FutureCombinators extends TestBase {
done =>
val f = future { 5 }
val g = f map { x => "result: " + x }
- g onSuccess {
- case s =>
- done()
- assert(s == "result: 5")
- }
- g onFailure {
- case _ =>
- done()
- assert(false)
- }
+ g onSuccess { case s => done(s == "result: 5") }
+ g onFailure { case _ => done(false) }
}
def testMapFailure(): Unit = once {
done =>
- val f = future {
- throw new Exception("exception message")
- }
+ val f = future[Unit] { throw new Exception("exception message") }
val g = f map { x => "result: " + x }
- g onSuccess {
- case _ =>
- done()
- assert(false)
- }
- g onFailure {
- case t =>
- done()
- assert(t.getMessage() == "exception message")
- }
+ g onSuccess { case _ => done(false) }
+ g onFailure { case t => done(t.getMessage() == "exception message") }
}
def testMapSuccessPF(): Unit = once {
done =>
val f = future { 5 }
val g = f map { case r => "result: " + r }
- g onSuccess {
- case s =>
- done()
- assert(s == "result: 5")
- }
- g onFailure {
- case _ =>
- done()
- assert(false)
- }
+ g onSuccess { case s => done(s == "result: 5") }
+ g onFailure { case _ => done(false) }
}
def testTransformSuccess(): Unit = once {
done =>
val f = future { 5 }
val g = f.transform(r => "result: " + r, identity)
- g onSuccess {
- case s =>
- done()
- assert(s == "result: 5")
- }
- g onFailure {
- case _ =>
- done()
- assert(false)
- }
+ g onSuccess { case s => done(s == "result: 5") }
+ g onFailure { case _ => done(false) }
}
def testTransformSuccessPF(): Unit = once {
done =>
val f = future { 5 }
val g = f.transform( { case r => "result: " + r }, identity)
- g onSuccess {
- case s =>
- done()
- assert(s == "result: 5")
- }
- g onFailure {
- case _ =>
- done()
- assert(false)
- }
+ g onSuccess { case s => done(s == "result: 5") }
+ g onFailure { case _ => done(false) }
+ }
+
+def testTransformFailure(): Unit = once {
+ done =>
+ val transformed = new Exception("transformed")
+ val f = future { throw new Exception("expected") }
+ val g = f.transform(identity, _ => transformed)
+ g onSuccess { case _ => done(false) }
+ g onFailure { case e => done(e eq transformed) }
+ }
+
+ def testTransformFailurePF(): Unit = once {
+ done =>
+ val e = new Exception("expected")
+ val transformed = new Exception("transformed")
+ val f = future[Unit] { throw e }
+ val g = f.transform(identity, { case `e` => transformed })
+ g onSuccess { case _ => done(false) }
+ g onFailure { case e => done(e eq transformed) }
}
def testFoldFailure(): Unit = once {
done =>
- val f = future {
- throw new Exception("exception message")
- }
+ val f = future[Unit] { throw new Exception("expected") }
val g = f.transform(r => "result: " + r, identity)
- g onSuccess {
- case _ =>
- done()
- assert(false)
- }
- g onFailure {
- case t =>
- done()
- assert(t.getMessage() == "exception message")
- }
+ g onSuccess { case _ => done(false) }
+ g onFailure { case t => done(t.getMessage() == "expected") }
}
def testFlatMapSuccess(): Unit = once {
done =>
val f = future { 5 }
val g = f flatMap { _ => future { 10 } }
- g onSuccess {
- case x =>
- done()
- assert(x == 10)
- }
- g onFailure {
- case _ =>
- done()
- assert(false)
- }
+ g onSuccess { case x => done(x == 10) }
+ g onFailure { case _ => done(false) }
}
def testFlatMapFailure(): Unit = once {
done =>
- val f = future {
- throw new Exception("exception message")
- }
+ val f = future[Unit] { throw new Exception("expected") }
val g = f flatMap { _ => future { 10 } }
- g onSuccess {
- case _ =>
- done()
- assert(false)
- }
- g onFailure {
- case t =>
- done()
- assert(t.getMessage() == "exception message")
- }
+ g onSuccess { case _ => done(false) }
+ g onFailure { case t => done(t.getMessage() == "expected") }
}
def testFilterSuccess(): Unit = once {
done =>
val f = future { 4 }
val g = f filter { _ % 2 == 0 }
- g onSuccess {
- case x: Int =>
- done()
- assert(x == 4)
- }
- g onFailure {
- case _ =>
- done()
- assert(false)
- }
+ g onSuccess { case x: Int => done(x == 4) }
+ g onFailure { case _ => done(false) }
}
def testFilterFailure(): Unit = once {
done =>
val f = future { 4 }
val g = f filter { _ % 2 == 1 }
- g onSuccess {
- case x: Int =>
- done()
- assert(false)
- }
+ g onSuccess { case x: Int => done(false) }
g onFailure {
- case e: NoSuchElementException =>
- done()
- assert(true)
- case _ =>
- done()
- assert(false)
+ case e: NoSuchElementException => done(true)
+ case _ => done(false)
}
}
def testCollectSuccess(): Unit = once {
done =>
val f = future { -5 }
- val g = f collect {
- case x if x < 0 => -x
- }
- g onSuccess {
- case x: Int =>
- done()
- assert(x == 5)
- }
- g onFailure {
- case _ =>
- done()
- assert(false)
- }
+ val g = f collect { case x if x < 0 => -x }
+ g onSuccess { case x: Int => done(x == 5) }
+ g onFailure { case _ => done(false) }
}
def testCollectFailure(): Unit = once {
done =>
val f = future { -5 }
- val g = f collect {
- case x if x > 0 => x * 2
- }
- g onSuccess {
- case _ =>
- done()
- assert(false)
- }
+ val g = f collect { case x if x > 0 => x * 2 }
+ g onSuccess { case _ => done(false) }
g onFailure {
- case e: NoSuchElementException =>
- done()
- assert(true)
- case _ =>
- done()
- assert(false)
+ case e: NoSuchElementException => done(true)
+ case _ => done(false)
}
}
@@ -376,16 +237,8 @@ trait FutureCombinators extends TestBase {
f foreach { x => p.success(x * 2) }
val g = p.future
- g.onSuccess {
- case res: Int =>
- done()
- assert(res == 10)
- }
- g.onFailure {
- case _ =>
- done()
- assert(false)
- }
+ g.onSuccess { case res: Int => done(res == 10) }
+ g.onFailure { case _ => done(false) }
}
def testForeachFailure(): Unit = once {
@@ -396,16 +249,8 @@ trait FutureCombinators extends TestBase {
f onFailure { case _ => p.failure(new Exception) }
val g = p.future
- g.onSuccess {
- case _ =>
- done()
- assert(false)
- }
- g.onFailure {
- case _ =>
- done()
- assert(true)
- }
+ g.onSuccess { case _ => done(false) }
+ g.onFailure { case _ => done(true) }
}
def testRecoverSuccess(): Unit = once {
@@ -415,18 +260,9 @@ trait FutureCombinators extends TestBase {
throw cause
} recover {
case re: RuntimeException =>
- "recovered"
- }
- f onSuccess {
- case x =>
- done()
- assert(x == "recovered")
- }
- f onFailure { case any =>
- done()
- assert(false)
- }
- f
+ "recovered" }
+ f onSuccess { case x => done(x == "recovered") }
+ f onFailure { case any => done(false) }
}
def testRecoverFailure(): Unit = once {
@@ -437,15 +273,8 @@ trait FutureCombinators extends TestBase {
} recover {
case te: TimeoutException => "timeout"
}
- f onSuccess {
- case x =>
- done()
- assert(false)
- }
- f onFailure { case any =>
- done()
- assert(any == cause)
- }
+ f onSuccess { case _ => done(false) }
+ f onFailure { case any => done(any == cause) }
}
def testRecoverWithSuccess(): Unit = once {
@@ -457,15 +286,8 @@ trait FutureCombinators extends TestBase {
case re: RuntimeException =>
future { "recovered" }
}
- f onSuccess {
- case x =>
- done()
- assert(x == "recovered")
- }
- f onFailure { case any =>
- done()
- assert(false)
- }
+ f onSuccess { case x => done(x == "recovered") }
+ f onFailure { case any => done(false) }
}
def testRecoverWithFailure(): Unit = once {
@@ -477,86 +299,46 @@ trait FutureCombinators extends TestBase {
case te: TimeoutException =>
future { "timeout" }
}
- f onSuccess {
- case x =>
- done()
- assert(false)
- }
- f onFailure { case any =>
- done()
- assert(any == cause)
- }
+ f onSuccess { case x => done(false) }
+ f onFailure { case any => done(any == cause) }
}
def testZipSuccess(): Unit = once {
done =>
val f = future { 5 }
val g = future { 6 }
val h = f zip g
- h onSuccess {
- case (l: Int, r: Int) =>
- done()
- assert(l+r == 11)
- }
- h onFailure {
- case _ =>
- done()
- assert(false)
- }
+ h onSuccess { case (l: Int, r: Int) => done(l+r == 11) }
+ h onFailure { case _ => done(false) }
}
def testZipFailureLeft(): Unit = once {
done =>
- val cause = new Exception("exception message")
+ val cause = new Exception("expected")
val f = future { throw cause }
val g = future { 6 }
val h = f zip g
- h onSuccess {
- case _ =>
- done()
- assert(false)
- }
- h onFailure {
- case e: Exception =>
- done()
- assert(e.getMessage == "exception message")
- }
+ h onSuccess { case _ => done(false) }
+ h onFailure { case e: Exception => done(e.getMessage == "expected") }
}
def testZipFailureRight(): Unit = once {
done =>
- val cause = new Exception("exception message")
+ val cause = new Exception("expected")
val f = future { 5 }
val g = future { throw cause }
val h = f zip g
- h onSuccess {
- case _ =>
- done()
- assert(false)
- }
- h onFailure {
- case e: Exception =>
- done()
- assert(e.getMessage == "exception message")
- }
+ h onSuccess { case _ => done(false) }
+ h onFailure { case e: Exception => done(e.getMessage == "expected") }
}
def testFallbackTo(): Unit = once {
done =>
val f = future { sys.error("failed") }
val g = future { 5 }
val h = f fallbackTo g
-
- h onSuccess {
- case x: Int =>
- done()
- assert(x == 5)
- }
- h onFailure {
- case _ =>
- done()
- assert(false)
- }
+ h onSuccess { case x: Int => done(x == 5) }
+ h onFailure { case _ => done(false) }
}
def testFallbackToFailure(): Unit = once {
@@ -566,16 +348,8 @@ trait FutureCombinators extends TestBase {
val g = future { throw cause }
val h = f fallbackTo g
- h onSuccess {
- case _ =>
- done()
- assert(false)
- }
- h onFailure {
- case e: Exception =>
- done()
- assert(e == cause)
- }
+ h onSuccess { case _ => done(false) }
+ h onFailure { case e => done(e eq cause) }
}
testMapSuccess()
@@ -597,6 +371,8 @@ trait FutureCombinators extends TestBase {
testZipFailureRight()
testFallbackTo()
testFallbackToFailure()
+ testTransformSuccess()
+ testTransformSuccessPF()
}
@@ -606,70 +382,55 @@ trait FutureProjections extends TestBase {
def testFailedFailureOnComplete(): Unit = once {
done =>
val cause = new RuntimeException
- val f = future {
- throw cause
- }
+ val f = future { throw cause }
f.failed onComplete {
- case Success(t) =>
- assert(t == cause)
- done()
- case Failure(t) =>
- assert(false)
+ case Success(t) => done(t == cause)
+ case Failure(t) => done(false)
}
}
def testFailedFailureOnSuccess(): Unit = once {
done =>
val cause = new RuntimeException
- val f = future {
- throw cause
- }
- f.failed onSuccess {
- case t =>
- assert(t == cause)
- done()
- }
+ val f = future { throw cause }
+ f.failed onSuccess { case t => done(t == cause) }
}
def testFailedSuccessOnComplete(): Unit = once {
done =>
val f = future { 0 }
f.failed onComplete {
- case Success(t) =>
- assert(false)
- case Failure(t) =>
- assert(t.isInstanceOf[NoSuchElementException])
- done()
+ case Failure(_: NoSuchElementException) => done(true)
+ case _ => done(false)
}
}
def testFailedSuccessOnFailure(): Unit = once {
done =>
val f = future { 0 }
f.failed onFailure {
- case nsee: NoSuchElementException =>
- done()
+ case e: NoSuchElementException => done(true)
+ case _ => done(false)
}
+ f.failed onSuccess { case _ => done(false) }
}
def testFailedFailureAwait(): Unit = once {
done =>
val cause = new RuntimeException
- val f = future {
- throw cause
- }
- assert(Await.result(f.failed, Duration(500, "ms")) == cause)
- done()
+ val f = future { throw cause }
+ done(Await.result(f.failed, Duration(500, "ms")) == cause)
}
def testFailedSuccessAwait(): Unit = once {
done =>
val f = future { 0 }
try {
Await.result(f.failed, Duration(500, "ms"))
- assert(false)
+ done(false)
} catch {
- case nsee: NoSuchElementException => done()
+ case nsee: NoSuchElementException => done(true)
+ case _: Throwable => done(false)
}
}
@@ -682,8 +443,8 @@ trait FutureProjections extends TestBase {
Await.ready(f, Duration.Zero)
Await.ready(f, Duration(500, "ms"))
Await.ready(f, Duration.Inf)
- done()
- } onFailure { case x => throw x }
+ done(true)
+ } onFailure { case x => done(throw x) }
}
def testAwaitNegativeDuration(): Unit = once { done =>
@@ -692,8 +453,8 @@ trait FutureProjections extends TestBase {
intercept[TimeoutException] { Await.ready(f, Duration.Zero) }
intercept[TimeoutException] { Await.ready(f, Duration.MinusInf) }
intercept[TimeoutException] { Await.ready(f, Duration(-500, "ms")) }
- done()
- } onFailure { case x => throw x }
+ done(true)
+ } onFailure { case x => done(throw x) }
}
testFailedFailureOnComplete()
@@ -704,7 +465,6 @@ trait FutureProjections extends TestBase {
testFailedSuccessAwait()
testAwaitPositiveDuration()
testAwaitNegativeDuration()
-
}
@@ -714,33 +474,25 @@ trait Blocking extends TestBase {
def testAwaitSuccess(): Unit = once {
done =>
val f = future { 0 }
- Await.result(f, Duration(500, "ms"))
- done()
+ done(Await.result(f, Duration(500, "ms")) == 0)
}
def testAwaitFailure(): Unit = once {
done =>
val cause = new RuntimeException
- val f = future {
- throw cause
- }
+ val f = future { throw cause }
try {
Await.result(f, Duration(500, "ms"))
- assert(false)
+ done(false)
} catch {
- case t =>
- assert(t == cause)
- done()
+ case t: Throwable => done(t == cause)
}
}
def testFQCNForAwaitAPI(): Unit = once {
done =>
-
- assert(classOf[CanAwait].getName == "scala.concurrent.CanAwait")
- assert(Await.getClass.getName == "scala.concurrent.Await")
-
- done()
+ done(classOf[CanAwait].getName == "scala.concurrent.CanAwait" &&
+ Await.getClass.getName == "scala.concurrent.Await")
}
testAwaitSuccess()
@@ -813,22 +565,26 @@ trait Promises extends TestBase {
val p = promise[Int]()
val f = p.future
- f onSuccess {
- case x =>
- done()
- assert(x == 5)
- }
- f onFailure {
- case any =>
- done()
- assert(false)
- }
+ f onSuccess { case x => done(x == 5) }
+ f onFailure { case any => done(false) }
p.success(5)
}
- testSuccess()
+ def testFailure(): Unit = once {
+ done =>
+ val e = new Exception("expected")
+ val p = promise[Int]()
+ val f = p.future
+
+ f onSuccess { case x => done(false) }
+ f onFailure { case any => done(any eq e) }
+
+ p.failure(e)
+ }
+ testSuccess()
+ testFailure()
}
@@ -888,11 +644,11 @@ trait CustomExecutionContext extends TestBase {
val count = countExecs { implicit ec =>
blocking {
once { done =>
- val f = future({ assertNoEC() })(defaultEC)
+ val f = future(assertNoEC())(defaultEC)
f onSuccess {
case _ =>
assertEC()
- done()
+ done(true)
}
assertNoEC()
}
@@ -911,7 +667,7 @@ trait CustomExecutionContext extends TestBase {
f onSuccess {
case _ =>
assertEC()
- done()
+ done(true)
}
}
}
@@ -935,15 +691,10 @@ trait CustomExecutionContext extends TestBase {
Promise.successful(x + 1).future.map(addOne).map(addOne)
} onComplete {
case Failure(t) =>
- try {
- throw new AssertionError("error in test: " + t.getMessage, t)
- } finally {
- done()
- }
+ done(throw new AssertionError("error in test: " + t.getMessage, t))
case Success(x) =>
assertEC()
- assert(x == 14)
- done()
+ done(x == 14)
}
assertNoEC()
}
@@ -999,21 +750,14 @@ trait ExecutionContextPrepare extends TestBase {
done =>
theLocal.set("secret")
val fut = future { 42 }
- fut onComplete {
- case _ =>
- assert(theLocal.get == "secret")
- done()
- }
+ fut onComplete { case _ => done(theLocal.get == "secret") }
}
def testMap(): Unit = once {
done =>
theLocal.set("secret2")
val fut = future { 42 }
- fut map { x =>
- assert(theLocal.get == "secret2")
- done()
- }
+ fut map { x => done(theLocal.get == "secret2") }
}
testOnComplete()

0 comments on commit d2c5324

Please sign in to comment.