microsoft-avro icon indicating copy to clipboard operation
microsoft-avro copied to clipboard

Broken Serialization/Deserialization of complicated object

Open svantreeck opened this issue 8 years ago • 0 comments

Below is a reproduction of an issue where a List containing a List containing a Dictionary doesn't seem to serialize/deserialize properly. From what I can tell, the second Grandchildren.Enums gets serialized incorrectly, and the deserialization blows up when attempting to read it. My suspicion is that the EnumerableSerializer is causing the issue; however, I'm not sure how best to address it. The code below is the minimal reproduction that I was able to create for this issue.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using FluentAssertions;
using Microsoft.Hadoop.Avro;
using Xunit;

namespace Microsoft.Avro.Tests.MyTests
{
    public class BrokenStuff
    {
        [Fact]
        public void Repro()
        {
            var data = new Container
            {
                Children = new List<Child>
                {
                    new Child()
                    {
                        Granchildren = new List<Grandchildren>
                        {
                            new Grandchildren { Enums = new Dictionary<TestEnum, string> {{ TestEnum.Val1, "testval1"}}},
                            new Grandchildren { Enums = new Dictionary<TestEnum, string> {{ TestEnum.Val2, "testval2"}}}
                        }
                    },
                }
            };

            RoundTripSerializationWithCheck(data,
                    actual => actual.ShouldBeEquivalentTo(data),
                    new AvroSerializerSettings
                    {
                        Resolver = new AvroPublicMemberContractResolver(true),
                    });
        }

        private static TS RoundTripSerializationWithCheck<TS>(TS serialized, Action<TS> check, AvroSerializerSettings settings = null)
        {
            if (check == null)
            {
                throw new ArgumentNullException("check");
            }

            var serializer = settings == null
                ? AvroSerializer.Create<TS>(new AvroSerializerSettings { Resolver = new AvroDataContractResolver(true) })
                : AvroSerializer.Create<TS>(settings);

            using (var stream = new MemoryStream())
            {
                serializer.Serialize(stream, serialized);
                stream.Seek(0, SeekOrigin.Begin);

                var bytes = stream.ToArray();
                var chars = bytes.Select(Convert.ToChar).ToArray();
                Debugger.Break();

                var deserialized = serializer.Deserialize(stream);

                check(deserialized);
                return deserialized;
            }
        }

        public class Container
        {
            public List<Child> Children { get; set; }
        }

        public class Child
        {
            public List<Grandchildren> Granchildren { get; set; }
        }

        public class Grandchildren
        {
            public Dictionary<TestEnum, string> Enums { get; set; }
        }

        public enum TestEnum
        {
            Val1,
            Val2
        }
    }
}

svantreeck avatar Oct 11 '17 20:10 svantreeck