mirror of
https://github.com/corda/corda.git
synced 2025-06-17 06:38:21 +00:00
CORDA-553 - Cope with future transforms
This commit is contained in:
@ -57,6 +57,7 @@ data class Envelope(val obj: Any?, val schema: Schema, val transformsSchema: Tra
|
|||||||
ENVELOPE_WITH_TRANSFORMS -> list[TRANSFORMS_SCHEMA_IDX] as TransformsSchema
|
ENVELOPE_WITH_TRANSFORMS -> list[TRANSFORMS_SCHEMA_IDX] as TransformsSchema
|
||||||
else -> throw NotSerializableException("Malformed list, bad length of ${list.size} (should be 2 or 3)")
|
else -> throw NotSerializableException("Malformed list, bad length of ${list.size} (should be 2 or 3)")
|
||||||
}
|
}
|
||||||
|
|
||||||
return Envelope(list[BLOB_IDX], list[SCHEMA_IDX] as Schema, transformSchema)
|
return Envelope(list[BLOB_IDX], list[SCHEMA_IDX] as Schema, transformSchema)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,11 +36,17 @@ private val wrapperExtract = { x: Annotation ->
|
|||||||
*/
|
*/
|
||||||
private val singleExtract = { x: Annotation -> listOf(x) }
|
private val singleExtract = { x: Annotation -> listOf(x) }
|
||||||
|
|
||||||
|
// Transform annotation used to test the handling of transforms the de-serialising node doesn't understand. At
|
||||||
|
// some point test cases will have been created with this transform applied.
|
||||||
|
//@Target(AnnotationTarget.CLASS)
|
||||||
|
//@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
//annotation class UnknownTransformAnnotation(val a: Int, val b: Int, val c: Int)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility list of all transforms we support that simplifies our generation code
|
* Utility list of all transforms we support that simplifies our generation code.
|
||||||
*
|
*
|
||||||
* NOTE: We have to support single instances of the transform annotations as well as the wrapping annotation
|
* NOTE: We have to support single instances of the transform annotations as well as the wrapping annotation
|
||||||
* when many instances are repeated
|
* when many instances are repeated.
|
||||||
*/
|
*/
|
||||||
val supportedTransforms = listOf(
|
val supportedTransforms = listOf(
|
||||||
SupportedTransform(
|
SupportedTransform(
|
||||||
@ -63,4 +69,8 @@ val supportedTransforms = listOf(
|
|||||||
TransformTypes.Rename,
|
TransformTypes.Rename,
|
||||||
singleExtract
|
singleExtract
|
||||||
)
|
)
|
||||||
|
//,SupportedTransform(
|
||||||
|
// UnknownTransformAnnotation::class.java,
|
||||||
|
// TransformTypes.UnknownTest,
|
||||||
|
// singleExtract)
|
||||||
)
|
)
|
||||||
|
@ -14,11 +14,21 @@ import java.io.NotSerializableException
|
|||||||
* @property build should be a function that takes a transform [Annotation] (currently one of
|
* @property build should be a function that takes a transform [Annotation] (currently one of
|
||||||
* [CordaSerializationTransformRename] or [CordaSerializationTransformEnumDefaults])
|
* [CordaSerializationTransformRename] or [CordaSerializationTransformEnumDefaults])
|
||||||
* and constructs an instance of the corresponding [Transform] type
|
* and constructs an instance of the corresponding [Transform] type
|
||||||
|
*
|
||||||
|
* DO NOT REORDER THE CONSTANTS!!! Please append any new entries to the end
|
||||||
*/
|
*/
|
||||||
// TODO: it would be awesome to auto build this list by scanning for transform annotations themselves
|
// TODO: it would be awesome to auto build this list by scanning for transform annotations themselves
|
||||||
// TODO: annotated with some annotation
|
// TODO: annotated with some annotation
|
||||||
enum class TransformTypes(val build: (Annotation) -> Transform) : DescribedType {
|
enum class TransformTypes(val build: (Annotation) -> Transform) : DescribedType {
|
||||||
EnumDefault({ a -> EnumDefaultSchemeTransform((a as CordaSerializationTransformEnumDefault).old, a.new) }) {
|
/**
|
||||||
|
* Placeholder entry for future transforms where a node receives a transform we've subsequently
|
||||||
|
* added and thus the de-serialising node doesn't know about that transform.
|
||||||
|
*/
|
||||||
|
Unknown({ UnknownTransform() }) {
|
||||||
|
override fun getDescriptor(): Any = DESCRIPTOR
|
||||||
|
override fun getDescribed(): Any = ordinal
|
||||||
|
},
|
||||||
|
EnumDefault({ a -> EnumDefaultSchemaTransform((a as CordaSerializationTransformEnumDefault).old, a.new) }) {
|
||||||
override fun getDescriptor(): Any = DESCRIPTOR
|
override fun getDescriptor(): Any = DESCRIPTOR
|
||||||
override fun getDescribed(): Any = ordinal
|
override fun getDescribed(): Any = ordinal
|
||||||
},
|
},
|
||||||
@ -26,6 +36,13 @@ enum class TransformTypes(val build: (Annotation) -> Transform) : DescribedType
|
|||||||
override fun getDescriptor(): Any = DESCRIPTOR
|
override fun getDescriptor(): Any = DESCRIPTOR
|
||||||
override fun getDescribed(): Any = ordinal
|
override fun getDescribed(): Any = ordinal
|
||||||
};
|
};
|
||||||
|
// Transform used to test the unknown handler, leave this at as the final constant, uncomment
|
||||||
|
// when regenerating test cases - if Java had a pre-processor this would be much neater
|
||||||
|
//
|
||||||
|
//UnknownTest({ a -> UnknownTestTransform((a as UnknownTransformAnnotation).a, a.b, a.c)}) {
|
||||||
|
// override fun getDescriptor(): Any = DESCRIPTOR
|
||||||
|
// override fun getDescribed(): Any = ordinal
|
||||||
|
//};
|
||||||
|
|
||||||
companion object : DescribedTypeConstructor<TransformTypes> {
|
companion object : DescribedTypeConstructor<TransformTypes> {
|
||||||
val DESCRIPTOR = AMQPDescriptorRegistry.TRANSFORM_ELEMENT_KEY.amqpDescriptor
|
val DESCRIPTOR = AMQPDescriptorRegistry.TRANSFORM_ELEMENT_KEY.amqpDescriptor
|
||||||
@ -42,10 +59,10 @@ enum class TransformTypes(val build: (Annotation) -> Transform) : DescribedType
|
|||||||
throw NotSerializableException("Unexpected descriptor ${describedType.descriptor}.")
|
throw NotSerializableException("Unexpected descriptor ${describedType.descriptor}.")
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return try {
|
||||||
return values()[describedType.described as Int]
|
values()[describedType.described as Int]
|
||||||
} catch (e: IndexOutOfBoundsException) {
|
} catch (e: IndexOutOfBoundsException) {
|
||||||
throw NotSerializableException("Bad ordinal value ${describedType.described}.")
|
values()[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,15 +37,18 @@ abstract class Transform : DescribedType {
|
|||||||
* the schema as a list of class name and parameters.Using the class name (list element 0)
|
* the schema as a list of class name and parameters.Using the class name (list element 0)
|
||||||
* create the appropriate class instance
|
* create the appropriate class instance
|
||||||
*
|
*
|
||||||
|
* For future proofing any unknown transform types are not treated as errors, rather we
|
||||||
|
* simply create a placeholder object so we can ignore it
|
||||||
|
*
|
||||||
* @param obj: a serialized instance of a described type, should be one of the
|
* @param obj: a serialized instance of a described type, should be one of the
|
||||||
* descendants of this class
|
* descendants of this class
|
||||||
*/
|
*/
|
||||||
override fun newInstance(obj: Any?): Transform {
|
override fun newInstance(obj: Any?): Transform {
|
||||||
val described = Transform.checkDescribed(obj) as List<*>
|
val described = Transform.checkDescribed(obj) as List<*>
|
||||||
return when (described[0]) {
|
return when (described[0]) {
|
||||||
EnumDefaultSchemeTransform.typeName -> EnumDefaultSchemeTransform.newInstance(described)
|
EnumDefaultSchemaTransform.typeName -> EnumDefaultSchemaTransform.newInstance(described)
|
||||||
RenameSchemaTransform.typeName -> RenameSchemaTransform.newInstance(described)
|
RenameSchemaTransform.typeName -> RenameSchemaTransform.newInstance(described)
|
||||||
else -> throw NotSerializableException("Unexpected transform type ${described[0]}")
|
else -> UnknownTransform()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,27 +66,64 @@ abstract class Transform : DescribedType {
|
|||||||
abstract val name: String
|
abstract val name: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform type placeholder that allows for backward compatibility. Should a noce recieve
|
||||||
|
* a transform type it doesn't recognise, we can will use this as a placeholder
|
||||||
|
*/
|
||||||
|
class UnknownTransform : Transform() {
|
||||||
|
companion object : DescribedTypeConstructor<UnknownTransform> {
|
||||||
|
val typeName = "UnknownTransform"
|
||||||
|
|
||||||
|
override fun newInstance(obj: Any?) = UnknownTransform()
|
||||||
|
|
||||||
|
override fun getTypeClass(): Class<*> = UnknownTransform::class.java
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDescribed(): Any = emptyList<Any>()
|
||||||
|
override fun params() = ""
|
||||||
|
|
||||||
|
override val name: String get() = typeName
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnknownTestTransform(val a: Int, val b: Int, val c: Int) : Transform() {
|
||||||
|
companion object : DescribedTypeConstructor<UnknownTestTransform> {
|
||||||
|
val typeName = "UnknownTest"
|
||||||
|
|
||||||
|
override fun newInstance(obj: Any?) : UnknownTestTransform {
|
||||||
|
val described = obj as List<*>
|
||||||
|
return UnknownTestTransform(described[1] as Int, described[2] as Int, described[3] as Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTypeClass(): Class<*> = UnknownTransform::class.java
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDescribed(): Any = listOf(name, a, b, c)
|
||||||
|
override fun params() = ""
|
||||||
|
|
||||||
|
override val name: String get() = typeName
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform to be used on an Enumerated Type whenever a new element is added
|
* Transform to be used on an Enumerated Type whenever a new element is added
|
||||||
*
|
*
|
||||||
* @property old The value the [new] instance should default to when not available
|
* @property old The value the [new] instance should default to when not available
|
||||||
* @property new the value (as a String) that has been added
|
* @property new the value (as a String) that has been added
|
||||||
*/
|
*/
|
||||||
class EnumDefaultSchemeTransform(val old: String, val new: String) : Transform() {
|
class EnumDefaultSchemaTransform(val old: String, val new: String) : Transform() {
|
||||||
companion object : DescribedTypeConstructor<EnumDefaultSchemeTransform> {
|
companion object : DescribedTypeConstructor<EnumDefaultSchemaTransform> {
|
||||||
/**
|
/**
|
||||||
* Value encoded into the schema that identifies a transform as this type
|
* Value encoded into the schema that identifies a transform as this type
|
||||||
*/
|
*/
|
||||||
val typeName = "EnumDefault"
|
val typeName = "EnumDefault"
|
||||||
|
|
||||||
override fun newInstance(obj: Any?): EnumDefaultSchemeTransform {
|
override fun newInstance(obj: Any?): EnumDefaultSchemaTransform {
|
||||||
val described = obj as List<*>
|
val described = obj as List<*>
|
||||||
val old = described[1] as? String ?: throw IllegalStateException("Was expecting \"old\" as a String")
|
val old = described[1] as? String ?: throw IllegalStateException("Was expecting \"old\" as a String")
|
||||||
val new = described[2] as? String ?: throw IllegalStateException("Was expecting \"new\" as a String")
|
val new = described[2] as? String ?: throw IllegalStateException("Was expecting \"new\" as a String")
|
||||||
return EnumDefaultSchemeTransform(old, new)
|
return EnumDefaultSchemaTransform(old, new)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTypeClass(): Class<*> = EnumDefaultSchemeTransform::class.java
|
override fun getTypeClass(): Class<*> = EnumDefaultSchemaTransform::class.java
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED")
|
@Suppress("UNUSED")
|
||||||
@ -93,7 +133,7 @@ class EnumDefaultSchemeTransform(val old: String, val new: String) : Transform()
|
|||||||
override fun params() = "old=${old.esc()} new=${new.esc()}"
|
override fun params() = "old=${old.esc()} new=${new.esc()}"
|
||||||
|
|
||||||
override fun equals(other: Any?) = (
|
override fun equals(other: Any?) = (
|
||||||
(other is EnumDefaultSchemeTransform && other.new == new && other.old == old) || super.equals(other))
|
(other is EnumDefaultSchemaTransform && other.new == new && other.old == old) || super.equals(other))
|
||||||
|
|
||||||
override fun hashCode() = (17 * new.hashCode()) + old.hashCode()
|
override fun hashCode() = (17 * new.hashCode()) + old.hashCode()
|
||||||
|
|
||||||
@ -138,7 +178,6 @@ class RenameSchemaTransform(val from: String, val to: String) : Transform() {
|
|||||||
override val name: String get() = typeName
|
override val name: String get() = typeName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the set of all transforms that can be a applied to all classes represented as part of
|
* Represents the set of all transforms that can be a applied to all classes represented as part of
|
||||||
* an AMQP schema. It forms a part of the AMQP envelope alongside the [Schema] and the serialized bytes
|
* an AMQP schema. It forms a part of the AMQP envelope alongside the [Schema] and the serialized bytes
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
package net.corda.nodeapi.internal.serialization.amqp
|
package net.corda.nodeapi.internal.serialization.amqp
|
||||||
|
|
||||||
import net.corda.core.serialization.CordaSerializationTransformEnumDefault
|
import net.corda.core.serialization.*
|
||||||
import net.corda.core.serialization.CordaSerializationTransformEnumDefaults
|
|
||||||
import net.corda.core.serialization.CordaSerializationTransformRename
|
|
||||||
import net.corda.core.serialization.CordaSerializationTransformRenames
|
|
||||||
import org.assertj.core.api.Assertions
|
import org.assertj.core.api.Assertions
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import java.io.File
|
||||||
import java.io.NotSerializableException
|
import java.io.NotSerializableException
|
||||||
|
import java.net.URI
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class EnumEvolvabilityTests {
|
class EnumEvolvabilityTests {
|
||||||
|
// var localPath = "file:///Users/katelynbaker/srcs-ide/corda/node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp"
|
||||||
|
var localPath = "file:///home/katelyn/srcs/corda/node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp"
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val VERBOSE = false
|
val VERBOSE = false
|
||||||
}
|
}
|
||||||
@ -104,9 +107,9 @@ class EnumEvolvabilityTests {
|
|||||||
assertEquals(1, schema.size)
|
assertEquals(1, schema.size)
|
||||||
assertTrue (schema.keys.contains(TransformTypes.EnumDefault))
|
assertTrue (schema.keys.contains(TransformTypes.EnumDefault))
|
||||||
assertEquals (1, schema[TransformTypes.EnumDefault]!!.size)
|
assertEquals (1, schema[TransformTypes.EnumDefault]!!.size)
|
||||||
assertTrue (schema[TransformTypes.EnumDefault]!![0] is EnumDefaultSchemeTransform)
|
assertTrue (schema[TransformTypes.EnumDefault]!![0] is EnumDefaultSchemaTransform)
|
||||||
assertEquals ("D", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemeTransform).new)
|
assertEquals ("D", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemaTransform).new)
|
||||||
assertEquals ("A", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemeTransform).old)
|
assertEquals ("A", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemaTransform).old)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -125,12 +128,12 @@ class EnumEvolvabilityTests {
|
|||||||
assertEquals(1, schema.size)
|
assertEquals(1, schema.size)
|
||||||
assertTrue (schema.keys.contains(TransformTypes.EnumDefault))
|
assertTrue (schema.keys.contains(TransformTypes.EnumDefault))
|
||||||
assertEquals (2, schema[TransformTypes.EnumDefault]!!.size)
|
assertEquals (2, schema[TransformTypes.EnumDefault]!!.size)
|
||||||
assertTrue (schema[TransformTypes.EnumDefault]!![0] is EnumDefaultSchemeTransform)
|
assertTrue (schema[TransformTypes.EnumDefault]!![0] is EnumDefaultSchemaTransform)
|
||||||
assertEquals ("E", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemeTransform).new)
|
assertEquals ("E", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemaTransform).new)
|
||||||
assertEquals ("D", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemeTransform).old)
|
assertEquals ("D", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemaTransform).old)
|
||||||
assertTrue (schema[TransformTypes.EnumDefault]!![1] is EnumDefaultSchemeTransform)
|
assertTrue (schema[TransformTypes.EnumDefault]!![1] is EnumDefaultSchemaTransform)
|
||||||
assertEquals ("D", (schema[TransformTypes.EnumDefault]!![1] as EnumDefaultSchemeTransform).new)
|
assertEquals ("D", (schema[TransformTypes.EnumDefault]!![1] as EnumDefaultSchemaTransform).new)
|
||||||
assertEquals ("A", (schema[TransformTypes.EnumDefault]!![1] as EnumDefaultSchemeTransform).old)
|
assertEquals ("A", (schema[TransformTypes.EnumDefault]!![1] as EnumDefaultSchemaTransform).old)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -157,9 +160,9 @@ class EnumEvolvabilityTests {
|
|||||||
|
|
||||||
assertTrue (schema!!.keys.contains(TransformTypes.EnumDefault))
|
assertTrue (schema!!.keys.contains(TransformTypes.EnumDefault))
|
||||||
assertEquals (1, schema[TransformTypes.EnumDefault]!!.size)
|
assertEquals (1, schema[TransformTypes.EnumDefault]!!.size)
|
||||||
assertTrue (schema[TransformTypes.EnumDefault]!![0] is EnumDefaultSchemeTransform)
|
assertTrue (schema[TransformTypes.EnumDefault]!![0] is EnumDefaultSchemaTransform)
|
||||||
assertEquals ("D", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemeTransform).new)
|
assertEquals ("D", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemaTransform).new)
|
||||||
assertEquals ("A", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemeTransform).old)
|
assertEquals ("A", (schema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemaTransform).old)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -183,10 +186,10 @@ class EnumEvolvabilityTests {
|
|||||||
|
|
||||||
val enumDefaults = transforms[AnnotatedEnumTwice::class.java.name]!![TransformTypes.EnumDefault]!!
|
val enumDefaults = transforms[AnnotatedEnumTwice::class.java.name]!![TransformTypes.EnumDefault]!!
|
||||||
|
|
||||||
assertEquals("E", (enumDefaults[0] as EnumDefaultSchemeTransform).new)
|
assertEquals("E", (enumDefaults[0] as EnumDefaultSchemaTransform).new)
|
||||||
assertEquals("D", (enumDefaults[0] as EnumDefaultSchemeTransform).old)
|
assertEquals("D", (enumDefaults[0] as EnumDefaultSchemaTransform).old)
|
||||||
assertEquals("D", (enumDefaults[1] as EnumDefaultSchemeTransform).new)
|
assertEquals("D", (enumDefaults[1] as EnumDefaultSchemaTransform).new)
|
||||||
assertEquals("A", (enumDefaults[1] as EnumDefaultSchemeTransform).old)
|
assertEquals("A", (enumDefaults[1] as EnumDefaultSchemaTransform).old)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -299,8 +302,8 @@ class EnumEvolvabilityTests {
|
|||||||
assertEquals("X", (serialisedSchema[TransformTypes.Rename]!![0] as RenameSchemaTransform).to)
|
assertEquals("X", (serialisedSchema[TransformTypes.Rename]!![0] as RenameSchemaTransform).to)
|
||||||
|
|
||||||
assertEquals(1, serialisedSchema[TransformTypes.EnumDefault]!!.size)
|
assertEquals(1, serialisedSchema[TransformTypes.EnumDefault]!!.size)
|
||||||
assertEquals("E", (serialisedSchema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemeTransform).new)
|
assertEquals("E", (serialisedSchema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemaTransform).new)
|
||||||
assertEquals("X", (serialisedSchema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemeTransform).old)
|
assertEquals("X", (serialisedSchema[TransformTypes.EnumDefault]!![0] as EnumDefaultSchemaTransform).old)
|
||||||
}
|
}
|
||||||
|
|
||||||
@CordaSerializationTransformEnumDefaults (
|
@CordaSerializationTransformEnumDefaults (
|
||||||
@ -402,6 +405,32 @@ class EnumEvolvabilityTests {
|
|||||||
|
|
||||||
assertEquals (sb1.transformsSchema.types[AnnotatedEnumOnce::class.java.name],
|
assertEquals (sb1.transformsSchema.types[AnnotatedEnumOnce::class.java.name],
|
||||||
sb2.transformsSchema.types[AnnotatedEnumOnce::class.java.name])
|
sb2.transformsSchema.types[AnnotatedEnumOnce::class.java.name])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// @UnknownTransformAnnotation (10, 20, 30)
|
||||||
|
enum class WithUnknownTest {
|
||||||
|
A, B, C, D
|
||||||
|
}
|
||||||
|
|
||||||
|
data class WrapsUnknown(val unknown: WithUnknownTest)
|
||||||
|
|
||||||
|
// To regenerate the types for this test uncomment the UnknownTransformAnnotation from
|
||||||
|
// TransformTypes.kt and SupportedTransforms.kt
|
||||||
|
@Test
|
||||||
|
fun testUnknownTransform() {
|
||||||
|
val resource = "EnumEvolvabilityTests.testUnknownTransform"
|
||||||
|
val sf = testDefaultFactory()
|
||||||
|
|
||||||
|
//File(URI("$localPath/$resource")).writeBytes(
|
||||||
|
// SerializationOutput(sf).serialize(WrapsUnknown(WithUnknownTest.D)).bytes)
|
||||||
|
|
||||||
|
val path = EvolvabilityTests::class.java.getResource(resource)
|
||||||
|
val sb1 = File(path.toURI()).readBytes()
|
||||||
|
|
||||||
|
val envelope = DeserializationInput(sf).deserializeAndReturnEnvelope(SerializedBytes<WrapsUnknown>(sb1)).envelope
|
||||||
|
|
||||||
|
assertTrue(envelope.transformsSchema.types.containsKey(WithUnknownTest::class.java.name))
|
||||||
|
assertTrue(envelope.transformsSchema.types[WithUnknownTest::class.java.name]!!.containsKey(TransformTypes.Unknown))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,36 +5,40 @@ import net.corda.core.serialization.SerializedBytes
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.NotSerializableException
|
import java.io.NotSerializableException
|
||||||
|
import java.net.URI
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
// To regenerate any of the binary test files do the following
|
// To regenerate any of the binary test files do the following
|
||||||
//
|
//
|
||||||
|
// 0. set localPath accordingly
|
||||||
// 1. Uncomment the code where the original form of the class is defined in the test
|
// 1. Uncomment the code where the original form of the class is defined in the test
|
||||||
// 2. Comment out the rest of the test
|
// 2. Comment out the rest of the test
|
||||||
// 3. Run the test
|
// 3. Run the test
|
||||||
// 4. Using the printed path copy that file to the resources directory
|
// 4. Using the printed path copy that file to the resources directory
|
||||||
// 5. Comment back out the generation code and uncomment the actual test
|
// 5. Comment back out the generation code and uncomment the actual test
|
||||||
class EvolvabilityTests {
|
class EvolvabilityTests {
|
||||||
|
// When regenerating the test files this needs to be set to the file system location of the resource files
|
||||||
|
var localPath = "file:///<path>/<to>/<toplevel of>/corda/node-api/src/test/resources/net/corda/nodeapi/internal/serialization/amqp"
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun simpleOrderSwapSameType() {
|
fun simpleOrderSwapSameType() {
|
||||||
val sf = testDefaultFactory()
|
val sf = testDefaultFactory()
|
||||||
val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.simpleOrderSwapSameType")
|
val resource= "EvolvabilityTests.simpleOrderSwapSameType"
|
||||||
val f = File(path.toURI())
|
|
||||||
|
|
||||||
val A = 1
|
val A = 1
|
||||||
val B = 2
|
val B = 2
|
||||||
|
|
||||||
// Original version of the class for the serialised version of this class
|
// Original version of the class for the serialised version of this class
|
||||||
//
|
|
||||||
// data class C (val a: Int, val b: Int)
|
// data class C (val a: Int, val b: Int)
|
||||||
// val sc = SerializationOutput(sf).serialize(C(A, B))
|
// val sc = SerializationOutput(sf).serialize(C(A, B))
|
||||||
// f.writeBytes(sc.bytes)
|
// File(URI("$localPath/$resource")).writeBytes(sc.bytes)
|
||||||
// println (path)
|
|
||||||
|
|
||||||
// new version of the class, in this case the order of the parameters has been swapped
|
// new version of the class, in this case the order of the parameters has been swapped
|
||||||
data class C(val b: Int, val a: Int)
|
data class C(val b: Int, val a: Int)
|
||||||
|
|
||||||
|
val path = EvolvabilityTests::class.java.getResource(resource)
|
||||||
|
val f = File(path.toURI())
|
||||||
|
|
||||||
val sc2 = f.readBytes()
|
val sc2 = f.readBytes()
|
||||||
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
|
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
|
||||||
|
|
||||||
@ -45,21 +49,20 @@ class EvolvabilityTests {
|
|||||||
@Test
|
@Test
|
||||||
fun simpleOrderSwapDifferentType() {
|
fun simpleOrderSwapDifferentType() {
|
||||||
val sf = testDefaultFactory()
|
val sf = testDefaultFactory()
|
||||||
val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.simpleOrderSwapDifferentType")
|
|
||||||
val f = File(path.toURI())
|
|
||||||
val A = 1
|
val A = 1
|
||||||
val B = "two"
|
val B = "two"
|
||||||
|
val resource = "EvolvabilityTests.simpleOrderSwapDifferentType"
|
||||||
|
|
||||||
// Original version of the class as it was serialised
|
// Original version of the class as it was serialised
|
||||||
//
|
|
||||||
// data class C (val a: Int, val b: String)
|
// data class C (val a: Int, val b: String)
|
||||||
// val sc = SerializationOutput(sf).serialize(C(A, B))
|
// val sc = SerializationOutput(sf).serialize(C(A, B))
|
||||||
// f.writeBytes(sc.bytes)
|
// File(URI("$localPath/$resource")).writeBytes(sc.bytes)
|
||||||
// println (path)
|
|
||||||
|
|
||||||
// new version of the class, in this case the order of the parameters has been swapped
|
// new version of the class, in this case the order of the parameters has been swapped
|
||||||
data class C(val b: String, val a: Int)
|
data class C(val b: String, val a: Int)
|
||||||
|
|
||||||
|
val path = EvolvabilityTests::class.java.getResource(resource)
|
||||||
|
val f = File(path.toURI())
|
||||||
val sc2 = f.readBytes()
|
val sc2 = f.readBytes()
|
||||||
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
|
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
|
||||||
|
|
||||||
@ -70,18 +73,18 @@ class EvolvabilityTests {
|
|||||||
@Test
|
@Test
|
||||||
fun addAdditionalParamNotMandatory() {
|
fun addAdditionalParamNotMandatory() {
|
||||||
val sf = testDefaultFactory()
|
val sf = testDefaultFactory()
|
||||||
val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.addAdditionalParamNotMandatory")
|
|
||||||
val f = File(path.toURI())
|
|
||||||
val A = 1
|
val A = 1
|
||||||
|
val resource = "EvolvabilityTests.addAdditionalParamNotMandatory"
|
||||||
|
|
||||||
// Original version of the class as it was serialised
|
// Original version of the class as it was serialised
|
||||||
//
|
|
||||||
// data class C(val a: Int)
|
// data class C(val a: Int)
|
||||||
// val sc = SerializationOutput(sf).serialize(C(A))
|
// val sc = SerializationOutput(sf).serialize(C(A))
|
||||||
// f.writeBytes(sc.bytes)
|
// File(URI("$localPath/$resource")).writeBytes(sc.bytes)
|
||||||
// println ("Path = $path")
|
|
||||||
data class C(val a: Int, val b: Int?)
|
data class C(val a: Int, val b: Int?)
|
||||||
|
|
||||||
|
val path = EvolvabilityTests::class.java.getResource(resource)
|
||||||
|
val f = File(path.toURI())
|
||||||
val sc2 = f.readBytes()
|
val sc2 = f.readBytes()
|
||||||
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
|
val deserializedC = DeserializationInput(sf).deserialize(SerializedBytes<C>(sc2))
|
||||||
|
|
||||||
@ -119,22 +122,21 @@ class EvolvabilityTests {
|
|||||||
@Test
|
@Test
|
||||||
fun removeParameters() {
|
fun removeParameters() {
|
||||||
val sf = testDefaultFactory()
|
val sf = testDefaultFactory()
|
||||||
val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.removeParameters")
|
val resource = "EvolvabilityTests.removeParameters"
|
||||||
val f = File(path.toURI())
|
|
||||||
val A = 1
|
val A = 1
|
||||||
val B = "two"
|
val B = "two"
|
||||||
val C = "three"
|
val C = "three"
|
||||||
val D = 4
|
val D = 4
|
||||||
|
|
||||||
// Original version of the class as it was serialised
|
// Original version of the class as it was serialised
|
||||||
//
|
|
||||||
// data class CC(val a: Int, val b: String, val c: String, val d: Int)
|
// data class CC(val a: Int, val b: String, val c: String, val d: Int)
|
||||||
// val scc = SerializationOutput(sf).serialize(CC(A, B, C, D))
|
// val scc = SerializationOutput(sf).serialize(CC(A, B, C, D))
|
||||||
// f.writeBytes(scc.bytes)
|
// File(URI("$localPath/$resource")).writeBytes(scc.bytes)
|
||||||
// println ("Path = $path")
|
|
||||||
|
|
||||||
data class CC(val b: String, val d: Int)
|
data class CC(val b: String, val d: Int)
|
||||||
|
|
||||||
|
val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.removeParameters")
|
||||||
|
val f = File(path.toURI())
|
||||||
val sc2 = f.readBytes()
|
val sc2 = f.readBytes()
|
||||||
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
|
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
|
||||||
|
|
||||||
@ -146,23 +148,23 @@ class EvolvabilityTests {
|
|||||||
@Test
|
@Test
|
||||||
fun addAndRemoveParameters() {
|
fun addAndRemoveParameters() {
|
||||||
val sf = testDefaultFactory()
|
val sf = testDefaultFactory()
|
||||||
val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.addAndRemoveParameters")
|
|
||||||
val f = File(path.toURI())
|
|
||||||
val A = 1
|
val A = 1
|
||||||
val B = "two"
|
val B = "two"
|
||||||
val C = "three"
|
val C = "three"
|
||||||
val D = 4
|
val D = 4
|
||||||
val E = null
|
val E = null
|
||||||
|
|
||||||
|
val resource = "EvolvabilityTests.addAndRemoveParameters"
|
||||||
|
|
||||||
// Original version of the class as it was serialised
|
// Original version of the class as it was serialised
|
||||||
//
|
|
||||||
// data class CC(val a: Int, val b: String, val c: String, val d: Int)
|
// data class CC(val a: Int, val b: String, val c: String, val d: Int)
|
||||||
// val scc = SerializationOutput(sf).serialize(CC(A, B, C, D))
|
// val scc = SerializationOutput(sf).serialize(CC(A, B, C, D))
|
||||||
// f.writeBytes(scc.bytes)
|
// File(URI("$localPath/$resource")).writeBytes(scc.bytes)
|
||||||
// println ("Path = $path")
|
|
||||||
|
|
||||||
data class CC(val a: Int, val e: Boolean?, val d: Int)
|
data class CC(val a: Int, val e: Boolean?, val d: Int)
|
||||||
|
|
||||||
|
val path = EvolvabilityTests::class.java.getResource(resource)
|
||||||
|
val f = File(path.toURI())
|
||||||
val sc2 = f.readBytes()
|
val sc2 = f.readBytes()
|
||||||
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
|
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
|
||||||
|
|
||||||
@ -174,16 +176,13 @@ class EvolvabilityTests {
|
|||||||
@Test
|
@Test
|
||||||
fun addMandatoryFieldWithAltConstructor() {
|
fun addMandatoryFieldWithAltConstructor() {
|
||||||
val sf = testDefaultFactory()
|
val sf = testDefaultFactory()
|
||||||
val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.addMandatoryFieldWithAltConstructor")
|
|
||||||
val f = File(path.toURI())
|
|
||||||
val A = 1
|
val A = 1
|
||||||
|
val resource = "EvolvabilityTests.addMandatoryFieldWithAltConstructor"
|
||||||
|
|
||||||
// Original version of the class as it was serialised
|
// Original version of the class as it was serialised
|
||||||
//
|
|
||||||
// data class CC(val a: Int)
|
// data class CC(val a: Int)
|
||||||
// val scc = SerializationOutput(sf).serialize(CC(A))
|
// val scc = SerializationOutput(sf).serialize(CC(A))
|
||||||
// f.writeBytes(scc.bytes)
|
// File(URI("$localPath/$resource")).writeBytes(scc.bytes)
|
||||||
// println ("Path = $path")
|
|
||||||
|
|
||||||
@Suppress("UNUSED")
|
@Suppress("UNUSED")
|
||||||
data class CC(val a: Int, val b: String) {
|
data class CC(val a: Int, val b: String) {
|
||||||
@ -191,6 +190,8 @@ class EvolvabilityTests {
|
|||||||
constructor (a: Int) : this(a, "hello")
|
constructor (a: Int) : this(a, "hello")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val path = EvolvabilityTests::class.java.getResource(resource)
|
||||||
|
val f = File(path.toURI())
|
||||||
val sc2 = f.readBytes()
|
val sc2 = f.readBytes()
|
||||||
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
|
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
|
||||||
|
|
||||||
@ -228,19 +229,15 @@ class EvolvabilityTests {
|
|||||||
@Test
|
@Test
|
||||||
fun addMandatoryFieldWithAltReorderedConstructor() {
|
fun addMandatoryFieldWithAltReorderedConstructor() {
|
||||||
val sf = testDefaultFactory()
|
val sf = testDefaultFactory()
|
||||||
val path = EvolvabilityTests::class.java.getResource(
|
val resource = "EvolvabilityTests.addMandatoryFieldWithAltReorderedConstructor"
|
||||||
"EvolvabilityTests.addMandatoryFieldWithAltReorderedConstructor")
|
|
||||||
val f = File(path.toURI())
|
|
||||||
val A = 1
|
val A = 1
|
||||||
val B = 100
|
val B = 100
|
||||||
val C = "This is not a banana"
|
val C = "This is not a banana"
|
||||||
|
|
||||||
// Original version of the class as it was serialised
|
// Original version of the class as it was serialised
|
||||||
//
|
|
||||||
// data class CC(val a: Int, val b: Int, val c: String)
|
// data class CC(val a: Int, val b: Int, val c: String)
|
||||||
// val scc = SerializationOutput(sf).serialize(CC(A, B, C))
|
// val scc = SerializationOutput(sf).serialize(CC(A, B, C))
|
||||||
// f.writeBytes(scc.bytes)
|
// File(URI("$localPath/$resource")).writeBytes(scc.bytes)
|
||||||
// println ("Path = $path")
|
|
||||||
|
|
||||||
@Suppress("UNUSED")
|
@Suppress("UNUSED")
|
||||||
data class CC(val a: Int, val b: Int, val c: String, val d: String) {
|
data class CC(val a: Int, val b: Int, val c: String, val d: String) {
|
||||||
@ -250,6 +247,8 @@ class EvolvabilityTests {
|
|||||||
constructor (c: String, a: Int, b: Int) : this(a, b, c, "wibble")
|
constructor (c: String, a: Int, b: Int) : this(a, b, c, "wibble")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val path = EvolvabilityTests::class.java.getResource(resource)
|
||||||
|
val f = File(path.toURI())
|
||||||
val sc2 = f.readBytes()
|
val sc2 = f.readBytes()
|
||||||
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
|
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
|
||||||
|
|
||||||
@ -262,20 +261,15 @@ class EvolvabilityTests {
|
|||||||
@Test
|
@Test
|
||||||
fun addMandatoryFieldWithAltReorderedConstructorAndRemoval() {
|
fun addMandatoryFieldWithAltReorderedConstructorAndRemoval() {
|
||||||
val sf = testDefaultFactory()
|
val sf = testDefaultFactory()
|
||||||
val path = EvolvabilityTests::class.java.getResource(
|
val resource = "EvolvabilityTests.addMandatoryFieldWithAltReorderedConstructorAndRemoval"
|
||||||
"EvolvabilityTests.addMandatoryFieldWithAltReorderedConstructorAndRemoval")
|
|
||||||
val f = File(path.toURI())
|
|
||||||
val A = 1
|
val A = 1
|
||||||
@Suppress("UNUSED_VARIABLE")
|
@Suppress("UNUSED_VARIABLE")
|
||||||
val B = 100
|
val B = 100
|
||||||
val C = "This is not a banana"
|
val C = "This is not a banana"
|
||||||
|
|
||||||
// Original version of the class as it was serialised
|
// Original version of the class as it was serialised
|
||||||
//
|
|
||||||
// data class CC(val a: Int, val b: Int, val c: String)
|
// data class CC(val a: Int, val b: Int, val c: String)
|
||||||
// val scc = SerializationOutput(sf).serialize(CC(A, B, C))
|
// File(URI("$localPath/$resource")).writeBytes(SerializationOutput(sf).serialize(CC(A, B, C)).bytes)
|
||||||
// f.writeBytes(scc.bytes)
|
|
||||||
// println ("Path = $path")
|
|
||||||
|
|
||||||
// b is removed, d is added
|
// b is removed, d is added
|
||||||
data class CC(val a: Int, val c: String, val d: String) {
|
data class CC(val a: Int, val c: String, val d: String) {
|
||||||
@ -286,6 +280,8 @@ class EvolvabilityTests {
|
|||||||
constructor (c: String, a: Int) : this(a, c, "wibble")
|
constructor (c: String, a: Int) : this(a, c, "wibble")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val path = EvolvabilityTests::class.java.getResource(resource)
|
||||||
|
val f = File(path.toURI())
|
||||||
val sc2 = f.readBytes()
|
val sc2 = f.readBytes()
|
||||||
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
|
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
|
||||||
|
|
||||||
@ -297,9 +293,9 @@ class EvolvabilityTests {
|
|||||||
@Test
|
@Test
|
||||||
fun multiVersion() {
|
fun multiVersion() {
|
||||||
val sf = testDefaultFactory()
|
val sf = testDefaultFactory()
|
||||||
val path1 = EvolvabilityTests::class.java.getResource("EvolvabilityTests.multiVersion.1")
|
val resource1 = "EvolvabilityTests.multiVersion.1"
|
||||||
val path2 = EvolvabilityTests::class.java.getResource("EvolvabilityTests.multiVersion.2")
|
val resource2 = "EvolvabilityTests.multiVersion.2"
|
||||||
val path3 = EvolvabilityTests::class.java.getResource("EvolvabilityTests.multiVersion.3")
|
val resource3 = "EvolvabilityTests.multiVersion.3"
|
||||||
|
|
||||||
val a = 100
|
val a = 100
|
||||||
val b = 200
|
val b = 200
|
||||||
@ -310,24 +306,15 @@ class EvolvabilityTests {
|
|||||||
//
|
//
|
||||||
// Version 1:
|
// Version 1:
|
||||||
// data class C (val a: Int, val b: Int)
|
// data class C (val a: Int, val b: Int)
|
||||||
//
|
// File(URI("$localPath/$resource1")).writeBytes(SerializationOutput(sf).serialize(C(a, b)).bytes)
|
||||||
// val scc = SerializationOutput(sf).serialize(C(a, b))
|
|
||||||
// File(path1.toURI()).writeBytes(scc.bytes)
|
|
||||||
// println ("Path = $path1")
|
|
||||||
//
|
//
|
||||||
// Version 2 - add param c
|
// Version 2 - add param c
|
||||||
// data class C (val c: Int, val b: Int, val a: Int)
|
// data class C (val c: Int, val b: Int, val a: Int)
|
||||||
//
|
// File(URI("$localPath/$resource2")).writeBytes(SerializationOutput(sf).serialize(C(c, b, a)).bytes)
|
||||||
// val scc = SerializationOutput(sf).serialize(C(c, b, a))
|
|
||||||
// File(path2.toURI()).writeBytes(scc.bytes)
|
|
||||||
// println ("Path = $path2")
|
|
||||||
//
|
//
|
||||||
// Version 3 - add param d
|
// Version 3 - add param d
|
||||||
// data class C (val b: Int, val c: Int, val d: Int, val a: Int)
|
// data class C (val b: Int, val c: Int, val d: Int, val a: Int)
|
||||||
//
|
// File(URI("$localPath/$resource3")).writeBytes(SerializationOutput(sf).serialize(C(b, c, d, a)).bytes)
|
||||||
// val scc = SerializationOutput(sf).serialize(C(b, c, d, a))
|
|
||||||
// File(path3.toURI()).writeBytes(scc.bytes)
|
|
||||||
// println ("Path = $path3")
|
|
||||||
|
|
||||||
@Suppress("UNUSED")
|
@Suppress("UNUSED")
|
||||||
data class C(val e: Int, val c: Int, val b: Int, val a: Int, val d: Int) {
|
data class C(val e: Int, val c: Int, val b: Int, val a: Int, val d: Int) {
|
||||||
@ -341,6 +328,10 @@ class EvolvabilityTests {
|
|||||||
constructor (a: Int, b: Int, c: Int, d: Int) : this(-1, c, b, a, d)
|
constructor (a: Int, b: Int, c: Int, d: Int) : this(-1, c, b, a, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val path1 = EvolvabilityTests::class.java.getResource(resource1)
|
||||||
|
val path2 = EvolvabilityTests::class.java.getResource(resource2)
|
||||||
|
val path3 = EvolvabilityTests::class.java.getResource(resource3)
|
||||||
|
|
||||||
val sb1 = File(path1.toURI()).readBytes()
|
val sb1 = File(path1.toURI()).readBytes()
|
||||||
val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1))
|
val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1))
|
||||||
|
|
||||||
@ -372,24 +363,21 @@ class EvolvabilityTests {
|
|||||||
@Test
|
@Test
|
||||||
fun changeSubType() {
|
fun changeSubType() {
|
||||||
val sf = testDefaultFactory()
|
val sf = testDefaultFactory()
|
||||||
val path = EvolvabilityTests::class.java.getResource("EvolvabilityTests.changeSubType")
|
val resource = "EvolvabilityTests.changeSubType"
|
||||||
val f = File(path.toURI())
|
|
||||||
val oa = 100
|
val oa = 100
|
||||||
val ia = 200
|
val ia = 200
|
||||||
|
|
||||||
// Original version of the class as it was serialised
|
// Original version of the class as it was serialised
|
||||||
//
|
|
||||||
// data class Inner (val a: Int)
|
// data class Inner (val a: Int)
|
||||||
// data class Outer (val a: Int, val b: Inner)
|
// data class Outer (val a: Int, val b: Inner)
|
||||||
// val scc = SerializationOutput(sf).serialize(Outer(oa, Inner (ia)))
|
// File(URI("$localPath/$resource")).writeBytes(SerializationOutput(sf).serialize(Outer(oa, Inner (ia))).bytes)
|
||||||
// f.writeBytes(scc.bytes)
|
|
||||||
// println ("Path = $path")
|
|
||||||
|
|
||||||
// Add a parameter to inner but keep outer unchanged
|
// Add a parameter to inner but keep outer unchanged
|
||||||
data class Inner(val a: Int, val b: String?)
|
data class Inner(val a: Int, val b: String?)
|
||||||
|
|
||||||
data class Outer(val a: Int, val b: Inner)
|
data class Outer(val a: Int, val b: Inner)
|
||||||
|
|
||||||
|
val path = EvolvabilityTests::class.java.getResource(resource)
|
||||||
|
val f = File(path.toURI())
|
||||||
val sc2 = f.readBytes()
|
val sc2 = f.readBytes()
|
||||||
val outer = DeserializationInput(sf).deserialize(SerializedBytes<Outer>(sc2))
|
val outer = DeserializationInput(sf).deserialize(SerializedBytes<Outer>(sc2))
|
||||||
|
|
||||||
@ -401,9 +389,10 @@ class EvolvabilityTests {
|
|||||||
@Test
|
@Test
|
||||||
fun multiVersionWithRemoval() {
|
fun multiVersionWithRemoval() {
|
||||||
val sf = testDefaultFactory()
|
val sf = testDefaultFactory()
|
||||||
val path1 = EvolvabilityTests::class.java.getResource("EvolvabilityTests.multiVersionWithRemoval.1")
|
|
||||||
val path2 = EvolvabilityTests::class.java.getResource("EvolvabilityTests.multiVersionWithRemoval.2")
|
val resource1 = "EvolvabilityTests.multiVersionWithRemoval.1"
|
||||||
val path3 = EvolvabilityTests::class.java.getResource("EvolvabilityTests.multiVersionWithRemoval.3")
|
val resource2 = "EvolvabilityTests.multiVersionWithRemoval.2"
|
||||||
|
val resource3 = "EvolvabilityTests.multiVersionWithRemoval.3"
|
||||||
|
|
||||||
@Suppress("UNUSED_VARIABLE")
|
@Suppress("UNUSED_VARIABLE")
|
||||||
val a = 100
|
val a = 100
|
||||||
@ -417,24 +406,15 @@ class EvolvabilityTests {
|
|||||||
//
|
//
|
||||||
// Version 1:
|
// Version 1:
|
||||||
// data class C (val a: Int, val b: Int, val c: Int)
|
// data class C (val a: Int, val b: Int, val c: Int)
|
||||||
|
// File(URI("$localPath/$resource1")).writeBytes(SerializationOutput(sf).serialize(C(a, b, c)).bytes)
|
||||||
//
|
//
|
||||||
// val scc = SerializationOutput(sf).serialize(C(a, b, c))
|
// Version 2 - remove property a, add property e
|
||||||
// File(path1.toURI()).writeBytes(scc.bytes)
|
|
||||||
// println ("Path = $path1")
|
|
||||||
//
|
|
||||||
// Version 2 - add param c
|
|
||||||
// data class C (val b: Int, val c: Int, val d: Int, val e: Int)
|
// data class C (val b: Int, val c: Int, val d: Int, val e: Int)
|
||||||
//
|
// File(URI("$localPath/$resource2")).writeBytes(SerializationOutput(sf).serialize(C(b, c, d, e)).bytes)
|
||||||
// val scc = SerializationOutput(sf).serialize(C(b, c, d, e))
|
|
||||||
// File(path2.toURI()).writeBytes(scc.bytes)
|
|
||||||
// println ("Path = $path2")
|
|
||||||
//
|
//
|
||||||
// Version 3 - add param d
|
// Version 3 - add param d
|
||||||
// data class C (val b: Int, val c: Int, val d: Int, val e: Int, val f: Int)
|
// data class C (val b: Int, val c: Int, val d: Int, val e: Int, val f: Int)
|
||||||
//
|
// File(URI("$localPath/$resource3")).writeBytes(SerializationOutput(sf).serialize(C(b, c, d, e, f)).bytes)
|
||||||
// val scc = SerializationOutput(sf).serialize(C(b, c, d, e, f))
|
|
||||||
// File(path3.toURI()).writeBytes(scc.bytes)
|
|
||||||
// println ("Path = $path3")
|
|
||||||
|
|
||||||
@Suppress("UNUSED")
|
@Suppress("UNUSED")
|
||||||
data class C(val b: Int, val c: Int, val d: Int, val e: Int, val f: Int, val g: Int) {
|
data class C(val b: Int, val c: Int, val d: Int, val e: Int, val f: Int, val g: Int) {
|
||||||
@ -451,6 +431,10 @@ class EvolvabilityTests {
|
|||||||
constructor (b: Int, c: Int, d: Int, e: Int, f: Int) : this(b, c, d, e, f, -1)
|
constructor (b: Int, c: Int, d: Int, e: Int, f: Int) : this(b, c, d, e, f, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val path1 = EvolvabilityTests::class.java.getResource(resource1)
|
||||||
|
val path2 = EvolvabilityTests::class.java.getResource(resource2)
|
||||||
|
val path3 = EvolvabilityTests::class.java.getResource(resource3)
|
||||||
|
|
||||||
val sb1 = File(path1.toURI()).readBytes()
|
val sb1 = File(path1.toURI()).readBytes()
|
||||||
val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1))
|
val db1 = DeserializationInput(sf).deserialize(SerializedBytes<C>(sb1))
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user