#22035 Make it possible to use anything as the key in a map
- All Map types are now generic in their key: ORMap, ORMultiMap, LWWMap, PNCounterMap - test for binary compatibility with previous version for serialization - entries are sorted for deterministic SHA-1 on same value
This commit is contained in:
parent
5c79b81e92
commit
8499ff6faf
28 changed files with 2231 additions and 584 deletions
|
|
@ -3,24 +3,16 @@
|
|||
*/
|
||||
package akka.cluster.ddata.protobuf
|
||||
|
||||
import java.util.Base64
|
||||
|
||||
import org.scalatest.BeforeAndAfterAll
|
||||
import org.scalatest.Matchers
|
||||
import org.scalatest.WordSpecLike
|
||||
import akka.actor.ActorSystem
|
||||
import akka.actor.Address
|
||||
import akka.actor.ExtendedActorSystem
|
||||
import akka.cluster.ddata.Flag
|
||||
import akka.cluster.ddata.GCounter
|
||||
import akka.cluster.ddata.GSet
|
||||
import akka.cluster.ddata.LWWMap
|
||||
import akka.cluster.ddata.LWWRegister
|
||||
import akka.cluster.ddata.ORMap
|
||||
import akka.cluster.ddata.ORMultiMap
|
||||
import akka.cluster.ddata.ORSet
|
||||
import akka.cluster.ddata.PNCounter
|
||||
import akka.cluster.ddata.PNCounterMap
|
||||
import akka.cluster.ddata._
|
||||
import akka.cluster.ddata.Replicator.Internal._
|
||||
import akka.cluster.ddata.VersionVector
|
||||
import akka.testkit.TestKit
|
||||
import akka.cluster.UniqueAddress
|
||||
import akka.remote.RARP
|
||||
|
|
@ -46,6 +38,17 @@ class ReplicatedDataSerializerSpec extends TestKit(ActorSystem(
|
|||
shutdown()
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a blob created with the previous serializer (with only string keys for maps). If we deserialize it and then
|
||||
* serialize it again and arive at the same BLOB we can assume that we are compatible in both directions.
|
||||
*/
|
||||
def checkCompatibility(oldBlobAsBase64: String, obj: AnyRef): Unit = {
|
||||
val oldBlob = Base64.getDecoder.decode(oldBlobAsBase64)
|
||||
val deserialized = serializer.fromBinary(oldBlob, serializer.manifest(obj))
|
||||
val newBlob = serializer.toBinary(deserialized)
|
||||
newBlob should equal(oldBlob)
|
||||
}
|
||||
|
||||
def checkSerialization(obj: AnyRef): Unit = {
|
||||
val blob = serializer.toBinary(obj)
|
||||
val ref = serializer.fromBinary(blob, serializer.manifest(obj))
|
||||
|
|
@ -140,38 +143,73 @@ class ReplicatedDataSerializerSpec extends TestKit(ActorSystem(
|
|||
}
|
||||
|
||||
"serialize ORMap" in {
|
||||
checkSerialization(ORMap())
|
||||
checkSerialization(ORMap().put(address1, "a", GSet() + "A"))
|
||||
checkSerialization(ORMap().put(address1, "a", GSet() + "A").put(address2, "b", GSet() + "B"))
|
||||
checkSerialization(ORMap().put(address1, 1, GSet() + "A"))
|
||||
checkSerialization(ORMap().put(address1, 1L, GSet() + "A"))
|
||||
// use Flag for this test as object key because it is serializable
|
||||
checkSerialization(ORMap().put(address1, Flag(), GSet() + "A"))
|
||||
}
|
||||
|
||||
"be compatible with old ORMap serialization" in {
|
||||
// Below blob was created with previous version of the serializer
|
||||
val oldBlobAsBase64 = "H4sIAAAAAAAAAOOax8jlyaXMJc8lzMWXX5KRWqSXkV9copdflC7wXEWUiYGBQRaIGQQkuJS45LiEuHiL83NTUdQwwtWIC6kQpUqVKAulGBOlGJOE+LkYE4W4uJi5GB0FuJUYnUACSRABJ7AAAOLO3C3DAAAA"
|
||||
checkCompatibility(oldBlobAsBase64, ORMap())
|
||||
}
|
||||
|
||||
"serialize LWWMap" in {
|
||||
checkSerialization(LWWMap())
|
||||
checkSerialization(LWWMap().put(address1, "a", "value1", LWWRegister.defaultClock[Any]))
|
||||
checkSerialization(LWWMap().put(address1, 1, "value1", LWWRegister.defaultClock[Any]))
|
||||
checkSerialization(LWWMap().put(address1, 1L, "value1", LWWRegister.defaultClock[Any]))
|
||||
checkSerialization(LWWMap().put(address1, Flag(), "value1", LWWRegister.defaultClock[Any]))
|
||||
checkSerialization(LWWMap().put(address1, "a", "value1", LWWRegister.defaultClock[Any])
|
||||
.put(address2, "b", 17, LWWRegister.defaultClock[Any]))
|
||||
}
|
||||
|
||||
"be compatible with old LWWMap serialization" in {
|
||||
// Below blob was created with previous version of the serializer
|
||||
val oldBlobAsBase64 = "H4sIAAAAAAAAAOPy51LhUuKS4xLi4i3Oz03Vy8gvLtHLL0oXeK4iysjAwCALxAwC0kJEqZJiTBSy5wISVhwzrl2fuyRMiIAWKUEu3jVvGVhLGNjKEnNKUw0FGAG1K/3VkgAAAA=="
|
||||
checkCompatibility(oldBlobAsBase64, LWWMap())
|
||||
}
|
||||
|
||||
"serialize PNCounterMap" in {
|
||||
checkSerialization(PNCounterMap())
|
||||
checkSerialization(PNCounterMap().increment(address1, "a", 3))
|
||||
checkSerialization(PNCounterMap().increment(address1, 1, 3))
|
||||
checkSerialization(PNCounterMap().increment(address1, 1L, 3))
|
||||
checkSerialization(PNCounterMap().increment(address1, Flag(), 3))
|
||||
checkSerialization(PNCounterMap().increment(address1, "a", 3).decrement(address2, "a", 2).
|
||||
increment(address2, "b", 5))
|
||||
}
|
||||
|
||||
"be compatible with old PNCounterMap serialization" in {
|
||||
// Below blob was created with previous version of the serializer
|
||||
val oldBlobAsBase64 = "H4sIAAAAAAAAAOPy51LhUuKS4xLi4i3Oz03Vy8gvLtHLL0oXeK4iysjAwCALxAwC8kJEqZJiTBTS4wISmlyqXMqE1AsxMgsxAADYQs/9gQAAAA=="
|
||||
checkCompatibility(oldBlobAsBase64, PNCounterMap())
|
||||
}
|
||||
|
||||
"serialize ORMultiMap" in {
|
||||
checkSerialization(ORMultiMap())
|
||||
checkSerialization(ORMultiMap().addBinding(address1, "a", "A"))
|
||||
checkSerialization(ORMultiMap.empty[String]
|
||||
checkSerialization(ORMultiMap().addBinding(address1, 1, "A"))
|
||||
checkSerialization(ORMultiMap().addBinding(address1, 1L, "A"))
|
||||
checkSerialization(ORMultiMap().addBinding(address1, Flag(), "A"))
|
||||
checkSerialization(ORMultiMap.empty[String, String]
|
||||
.addBinding(address1, "a", "A1")
|
||||
.put(address2, "b", Set("B1", "B2", "B3"))
|
||||
.addBinding(address2, "a", "A2"))
|
||||
|
||||
val m1 = ORMultiMap.empty[String].addBinding(address1, "a", "A1").addBinding(address2, "a", "A2")
|
||||
val m2 = ORMultiMap.empty[String].put(address2, "b", Set("B1", "B2", "B3"))
|
||||
val m1 = ORMultiMap.empty[String, String].addBinding(address1, "a", "A1").addBinding(address2, "a", "A2")
|
||||
val m2 = ORMultiMap.empty[String, String].put(address2, "b", Set("B1", "B2", "B3"))
|
||||
checkSameContent(m1.merge(m2), m2.merge(m1))
|
||||
}
|
||||
|
||||
"be compatible with old ORMultiMap serialization" in {
|
||||
// Below blob was created with previous version of the serializer
|
||||
val oldBlobAsBase64 = "H4sIAAAAAAAAAOPy51LhUuKS4xLi4i3Oz03Vy8gvLtHLL0oXeK4iysjAwCALxAwCakJEqZJiTBQK4QISxJmqSpSpqlKMjgDlsHjDpwAAAA=="
|
||||
checkCompatibility(oldBlobAsBase64, ORMultiMap())
|
||||
}
|
||||
|
||||
"serialize DeletedData" in {
|
||||
checkSerialization(DeletedData)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue