summaryrefslogtreecommitdiff
path: root/test/files/jvm/t1600.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-12-01 18:28:55 +0000
committerPaul Phillips <paulp@improving.org>2009-12-01 18:28:55 +0000
commita3bf3f136caaefa98268607a3529b7554df5fc80 (patch)
tree220322df1130f864af06661baca1b7f4434ee32d /test/files/jvm/t1600.scala
parentc2359ccec521ed24641fb010774e7b39b4ae62b2 (diff)
downloadscala-a3bf3f136caaefa98268607a3529b7554df5fc80.tar.gz
scala-a3bf3f136caaefa98268607a3529b7554df5fc80.tar.bz2
scala-a3bf3f136caaefa98268607a3529b7554df5fc80.zip
[This patch submitted by ismael juma - commit m...
[This patch submitted by ismael juma - commit message his words, but condensed.] Fix ticket #1600: Serialization and deserialization of hash-based collections should not re-use hashCode. The collection is rebuilt on deserialization - note that this is not compatible with the previous serialization format. All @SerialVersionUIDs have been reset to 1. WeakHashMap is not Serializable and should not be so. TreeHashMap has not been reintegrated yet. OpenHashMap has not been updated. (I think this collection is flawed and should be removed or reimplemented.)
Diffstat (limited to 'test/files/jvm/t1600.scala')
-rw-r--r--test/files/jvm/t1600.scala76
1 files changed, 76 insertions, 0 deletions
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
+ }
+}