I posted this in the Scalatest discussion list, but I don’t think it’s much alive. Maybe someone here can hep me.
I’m trying to rewrite some FunSuite
tests I have using AsyncFunSuite
and I have a few questions.
Suppose I want to test an object for thread-safety (an atomic integer in my example):
test("a single-thread future test") {
val n = 32
val range = 1 to n
val shared = new AtomicInteger()
val f = Future.traverse(range)(_ => Future(shared.incrementAndGet()))
for (l <- f) yield {
assert(shared.get === n)
assert(l.toSet === range.toSet)
}
}
Given the default behavior of Async, this only tests my atomic integer using a single thread, which is not very exciting. I can write a more interesting test like this:
test("a multi-threaded future test") {
implicit val exec: ExecutionContextExecutorService =
ExecutionContext.fromExecutorService(Executors.newCachedThreadPool)
val n = 32
val range = 1 to n
val shared = new AtomicInteger()
val ready = new CountDownLatch(n)
val f = Future.traverse(range) { _ =>
Future {
ready.countDown()
ready.await()
shared.incrementAndGet()
}
}
for (l <- f) yield {
exec.shutdown()
assert(shared.get === n)
assert(l.toSet === range.toSet)
}
}
(I’m not overriding the default executor because I envision different executors for different tests.)
My questions:
-
(this is more of a general Scala question) I cannot have an implicit exec of type
ExecutionContext
inside the test because it leads to ambiguous implicit resolution. Shouldn’t an implicit in a narrower scope shadow the other one? What’s the workaround? -
My test looks just like it did before, with all the concurrency setting done by hand. Does
AsyncFunSuite
offer useful mechanisms for that, which I missed? -
If not, the only difference with my previous test in
FunSuite
is that I can omit the line at the end:awaitFutures(timeout)(g)
where
awaitFutures
is a little function I wrote (andg
is the value produced byfor/yield
). Is that it? What am I getting from switching fromFunSuite
toAsyncFunSuite
besides not having to wait for my futures explicitly? Is there a suitable Async style for the kind of concurrency test above? -
My
awaitFutures
lets me specify a timeout. Is that even possible if I useAsyncFunSuite
?
Thanks,
MC