From c4d5af2aba759dacbdb2b8e913f2d3ae6ecef403 Mon Sep 17 00:00:00 2001 From: Christian Corsano Date: Sun, 25 Feb 2024 12:54:37 +0100 Subject: [PATCH 1/2] Added failing ICopier unit test - When declaring a single converter class for multiple surrogates, ICopier will always resolve the last declared IConverter<,> interface, failing with a InvalidCastException at runtime --- .../ConverterTests.cs | 12 ++++ .../Orleans.Serialization.UnitTests/Models.cs | 58 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/test/Orleans.Serialization.UnitTests/ConverterTests.cs b/test/Orleans.Serialization.UnitTests/ConverterTests.cs index 7ffd40f265..81fc59fdfb 100644 --- a/test/Orleans.Serialization.UnitTests/ConverterTests.cs +++ b/test/Orleans.Serialization.UnitTests/ConverterTests.cs @@ -115,3 +115,15 @@ public DerivedConverterCopierTests(ITestOutputHelper output) : base(output) protected override bool Equals(DerivedFromMyForeignLibraryType left, DerivedFromMyForeignLibraryType right) => ReferenceEquals(left, right) || left.Equals(right); protected override DerivedFromMyForeignLibraryType[] TestValues => new DerivedFromMyForeignLibraryType[] { null, CreateValue() }; } + + +public class CombinedConverterCopierTests : CopierTester> +{ + public CombinedConverterCopierTests(ITestOutputHelper output) : base(output) + { + } + + protected override MyFirstForeignLibraryType CreateValue() => new() { Num = 12, String = "hi", DateTimeOffset = DateTimeOffset.Now }; + protected override bool Equals(MyFirstForeignLibraryType left, MyFirstForeignLibraryType right) => ReferenceEquals(left, right) || left.Equals(right); + protected override MyFirstForeignLibraryType[] TestValues => new MyFirstForeignLibraryType[] { null, CreateValue() }; +} diff --git a/test/Orleans.Serialization.UnitTests/Models.cs b/test/Orleans.Serialization.UnitTests/Models.cs index 721c48691e..1ca28ab5ec 100644 --- a/test/Orleans.Serialization.UnitTests/Models.cs +++ b/test/Orleans.Serialization.UnitTests/Models.cs @@ -843,4 +843,62 @@ public sealed class ClassWithTypeFields [Id(2)] public object UntypedValue; [Id(3)] public Type Type2; } + + public class MyFirstForeignLibraryType + { + + public int Num { get; set; } + public string String { get; set; } + public DateTimeOffset DateTimeOffset { get; set; } + } + + public class MySecondForeignLibraryType + { + public string Name { get; set; } + public float Value { get; set; } + public DateTimeOffset Timestamp { get; set; } + } + + [GenerateSerializer] + public struct MyFirstForeignLibraryTypeSurrogate + { + [Id(0)] + public int Num { get; set; } + + [Id(1)] + public string String { get; set; } + + [Id(2)] + public DateTimeOffset DateTimeOffset { get; set; } + } + + + [GenerateSerializer] + public struct MySecondForeignLibraryTypeSurrogate + { + [Id(0)] + public string Name { get; set; } + + [Id(1)] + public float Value { get; set; } + + [Id(2)] + public DateTimeOffset Timestamp { get; set; } + } + + [RegisterConverter] + public sealed class MyCombinedForeignLibraryValueTypeSurrogateConverter : + IConverter, + IConverter + { + public MyFirstForeignLibraryType ConvertFromSurrogate(in MyFirstForeignLibraryTypeSurrogate surrogate) + => new () { Num = surrogate.Num, String = surrogate.String, DateTimeOffset = surrogate.DateTimeOffset }; + public MyFirstForeignLibraryTypeSurrogate ConvertToSurrogate(in MyFirstForeignLibraryType value) + => new() { Num = value.Num, String = value.String, DateTimeOffset = value.DateTimeOffset }; + + public MySecondForeignLibraryType ConvertFromSurrogate(in MySecondForeignLibraryTypeSurrogate surrogate) + => new() { Name = surrogate.Name, Value = surrogate.Value, Timestamp = surrogate.Timestamp }; + public MySecondForeignLibraryTypeSurrogate ConvertToSurrogate(in MySecondForeignLibraryType value) + => new () { Name = value.Name, Value = value.Value, Timestamp = value.Timestamp }; + } } \ No newline at end of file From ce575818afea18253345783bf8eb48c793258dac Mon Sep 17 00:00:00 2001 From: Christian Corsano Date: Sun, 25 Feb 2024 13:12:14 +0100 Subject: [PATCH 2/2] Completed failing ICopier unit test - Added Equals and GetHashCode to foreign types --- .../ConverterTests.cs | 4 ++-- test/Orleans.Serialization.UnitTests/Models.cs | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/test/Orleans.Serialization.UnitTests/ConverterTests.cs b/test/Orleans.Serialization.UnitTests/ConverterTests.cs index 81fc59fdfb..2747182ac3 100644 --- a/test/Orleans.Serialization.UnitTests/ConverterTests.cs +++ b/test/Orleans.Serialization.UnitTests/ConverterTests.cs @@ -124,6 +124,6 @@ public CombinedConverterCopierTests(ITestOutputHelper output) : base(output) } protected override MyFirstForeignLibraryType CreateValue() => new() { Num = 12, String = "hi", DateTimeOffset = DateTimeOffset.Now }; - protected override bool Equals(MyFirstForeignLibraryType left, MyFirstForeignLibraryType right) => ReferenceEquals(left, right) || left.Equals(right); - protected override MyFirstForeignLibraryType[] TestValues => new MyFirstForeignLibraryType[] { null, CreateValue() }; + protected override bool Equals(MyFirstForeignLibraryType left, MyFirstForeignLibraryType right) => left.Equals(right); + protected override MyFirstForeignLibraryType[] TestValues => new MyFirstForeignLibraryType[] { CreateValue() }; } diff --git a/test/Orleans.Serialization.UnitTests/Models.cs b/test/Orleans.Serialization.UnitTests/Models.cs index 1ca28ab5ec..19515ea3f8 100644 --- a/test/Orleans.Serialization.UnitTests/Models.cs +++ b/test/Orleans.Serialization.UnitTests/Models.cs @@ -850,6 +850,14 @@ public class MyFirstForeignLibraryType public int Num { get; set; } public string String { get; set; } public DateTimeOffset DateTimeOffset { get; set; } + + public override bool Equals(object obj) => + obj is MyFirstForeignLibraryType type + && Num == type.Num + && string.Equals(String, type.String, StringComparison.Ordinal) + && DateTimeOffset.Equals(type.DateTimeOffset); + + public override int GetHashCode() => HashCode.Combine(Num, String, DateTimeOffset); } public class MySecondForeignLibraryType @@ -857,6 +865,14 @@ public class MySecondForeignLibraryType public string Name { get; set; } public float Value { get; set; } public DateTimeOffset Timestamp { get; set; } + + public override bool Equals(object obj) => + obj is MySecondForeignLibraryType type + && string.Equals(Name, type.Name, StringComparison.Ordinal) + && Value == type.Value + && Timestamp.Equals(type.Timestamp); + + public override int GetHashCode() => HashCode.Combine(Name, Value, Timestamp); } [GenerateSerializer]