CORDA-1530 - Generics break default evolver (#3232)

* CORDA-1530 - Generics break default  evolver

When selecting an annotated constructor for evolving a type make sure
we treat generics in the same manner we did when serialized. Effectively
throw away the template information and treat lists as lists and maps
as maps
This commit is contained in:
Katelyn Baker
2018-05-24 18:30:45 +01:00
committed by GitHub
parent 4e0378de9c
commit ee0d580448
4 changed files with 113 additions and 11 deletions

View File

@ -8,10 +8,7 @@ import net.corda.core.node.NotaryInfo
import net.corda.core.serialization.ConstructorForDeserialization
import net.corda.core.serialization.DeprecatedConstructorForDeserialization
import net.corda.core.serialization.SerializedBytes
import net.corda.serialization.internal.amqp.testutils.TestSerializationOutput
import net.corda.serialization.internal.amqp.testutils.deserialize
import net.corda.serialization.internal.amqp.testutils.serialize
import net.corda.serialization.internal.amqp.testutils.testDefaultFactory
import net.corda.serialization.internal.amqp.testutils.*
import net.corda.testing.common.internal.ProjectStructure.projectRootDir
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.TestIdentity
@ -22,6 +19,7 @@ import java.io.NotSerializableException
import java.net.URI
import java.time.Instant
import kotlin.test.assertEquals
import net.corda.serialization.internal.amqp.custom.InstantSerializer
// To regenerate any of the binary test files do the following
//
@ -202,6 +200,86 @@ class EvolvabilityTests {
assertEquals("hello", deserializedCC.b)
}
@Test
fun addMandatoryFieldWithAltConstructorForceReorder() {
val sf = testDefaultFactory()
val z = 30
val y = 20
val resource = "EvolvabilityTests.addMandatoryFieldWithAltConstructorForceReorder"
// Original version of the class as it was serialised
// data class CC(val z: Int, val y: Int)
// File(URI("$localPath/$resource")).writeBytes(SerializationOutput(sf).serialize(CC(z, y)).bytes)
@Suppress("UNUSED")
data class CC(val z: Int, val y: Int, val a: String) {
@DeprecatedConstructorForDeserialization(1)
constructor (z: Int, y: Int) : this(z, y, "10")
}
val url = EvolvabilityTests::class.java.getResource(resource)
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(url.readBytes()))
assertEquals("10", deserializedCC.a)
assertEquals(y, deserializedCC.y)
assertEquals(z, deserializedCC.z)
}
@Test
fun moreComplexNonNullWithReorder() {
val resource = "${javaClass.simpleName}.${testName()}"
data class NetworkParametersExample(
val minimumPlatformVersion: Int,
val notaries: List<String>,
val maxMessageSize: Int,
val maxTransactionSize: Int,
val modifiedTime: Instant,
val epoch: Int,
val whitelistedContractImplementations: Map<String, List<Int>>,
/* to regenerate test class, comment out this element */
val eventHorizon: Int
) {
// when regenerating test class this won't be required
@DeprecatedConstructorForDeserialization(1)
@Suppress("UNUSED")
constructor (
minimumPlatformVersion: Int,
notaries: List<String>,
maxMessageSize: Int,
maxTransactionSize: Int,
modifiedTime: Instant,
epoch: Int,
whitelistedContractImplementations: Map<String, List<Int>>
) : this(minimumPlatformVersion,
notaries,
maxMessageSize,
maxTransactionSize,
modifiedTime,
epoch,
whitelistedContractImplementations,
Int.MAX_VALUE)
}
val factory = testDefaultFactory().apply {
register(InstantSerializer(this))
}
// Uncomment to regenerate test case
// File(URI("$localPath/$resource")).writeBytes(SerializationOutput(factory).serialize(
// NetworkParametersExample(
// 10,
// listOf("Notary1", "Notary2"),
// 100,
// 10,
// Instant.now(),
// 9,
// mapOf("A" to listOf(1, 2, 3), "B" to listOf (4, 5, 6)))).bytes)
val url = EvolvabilityTests::class.java.getResource(resource)
DeserializationInput(factory).deserialize(SerializedBytes<NetworkParametersExample>(url.readBytes()))
}
@Test(expected = NotSerializableException::class)
@Suppress("UNUSED")
fun addMandatoryFieldWithAltConstructorUnAnnotated() {
@ -479,7 +557,7 @@ class EvolvabilityTests {
//
@Test
@Ignore("Test fails after moving NetworkParameters and NotaryInfo into core from node-api")
fun readBrokenNetworkParameters(){
fun readBrokenNetworkParameters() {
val sf = testDefaultFactory()
sf.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(sf))
sf.register(net.corda.serialization.internal.amqp.custom.PublicKeySerializer)
@ -515,7 +593,7 @@ class EvolvabilityTests {
val resource = "networkParams.<corda version>.<commit sha>"
val DUMMY_NOTARY = TestIdentity(DUMMY_NOTARY_NAME, 20).party
val networkParameters = NetworkParameters(
3, listOf(NotaryInfo(DUMMY_NOTARY, false)),1000, 1000, Instant.EPOCH, 1, emptyMap())
3, listOf(NotaryInfo(DUMMY_NOTARY, false)), 1000, 1000, Instant.EPOCH, 1, emptyMap())
val sf = testDefaultFactory()
sf.register(net.corda.serialization.internal.amqp.custom.InstantSerializer(sf))