diff options
author | Rex Kerr <ichoran@gmail.com> | 2015-02-18 18:52:46 -0800 |
---|---|---|
committer | Rex Kerr <ichoran@gmail.com> | 2015-02-20 00:07:44 -0800 |
commit | 1d4a1f721d360c73b9f2468368c7e9b2b4c17fea (patch) | |
tree | 9cd0a2db1374c03934adde0483f43dd96cac235a /test/junit | |
parent | 18870094f2464e39067baeea71c4ae7ab8dfc6d9 (diff) | |
download | scala-1d4a1f721d360c73b9f2468368c7e9b2b4c17fea.tar.gz scala-1d4a1f721d360c73b9f2468368c7e9b2b4c17fea.tar.bz2 scala-1d4a1f721d360c73b9f2468368c7e9b2b4c17fea.zip |
SI-9126 Missing .seqs causes problems with parallel GenXs
Added `.seq` in two essential places so that a parallel collection passed as an argument won't mess up side-effecting sequential computations in `List.flatMap` and `GenericTraversableTemplate.transpose` (thanks to retronym for finding the danger spots).
Tests that `.seq` is called by constructing a `GenSeq` whose `.seq` disagrees with anything non-`.seq` (idea & working implementation from retronym).
Also updates the `.seq` test for `Vector#++` to use the new more efficient method.
Diffstat (limited to 'test/junit')
-rw-r--r-- | test/junit/scala/collection/ParallelConsistencyTest.scala | 44 | ||||
-rw-r--r-- | test/junit/scala/collection/immutable/VectorTest.scala | 20 |
2 files changed, 44 insertions, 20 deletions
diff --git a/test/junit/scala/collection/ParallelConsistencyTest.scala b/test/junit/scala/collection/ParallelConsistencyTest.scala new file mode 100644 index 0000000000..da96362413 --- /dev/null +++ b/test/junit/scala/collection/ParallelConsistencyTest.scala @@ -0,0 +1,44 @@ +package scala.collection.immutable + +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(classOf[JUnit4]) +class ParallelConsistencyTest { + + private val theSeq = Seq(1,2,3) + + // This collection will throw an exception if you do anything but call .length or .seq + private val mustCallSeq: collection.GenSeq[Int] = new collection.parallel.ParSeq[Int] { + def length = 3 + + // This method is surely sequential & safe -- want all access to go through here + def seq = theSeq + + def notSeq = throw new Exception("Access to parallel collection not via .seq") + + // These methods could possibly be used dangerously explicitly or internally + // (apply could also be used safely; if it is, do test with mustCallSeq) + def apply(i: Int) = notSeq + def splitter = notSeq + } + + // Test Vector ++ with a small parallel collection concatenation (SI-9072). + @Test + def testPlusPlus(): Unit = { + assert((Vector.empty ++ mustCallSeq) == theSeq, "Vector ++ unsafe with parallel vectors") + } + + // SI-9126, 1 of 2 + @Test + def testTranspose(): Unit = { + assert(List(mustCallSeq).transpose.flatten == theSeq, "Transposing inner parallel collection unsafe") + } + + // SI-9126, 2 of 2 + @Test + def testList_flatMap(): Unit = { + assert(List(1).flatMap(_ => mustCallSeq) == theSeq, "List#flatMap on inner parallel collection unsafe") + } +} diff --git a/test/junit/scala/collection/immutable/VectorTest.scala b/test/junit/scala/collection/immutable/VectorTest.scala deleted file mode 100644 index e7edba3e43..0000000000 --- a/test/junit/scala/collection/immutable/VectorTest.scala +++ /dev/null @@ -1,20 +0,0 @@ -package scala.collection.immutable - -import org.junit.{Assert, Test} -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 - -@RunWith(classOf[JUnit4]) -class VectorTest { - /** - * Test Vector ++ with a small parallel collection concatenation (SI-9072). - * - */ - @Test - def testPlusPlus(): Unit = { - val smallVec = (0 to 1) - val smallParVec = smallVec.par - val testElementsSize = (0 to 1000).map( _ => Vector.empty ++ smallParVec ) - Assert.assertTrue(testElementsSize.forall( v => v.size == 2 )) - } -} |