diff options
Diffstat (limited to 'test/files')
-rw-r--r-- | test/files/jvm/serialization.check | 6 | ||||
-rw-r--r-- | test/files/jvm/t1600.scala | 76 |
2 files changed, 79 insertions, 3 deletions
diff --git a/test/files/jvm/serialization.check b/test/files/jvm/serialization.check index f1b5b10ec6..2b0ad3888b 100644 --- a/test/files/jvm/serialization.check +++ b/test/files/jvm/serialization.check @@ -78,11 +78,11 @@ y = BitSet(2, 3) x equals y: true, y equals x: true x = Map(2 -> B, 1 -> A, 3 -> C) -y = Map(2 -> B, 1 -> A, 3 -> C) +y = Map(1 -> A, 2 -> B, 3 -> C) x equals y: true, y equals x: true x = Set(1, 2) -y = Set(1, 2) +y = Set(2, 1) x equals y: true, y equals x: true x = List((buffers,20), (layers,2), (title,3)) @@ -158,7 +158,7 @@ y = BitSet(0, 8, 9) x equals y: true, y equals x: true x = Map(A -> 1, C -> 3, B -> 2) -y = Map(A -> 1, C -> 3, B -> 2) +y = Map(B -> 2, C -> 3, A -> 1) x equals y: true, y equals x: true x = Set(layers, buffers, title) diff --git a/test/files/jvm/t1600.scala b/test/files/jvm/t1600.scala new file mode 100644 index 0000000000..1cdcee8547 --- /dev/null +++ b/test/files/jvm/t1600.scala @@ -0,0 +1,76 @@ + +/** + * Checks that serialization of hash-based collections works correctly if the hashCode + * changes on deserialization. + */ +object Test { + + import collection._ + def main(args: Array[String]) { + for (i <- Seq(0, 1, 2, 10, 100)) { + def entries = (0 until i).map(i => (new Foo, i)).toList + def elements = entries.map(_._1) + + val maps = Seq[Map[Foo, Int]](new mutable.HashMap, new mutable.LinkedHashMap, + new immutable.HashMap).map(_ ++ entries) + test[Map[Foo, Int]](maps, entries.size, assertMap _) + + val sets = Seq[Set[Foo]](new mutable.HashSet, new mutable.LinkedHashSet, + new immutable.HashSet).map(_ ++ elements) + test[Set[Foo]](sets, entries.size, assertSet _) + } + } + + private def test[A <: AnyRef](collections: Seq[A], expectedSize: Int, assertFunction: (A, Int) => Unit) { + for (collection <- collections) { + assertFunction(collection, expectedSize) + + val bytes = toBytes(collection) + Foo.hashCodeModifier = 1 + val deserializedCollection = toObject[A](bytes) + + assertFunction(deserializedCollection, expectedSize) + assert(deserializedCollection.getClass == collection.getClass, + "collection class should remain the same after deserialization") + Foo.hashCodeModifier = 0 + } + } + + private def toObject[A](bytes: Array[Byte]): A = { + val in = new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(bytes)) + in.readObject.asInstanceOf[A] + } + + private def toBytes(o: AnyRef): Array[Byte] = { + val bos = new java.io.ByteArrayOutputStream + val out = new java.io.ObjectOutputStream(bos) + out.writeObject(o) + out.close + bos.toByteArray + } + + private def assertMap[A, B](map: Map[A, B], expectedSize: Int) { + assert(expectedSize == map.size, "expected map size: " + expectedSize + ", actual size: " + map.size) + map.foreach { case (k, v) => + assert(map.contains(k), "contains should return true for key in the map, key: " + k) + assert(map(k) == v) + } + } + + private def assertSet[A](set: Set[A], expectedSize: Int) { + assert(expectedSize == set.size, "expected set size: " + expectedSize + ", actual size: " + set.size) + set.foreach { e => assert(set.contains(e), "contains should return true for element in the set, element: " + e) } + } + + object Foo { + /* Used to simulate a hashCode change caused by deserializing an instance with an + * identity-based hashCode in another JVM. + */ + var hashCodeModifier = 0 + } + + @serializable + class Foo { + override def hashCode = System.identityHashCode(this) + Foo.hashCodeModifier + } +} |