#region License Information /* HeuristicLab * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using HeuristicLab.Algorithms.GeneticAlgorithm; using HeuristicLab.Data; using HeuristicLab.Persistence; using HeuristicLab.Persistence.Auxiliary; using HeuristicLab.Persistence.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Persistence.Default.DebugString; using HeuristicLab.Persistence.Default.Xml; using HeuristicLab.Persistence.Tests; using HeuristicLab.Tests; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace HeuristicLab.PersistenceNew.Tests { public static class EnumerableTimeSpanExtensions { public static TimeSpan Average(this IEnumerable span) { var avg = (long)Math.Round(span.Select(x => x.Ticks).Average()); return new TimeSpan(avg); } } #region Test Classes [StorableClass("7D9672BD-703D-42BB-9080-9929885D4580")] public class NumberTest { [Storable] private bool _bool = true; [Storable] private byte _byte = 0xFF; [Storable] private sbyte _sbyte = 0xF; [Storable] private short _short = -123; [Storable] private ushort _ushort = 123; [Storable] private int _int = -123; [Storable] private uint _uint = 123; [Storable] private long _long = 123456; [Storable] private ulong _ulong = 123456; public override bool Equals(object obj) { NumberTest nt = obj as NumberTest; if (nt == null) throw new NotSupportedException(); return nt._bool == _bool && nt._byte == _byte && nt._sbyte == _sbyte && nt._short == _short && nt._ushort == _ushort && nt._int == _int && nt._uint == _uint && nt._long == _long && nt._ulong == _ulong; } public override int GetHashCode() { return _bool.GetHashCode() ^ _byte.GetHashCode() ^ _sbyte.GetHashCode() ^ _short.GetHashCode() ^ _short.GetHashCode() ^ _int.GetHashCode() ^ _uint.GetHashCode() ^ _long.GetHashCode() ^ _ulong.GetHashCode(); } } [StorableClass("EEB19599-D5AC-48ED-A56B-CF213DFAF2E4")] public class NonDefaultConstructorClass { [Storable] int value; public NonDefaultConstructorClass(int value) { this.value = value; } } [StorableClass("EE43FE7A-6D07-4D52-9338-C21B3485F82A")] public class IntWrapper { [Storable] public int Value; private IntWrapper() { } public IntWrapper(int value) { this.Value = value; } public override bool Equals(object obj) { if (obj as IntWrapper == null) return false; return Value.Equals(((IntWrapper)obj).Value); } public override int GetHashCode() { return Value.GetHashCode(); } } [StorableClass("00A8E48E-8E8A-443C-A327-9F6ACCBE7E80")] public class PrimitivesTest : NumberTest { [Storable] private char c = 'e'; [Storable] private long[,] _long_array = new long[,] { { 123, 456, }, { 789, 123 } }; [Storable] public List list = new List { 1, 2, 3, 4, 5 }; [Storable] private object o = new object(); public override bool Equals(object obj) { PrimitivesTest pt = obj as PrimitivesTest; if (pt == null) throw new NotSupportedException(); return base.Equals(obj) && c == pt.c && _long_array == pt._long_array && list == pt.list && o == pt.o; } public override int GetHashCode() { return base.GetHashCode() ^ c.GetHashCode() ^ _long_array.GetHashCode() ^ list.GetHashCode() ^ o.GetHashCode(); } } public enum TestEnum { va1, va2, va3, va8 }; [StorableClass("26BA37F6-926D-4665-A10A-1F39E1CF6468")] public class RootBase { [Storable] private string baseString = " Serial "; [Storable] public TestEnum myEnum = TestEnum.va3; public override bool Equals(object obj) { RootBase rb = obj as RootBase; if (rb == null) throw new NotSupportedException(); return baseString == rb.baseString && myEnum == rb.myEnum; } public override int GetHashCode() { return baseString.GetHashCode() ^ myEnum.GetHashCode(); } } [StorableClass("F6BCB436-B5F2-40F6-8E2F-7A018CD1CBA0")] public class Root : RootBase { [Storable] public Stack intStack = new Stack(); [Storable] public int[] i = new[] { 3, 4, 5, 6 }; [Storable(Name = "Test String")] public string s; [Storable] public ArrayList intArray = new ArrayList(new[] { 1, 2, 3 }); [Storable] public List intList = new List(new[] { 321, 312, 321 }); [Storable] public Custom c; [Storable] public List selfReferences; [Storable] public double[,] multiDimArray = new double[,] { { 1, 2, 3 }, { 3, 4, 5 } }; [Storable] public bool boolean = true; [Storable] public DateTime dateTime; [Storable] public KeyValuePair kvp = new KeyValuePair("Serial", 123); [Storable] public Dictionary dict = new Dictionary(); [Storable(DefaultValue = "default")] public string uninitialized; } public enum SimpleEnum { one, two, three } public enum ComplexEnum { one = 1, two = 2, three = 3 } [FlagsAttribute] public enum TrickyEnum { zero = 0, one = 1, two = 2 } [StorableClass("2F6326ED-023A-415F-B5C7-9F9241940D05")] public class EnumTest { [Storable] public SimpleEnum simpleEnum = SimpleEnum.one; [Storable] public ComplexEnum complexEnum = (ComplexEnum)2; [Storable] public TrickyEnum trickyEnum = (TrickyEnum)15; } [StorableClass("92365E2A-1184-4280-B763-4853C7ADF3E3")] public class Custom { [Storable] public int i; [Storable] public Root r; [Storable] public string name = "]]>"; } [StorableClass("7CF19EBC-1EC4-4FBE-BCA9-DA48E3CFE30D")] public class Manager { public DateTime lastLoadTime; [Storable] private DateTime lastLoadTimePersistence { get { return lastLoadTime; } set { lastLoadTime = DateTime.Now; } } [Storable] public double? dbl; } [StorableClass("9092C705-F5E9-4BA9-9750-4357DB29AABF")] public class C { [Storable] public C[][] allCs; [Storable] public KeyValuePair, C> kvpList; } public class NonSerializable { int x = 0; public override bool Equals(object obj) { NonSerializable ns = obj as NonSerializable; if (ns == null) throw new NotSupportedException(); return ns.x == x; } public override int GetHashCode() { return x.GetHashCode(); } } public class SimpleClass { public double x { get; set; } public int y { get; set; } } #endregion [TestClass] public class UseCasesPersistenceNew { #region Helpers private string tempFile; [ClassInitialize] public static void Initialize(TestContext testContext) { ConfigurationService.Instance.Reset(); } [TestInitialize()] public void CreateTempFile() { tempFile = Path.GetTempFileName(); } [TestCleanup()] public void ClearTempFile() { StreamReader reader = new StreamReader(tempFile); string s = reader.ReadToEnd(); reader.Close(); File.Delete(tempFile); } #endregion #region Persistence 4.0 Profiling Helpers public class PerformanceData { public TimeSpan OldSerializingTime { get; set; } public TimeSpan NewSerializingTime { get; set; } public TimeSpan OldDeserializingTime { get; set; } public TimeSpan NewDeserializingTime { get; set; } public long OldFileSize { get; set; } public long NewFileSize { get; set; } public long OldSerializingMemoryConsumed { get; set; } public long NewSerializingMemoryConsumed { get; set; } public long OldDeserializingMemoryConsumed { get; set; } public long NewDeserializingMemoryConsumed { get; set; } } private void SerializeNew(object o) { ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(o, tempFile); } private void SerializeOld(object o) { XmlGenerator.Serialize(o, tempFile); } private object DeserializeNew() { ProtoBufSerializer serializer = new ProtoBufSerializer(); return serializer.Deserialize(tempFile); } private object DeserialiezOld() { return XmlParser.Deserialize(tempFile); } private void CollectGarbage() { GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true); GC.WaitForPendingFinalizers(); } public PerformanceData ProfileSingleRun(Func GenerateDataFunc) { PerformanceData performanceData = new PerformanceData(); Stopwatch sw = new Stopwatch(); object data = GenerateDataFunc(); object result = null; long startMem, endMem; //old file format serializing CollectGarbage(); startMem = GC.GetTotalMemory(false); sw.Start(); SerializeOld(data); sw.Stop(); endMem = GC.GetTotalMemory(false); performanceData.OldSerializingTime = sw.Elapsed; performanceData.OldFileSize = new FileInfo(tempFile).Length; performanceData.OldSerializingMemoryConsumed = endMem - startMem; sw.Reset(); //old file format deserializing CollectGarbage(); startMem = GC.GetTotalMemory(false); sw.Start(); result = DeserialiezOld(); sw.Stop(); endMem = GC.GetTotalMemory(false); performanceData.OldDeserializingTime = sw.Elapsed; performanceData.OldDeserializingMemoryConsumed = endMem - startMem; sw.Reset(); //new file format serializing CollectGarbage(); startMem = GC.GetTotalMemory(false); sw.Start(); SerializeNew(data); sw.Stop(); endMem = GC.GetTotalMemory(false); performanceData.NewSerializingTime = sw.Elapsed; performanceData.NewSerializingMemoryConsumed = endMem - startMem; performanceData.NewFileSize = new FileInfo(tempFile).Length; sw.Reset(); //new file format deserializing CollectGarbage(); startMem = GC.GetTotalMemory(false); sw.Start(); result = DeserializeNew(); sw.Stop(); endMem = GC.GetTotalMemory(false); performanceData.NewDeserializingTime = sw.Elapsed; performanceData.NewDeserializingMemoryConsumed = endMem - startMem; sw.Reset(); return performanceData; } public string Profile(Func GenerateDataFunc) { int nrOfRepetitions = 100; StringBuilder report = new StringBuilder(); List dataList = new List(); for (int i = 0; i < nrOfRepetitions; i++) { dataList.Add(ProfileSingleRun(GenerateDataFunc)); } report.Append("Performance Report for " + GenerateDataFunc.Method.Name + ": " + Environment.NewLine); report.Append(Environment.NewLine); report.AppendFormat("Avg. old vs. new time for serializing a file: {0} / {1}; Factor: {2}", dataList.Select(x => x.OldSerializingTime).Average(), dataList.Select(x => x.NewSerializingTime).Average(), dataList.Select(x => x.OldSerializingTime.TotalMilliseconds).Average() / dataList.Select(x => x.NewSerializingTime.TotalMilliseconds).Average() ); report.Append(Environment.NewLine); report.AppendFormat("Avg. old vs. new time for deserializing a file: {0} / {1}; Factor: {2}", dataList.Select(x => x.OldDeserializingTime).Average(), dataList.Select(x => x.NewDeserializingTime).Average(), dataList.Select(x => x.OldDeserializingTime.TotalMilliseconds).Average() / dataList.Select(x => x.NewDeserializingTime.TotalMilliseconds).Average() ); report.Append(Environment.NewLine); report.AppendFormat("Avg. old vs. new file size (in bytes): {0} / {1}; Factor: {2}", dataList.Select(x => x.OldFileSize).Average(), dataList.Select(x => x.NewFileSize).Average(), dataList.Select(x => x.OldFileSize).Average() / dataList.Select(x => x.NewFileSize).Average() ); report.Append(Environment.NewLine); report.AppendFormat("Avg. old vs. new memory consumption for serializing a file (in bytes): {0} / {1}; Factor: {2}", dataList.Select(x => x.OldSerializingMemoryConsumed).Average(), dataList.Select(x => x.NewSerializingMemoryConsumed).Average(), dataList.Select(x => x.OldSerializingMemoryConsumed).Average() / dataList.Select(x => x.NewSerializingMemoryConsumed).Average() ); report.Append(Environment.NewLine); report.AppendFormat("Avg. old vs. new memory consumption for deserializing a file (in bytes): {0} / {1}; Factor: {2}", dataList.Select(x => x.OldDeserializingMemoryConsumed).Average(), dataList.Select(x => x.NewDeserializingMemoryConsumed).Average(), dataList.Select(x => x.OldDeserializingMemoryConsumed).Average() / dataList.Select(x => x.NewDeserializingMemoryConsumed).Average() ); report.Append(Environment.NewLine); return report.ToString(); } #endregion #region Persistence 4.0 test methods [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestBool() { var test = new Func(() => { return true; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); bool result = (bool)o; Assert.AreEqual(test(), result); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestInt() { var test = new Func(() => { return (int)42; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); int result = (int)o; Assert.AreEqual(test(), result); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestDouble() { var test = new Func(() => { return 42.5d; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); double result = (double)o; Assert.AreEqual(test(), result); Assert.IsTrue(o is double); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestFloat() { var test = new Func(() => { return 42.5f; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); float result = (float)o; Assert.AreEqual(test(), result); Assert.IsTrue(o is float); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestDecimal() { var test = new Func(() => { return 42.5m; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); decimal result = (decimal)o; Assert.AreEqual(test(), result); Assert.IsTrue(o is decimal); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestLong() { var test = new Func(() => { return 42l; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); long result = (long)o; Assert.AreEqual(test(), result); Assert.IsTrue(o is long); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestUInt() { var test = new Func(() => { return 42u; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); uint result = (uint)o; Assert.AreEqual(test(), result); Assert.IsTrue(o is uint); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestShort() { var test = new Func(() => { short s = 42; return s; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); short result = (short)o; Assert.IsTrue(o is short); Assert.AreEqual(test(), result); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestByte() { var test = new Func(() => { byte b = 42; return b; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); byte result = (byte)o; Assert.IsTrue(o is byte); Assert.AreEqual(test(), result); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestEnumSimple() { var test = new Func(() => { return SimpleEnum.two; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); SimpleEnum result = (SimpleEnum)o; Assert.AreEqual(test(), result); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestEnumComplex() { var test = new Func(() => { return ComplexEnum.three; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); ComplexEnum result = (ComplexEnum)o; Assert.AreEqual(test(), result); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestType() { var test = new Func(() => { return typeof(HeuristicLab.Algorithms.GeneticAlgorithm.GeneticAlgorithm); }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); Type result = (Type)o; Assert.AreEqual(test(), result); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestBytes() { var test = new Func(() => { return new byte[] { 3, 1 }; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); byte[] result = (byte[])o; Assert.AreEqual(test()[0], result[0]); Assert.AreEqual(test()[1], result[1]); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestString() { var test = new Func(() => { return "Hello World!"; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); string result = (string)o; Assert.AreEqual(test(), result); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestColor() { var test = new Func(() => { return Color.DeepSkyBlue; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); Color result = (Color)o; Assert.AreEqual(test(), result); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestPoint() { var test = new Func(() => { return new Point(3, 4); }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); Point result = (Point)o; Assert.AreEqual(((Point)test()).X, result.X); Assert.AreEqual(((Point)test()).Y, result.Y); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestBoolArray() { var test = new Func(() => { return new[] { true, false, true }; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); bool[] result = (bool[])o; Assert.AreEqual(test()[0], result[0]); Assert.AreEqual(test()[1], result[1]); Assert.AreEqual(test()[2], result[2]); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestIntArray() { var test = new Func(() => { return new[] { 41, 22, 13 }; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); int[] result = (int[])o; Assert.AreEqual(test()[0], result[0]); Assert.AreEqual(test()[1], result[1]); Assert.AreEqual(test()[2], result[2]); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestLongArray() { var test = new Func(() => { return new[] { 414481188112191633l, 245488586662l, 13546881335845865l }; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); long[] result = (long[])o; Assert.AreEqual(test()[0], result[0]); Assert.AreEqual(test()[1], result[1]); Assert.AreEqual(test()[2], result[2]); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestDoubleArray() { var test = new Func(() => { return new[] { 41.5, 22.7, 13.8 }; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); double[] result = (double[])o; Assert.AreEqual(test()[0], result[0]); Assert.AreEqual(test()[1], result[1]); Assert.AreEqual(test()[2], result[2]); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestObjectArray() { var test = new Func(() => { return new[] { new SimpleClass() { x = 42, y = 43 }, new SimpleClass() { x = 44.44, y = 5677 }, new SimpleClass() { x = 533.33, y = 2345 } }; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); SimpleClass[] result = (SimpleClass[])o; Assert.AreEqual(test()[0].x, result[0].x); Assert.AreEqual(test()[0].y, result[0].y); Assert.AreEqual(test()[1].x, result[1].x); Assert.AreEqual(test()[1].y, result[1].y); Assert.AreEqual(test()[2].x, result[2].x); Assert.AreEqual(test()[2].y, result[2].y); string msg = Profile(test); Console.WriteLine(msg); } [TestMethod] [TestCategory("Persistence4")] [TestProperty("Time", "short")] public void TestIntValueArray() { var test = new Func(() => { return new[] { new IntValue(41), new IntValue(22), new IntValue(13) }; }); ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(test(), tempFile); object o = serializer.Deserialize(tempFile); IntValue[] result = (IntValue[])o; Assert.AreEqual(test()[0], result[0]); Assert.AreEqual(test()[1], result[1]); Assert.AreEqual(test()[2], result[2]); string msg = Profile(test); Console.WriteLine(msg); } #endregion #region Old persistence test methods [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void ComplexStorable() { ProtoBufSerializer serializer = new ProtoBufSerializer(); Root r = InitializeComplexStorable(); serializer.Serialize(r, tempFile); Root newR = (Root)serializer.Deserialize(tempFile); CompareComplexStorables(r, newR); } private static void CompareComplexStorables(Root r, Root newR) { Assert.AreEqual( DebugStringGenerator.Serialize(r), DebugStringGenerator.Serialize(newR)); Assert.AreSame(newR, newR.selfReferences[0]); Assert.AreNotSame(r, newR); Assert.AreEqual(r.myEnum, TestEnum.va1); Assert.AreEqual(r.i[0], 7); Assert.AreEqual(r.i[1], 5); Assert.AreEqual(r.i[2], 6); Assert.AreEqual(r.s, "new value"); Assert.AreEqual(r.intArray[0], 3); Assert.AreEqual(r.intArray[1], 2); Assert.AreEqual(r.intArray[2], 1); Assert.AreEqual(r.intList[0], 9); Assert.AreEqual(r.intList[1], 8); Assert.AreEqual(r.intList[2], 7); Assert.AreEqual(r.multiDimArray[0, 0], 5); Assert.AreEqual(r.multiDimArray[0, 1], 4); Assert.AreEqual(r.multiDimArray[0, 2], 3); Assert.AreEqual(r.multiDimArray[1, 0], 1); Assert.AreEqual(r.multiDimArray[1, 1], 4); Assert.AreEqual(r.multiDimArray[1, 2], 6); Assert.IsFalse(r.boolean); Assert.IsTrue((DateTime.Now - r.dateTime).TotalSeconds < 10); Assert.AreEqual(r.kvp.Key, "string key"); Assert.AreEqual(r.kvp.Value, 321); Assert.IsNull(r.uninitialized); Assert.AreEqual(newR.myEnum, TestEnum.va1); Assert.AreEqual(newR.i[0], 7); Assert.AreEqual(newR.i[1], 5); Assert.AreEqual(newR.i[2], 6); Assert.AreEqual(newR.s, "new value"); Assert.AreEqual(newR.intArray[0], 3); Assert.AreEqual(newR.intArray[1], 2); Assert.AreEqual(newR.intArray[2], 1); Assert.AreEqual(newR.intList[0], 9); Assert.AreEqual(newR.intList[1], 8); Assert.AreEqual(newR.intList[2], 7); Assert.AreEqual(newR.multiDimArray[0, 0], 5); Assert.AreEqual(newR.multiDimArray[0, 1], 4); Assert.AreEqual(newR.multiDimArray[0, 2], 3); Assert.AreEqual(newR.multiDimArray[1, 0], 1); Assert.AreEqual(newR.multiDimArray[1, 1], 4); Assert.AreEqual(newR.multiDimArray[1, 2], 6); Assert.AreEqual(newR.intStack.Pop(), 3); Assert.AreEqual(newR.intStack.Pop(), 2); Assert.AreEqual(newR.intStack.Pop(), 1); Assert.IsFalse(newR.boolean); Assert.IsTrue((DateTime.Now - newR.dateTime).TotalSeconds < 10); Assert.AreEqual(newR.kvp.Key, "string key"); Assert.AreEqual(newR.kvp.Value, 321); Assert.IsNull(newR.uninitialized); } private static Root InitializeComplexStorable() { Root r = new Root(); r.intStack.Push(1); r.intStack.Push(2); r.intStack.Push(3); r.selfReferences = new List { r, r }; r.c = new Custom { r = r }; r.dict.Add("one", 1); r.dict.Add("two", 2); r.dict.Add("three", 3); r.myEnum = TestEnum.va1; r.i = new[] { 7, 5, 6 }; r.s = "new value"; r.intArray = new ArrayList { 3, 2, 1 }; r.intList = new List { 9, 8, 7 }; r.multiDimArray = new double[,] { { 5, 4, 3 }, { 1, 4, 6 } }; r.boolean = false; r.dateTime = DateTime.Now; r.kvp = new KeyValuePair("string key", 321); r.uninitialized = null; return r; } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void SelfReferences() { ProtoBufSerializer serializer = new ProtoBufSerializer(); C c = new C(); C[][] cs = new C[2][]; cs[0] = new C[] { c }; cs[1] = new C[] { c }; c.allCs = cs; c.kvpList = new KeyValuePair, C>(new List { c }, c); serializer.Serialize(cs, tempFile); object o = serializer.Deserialize(tempFile); Assert.AreEqual( DebugStringGenerator.Serialize(cs), DebugStringGenerator.Serialize(o)); Assert.AreSame(c, c.allCs[0][0]); Assert.AreSame(c, c.allCs[1][0]); Assert.AreSame(c, c.kvpList.Key[0]); Assert.AreSame(c, c.kvpList.Value); C[][] newCs = (C[][])o; C newC = newCs[0][0]; Assert.AreSame(newC, newC.allCs[0][0]); Assert.AreSame(newC, newC.allCs[1][0]); Assert.AreSame(newC, newC.kvpList.Key[0]); Assert.AreSame(newC, newC.kvpList.Value); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void ArrayCreation() { ProtoBufSerializer serializer = new ProtoBufSerializer(); ArrayList[] arrayListArray = new ArrayList[4]; arrayListArray[0] = new ArrayList(); arrayListArray[0].Add(arrayListArray); arrayListArray[0].Add(arrayListArray); arrayListArray[1] = new ArrayList(); arrayListArray[1].Add(arrayListArray); arrayListArray[2] = new ArrayList(); arrayListArray[2].Add(arrayListArray); arrayListArray[2].Add(arrayListArray); Array a = Array.CreateInstance( typeof(object), new[] { 1, 2 }, new[] { 3, 4 }); arrayListArray[2].Add(a); serializer.Serialize(arrayListArray, tempFile); object o = serializer.Deserialize(tempFile); Assert.AreEqual( DebugStringGenerator.Serialize(arrayListArray), DebugStringGenerator.Serialize(o)); ArrayList[] newArray = (ArrayList[])o; Assert.AreSame(arrayListArray, arrayListArray[0][0]); Assert.AreSame(arrayListArray, arrayListArray[2][1]); Assert.AreSame(newArray, newArray[0][0]); Assert.AreSame(newArray, newArray[2][1]); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void CustomSerializationProperty() { ProtoBufSerializer serializer = new ProtoBufSerializer(); Manager m = new Manager(); serializer.Serialize(m, tempFile); Manager newM = (Manager)serializer.Deserialize(tempFile); Assert.AreNotEqual( DebugStringGenerator.Serialize(m), DebugStringGenerator.Serialize(newM)); Assert.AreEqual(m.dbl, newM.dbl); Assert.AreEqual(m.lastLoadTime, new DateTime()); Assert.AreNotEqual(newM.lastLoadTime, new DateTime()); Assert.IsTrue((DateTime.Now - newM.lastLoadTime).TotalSeconds < 10); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void Primitives() { ProtoBufSerializer serializer = new ProtoBufSerializer(); PrimitivesTest sdt = new PrimitivesTest(); serializer.Serialize(sdt, tempFile); object o = serializer.Deserialize(tempFile); Assert.AreEqual( DebugStringGenerator.Serialize(sdt), DebugStringGenerator.Serialize(o)); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void MultiDimensionalArray() { ProtoBufSerializer serializer = new ProtoBufSerializer(); string[,] mDimString = new string[,] { {"ora", "et", "labora"}, {"Beten", "und", "Arbeiten"} }; serializer.Serialize(mDimString, tempFile); object o = serializer.Deserialize(tempFile); Assert.AreEqual( DebugStringGenerator.Serialize(mDimString), DebugStringGenerator.Serialize(o)); } [StorableClass("87A331AF-14DC-48B3-B577-D49065743BE6")] public class NestedType { [Storable] private string value = "value"; public override bool Equals(object obj) { NestedType nt = obj as NestedType; if (nt == null) throw new NotSupportedException(); return nt.value == value; } public override int GetHashCode() { return value.GetHashCode(); } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void NestedTypeTest() { ProtoBufSerializer serializer = new ProtoBufSerializer(); NestedType t = new NestedType(); serializer.Serialize(t, tempFile); object o = serializer.Deserialize(tempFile); Assert.AreEqual( DebugStringGenerator.Serialize(t), DebugStringGenerator.Serialize(o)); Assert.IsTrue(t.Equals(o)); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void SimpleArray() { ProtoBufSerializer serializer = new ProtoBufSerializer(); string[] strings = { "ora", "et", "labora" }; serializer.Serialize(strings, tempFile); object o = serializer.Deserialize(tempFile); Assert.AreEqual( DebugStringGenerator.Serialize(strings), DebugStringGenerator.Serialize(o)); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void PrimitiveRoot() { ProtoBufSerializer serializer = new ProtoBufSerializer(); serializer.Serialize(12.3f, tempFile); object o = serializer.Deserialize(tempFile); Assert.AreEqual( DebugStringGenerator.Serialize(12.3f), DebugStringGenerator.Serialize(o)); } private string formatFullMemberName(MemberInfo mi) { return new StringBuilder() .Append(mi.DeclaringType.Assembly.GetName().Name) .Append(": ") .Append(mi.DeclaringType.Namespace) .Append('.') .Append(mi.DeclaringType.Name) .Append('.') .Append(mi.Name).ToString(); } public void CodingConventions() { List lowerCaseMethodNames = new List(); List lowerCaseProperties = new List(); List lowerCaseFields = new List(); foreach (Assembly a in PluginLoader.Assemblies) { if (!a.GetName().Name.StartsWith("HeuristicLab")) continue; foreach (Type t in a.GetTypes()) { foreach (MemberInfo mi in t.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) { if (mi.DeclaringType.Name.StartsWith("<>")) continue; if (char.IsLower(mi.Name[0])) { if (mi.MemberType == MemberTypes.Field) lowerCaseFields.Add(formatFullMemberName(mi)); if (mi.MemberType == MemberTypes.Property) lowerCaseProperties.Add(formatFullMemberName(mi)); if (mi.MemberType == MemberTypes.Method && !mi.Name.StartsWith("get_") && !mi.Name.StartsWith("set_") && !mi.Name.StartsWith("add_") && !mi.Name.StartsWith("remove_") && !mi.Name.StartsWith("op_")) lowerCaseMethodNames.Add(formatFullMemberName(mi)); } } } } //Assert.AreEqual("", lowerCaseFields.Aggregate("", (a, b) => a + "\r\n" + b)); Assert.AreEqual("", lowerCaseMethodNames.Aggregate("", (a, b) => a + "\r\n" + b)); Assert.AreEqual("", lowerCaseProperties.Aggregate("", (a, b) => a + "\r\n" + b)); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void Enums() { ProtoBufSerializer serializer = new ProtoBufSerializer(); EnumTest et = new EnumTest(); et.simpleEnum = SimpleEnum.two; et.complexEnum = ComplexEnum.three; et.trickyEnum = TrickyEnum.two | TrickyEnum.one; serializer.Serialize(et, tempFile); EnumTest newEt = (EnumTest)serializer.Deserialize(tempFile); Assert.AreEqual(et.simpleEnum, SimpleEnum.two); Assert.AreEqual(et.complexEnum, ComplexEnum.three); Assert.AreEqual(et.trickyEnum, (TrickyEnum)3); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestAliasingWithOverriddenEquals() { ProtoBufSerializer serializer = new ProtoBufSerializer(); List ints = new List(); ints.Add(new IntWrapper(1)); ints.Add(new IntWrapper(1)); Assert.AreEqual(ints[0], ints[1]); Assert.AreNotSame(ints[0], ints[1]); serializer.Serialize(ints, tempFile); List newInts = (List)serializer.Deserialize(tempFile); Assert.AreEqual(newInts[0].Value, 1); Assert.AreEqual(newInts[1].Value, 1); Assert.AreEqual(newInts[0], newInts[1]); Assert.AreNotSame(newInts[0], newInts[1]); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void NonDefaultConstructorTest() { ProtoBufSerializer serializer = new ProtoBufSerializer(); NonDefaultConstructorClass c = new NonDefaultConstructorClass(1); try { serializer.Serialize(c, tempFile); Assert.Fail("Exception not thrown"); } catch (PersistenceException) { } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestSavingException() { ProtoBufSerializer serializer = new ProtoBufSerializer(); List list = new List { 1, 2, 3 }; serializer.Serialize(list, tempFile); NonSerializable s = new NonSerializable(); try { serializer.Serialize(s, tempFile); Assert.Fail("Exception expected"); } catch (PersistenceException) { } List newList = (List)serializer.Deserialize(tempFile); Assert.AreEqual(list[0], newList[0]); Assert.AreEqual(list[1], newList[1]); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestTypeStringConversion() { string name = typeof(List[]).AssemblyQualifiedName; string shortName = "System.Collections.Generic.List`1[[System.Int32, mscorlib]][], mscorlib"; Assert.AreEqual(name, TypeNameParser.Parse(name).ToString()); Assert.AreEqual(shortName, TypeNameParser.Parse(name).ToString(false)); Assert.AreEqual(shortName, typeof(List[]).VersionInvariantName()); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestHexadecimalPublicKeyToken() { string name = "TestClass, TestAssembly, Version=1.2.3.4, PublicKey=1234abc"; string shortName = "TestClass, TestAssembly"; Assert.AreEqual(name, TypeNameParser.Parse(name).ToString()); Assert.AreEqual(shortName, TypeNameParser.Parse(name).ToString(false)); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void InheritanceTest() { ProtoBufSerializer serializer = new ProtoBufSerializer(); New n = new New(); serializer.Serialize(n, tempFile); New nn = (New)serializer.Deserialize(tempFile); Assert.AreEqual(n.Name, nn.Name); Assert.AreEqual(((Override)n).Name, ((Override)nn).Name); } [StorableClass("B963EF51-12B4-432E-8C54-88F026F9ACE2")] class Child { [Storable] public GrandParent grandParent; } [StorableClass("E66E9606-967A-4C35-A361-F6F0D21C064A")] class Parent { [Storable] public Child child; } [StorableClass("34D3893A-57AD-4F72-878B-81D6FA3F14A9")] class GrandParent { [Storable] public Parent parent; } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void InstantiateParentChainReference() { ProtoBufSerializer serializer = new ProtoBufSerializer(); GrandParent gp = new GrandParent(); gp.parent = new Parent(); gp.parent.child = new Child(); gp.parent.child.grandParent = gp; Assert.AreSame(gp, gp.parent.child.grandParent); serializer.Serialize(gp, tempFile); GrandParent newGp = (GrandParent)serializer.Deserialize(tempFile); Assert.AreSame(newGp, newGp.parent.child.grandParent); } struct TestStruct { int value; int PropertyValue { get; set; } public TestStruct(int value) : this() { this.value = value; PropertyValue = value; } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void StructTest() { ProtoBufSerializer serializer = new ProtoBufSerializer(); TestStruct s = new TestStruct(10); serializer.Serialize(s, tempFile); TestStruct newS = (TestStruct)serializer.Deserialize(tempFile); Assert.AreEqual(s, newS); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void PointTest() { ProtoBufSerializer serializer = new ProtoBufSerializer(); Point p = new Point(12, 34); serializer.Serialize(p, tempFile); Point newP = (Point)serializer.Deserialize(tempFile); Assert.AreEqual(p, newP); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void NullableValueTypes() { ProtoBufSerializer serializer = new ProtoBufSerializer(); double?[] d = new double?[] { null, 1, 2, 3 }; serializer.Serialize(d, tempFile); double?[] newD = (double?[])serializer.Deserialize(tempFile); Assert.AreEqual(d[0], newD[0]); Assert.AreEqual(d[1], newD[1]); Assert.AreEqual(d[2], newD[2]); Assert.AreEqual(d[3], newD[3]); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void BitmapTest() { ProtoBufSerializer serializer = new ProtoBufSerializer(); Icon icon = System.Drawing.SystemIcons.Hand; Bitmap bitmap = icon.ToBitmap(); serializer.Serialize(bitmap, tempFile); Bitmap newBitmap = (Bitmap)serializer.Deserialize(tempFile); Assert.AreEqual(bitmap.Size, newBitmap.Size); for (int i = 0; i < bitmap.Size.Width; i++) for (int j = 0; j < bitmap.Size.Height; j++) Assert.AreEqual(bitmap.GetPixel(i, j), newBitmap.GetPixel(i, j)); } [StorableClass("E846BC49-20F3-4D3F-A3F3-73D4F2DB1C2E")] private class PersistenceHooks { [Storable] public int a; [Storable] public int b; public int sum; public bool WasSerialized { get; private set; } [StorableHook(HookType.BeforeSerialization)] void PreSerializationHook() { WasSerialized = true; } [StorableHook(HookType.AfterDeserialization)] void PostDeserializationHook() { sum = a + b; } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void HookTest() { ProtoBufSerializer serializer = new ProtoBufSerializer(); PersistenceHooks hookTest = new PersistenceHooks(); hookTest.a = 2; hookTest.b = 5; Assert.IsFalse(hookTest.WasSerialized); Assert.AreEqual(hookTest.sum, 0); serializer.Serialize(hookTest, tempFile); Assert.IsTrue(hookTest.WasSerialized); Assert.AreEqual(hookTest.sum, 0); PersistenceHooks newHookTest = (PersistenceHooks)serializer.Deserialize(tempFile); Assert.AreEqual(newHookTest.a, hookTest.a); Assert.AreEqual(newHookTest.b, hookTest.b); Assert.AreEqual(newHookTest.sum, newHookTest.a + newHookTest.b); Assert.IsFalse(newHookTest.WasSerialized); } [StorableClass("A35D71DF-397F-4910-A950-ED6923BE9483")] private class CustomConstructor { public string Value = "none"; public CustomConstructor() { Value = "default"; } [StorableConstructor] private CustomConstructor(bool deserializing) { Assert.IsTrue(deserializing); Value = "persistence"; } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestCustomConstructor() { ProtoBufSerializer serializer = new ProtoBufSerializer(); CustomConstructor cc = new CustomConstructor(); Assert.AreEqual(cc.Value, "default"); serializer.Serialize(cc, tempFile); CustomConstructor newCC = (CustomConstructor)serializer.Deserialize(tempFile); Assert.AreEqual(newCC.Value, "persistence"); } [StorableClass("D276E825-1F35-4BAC-8937-9ABC91D5C316")] public class ExplodingDefaultConstructor { public ExplodingDefaultConstructor() { throw new Exception("this constructor will always fail"); } public ExplodingDefaultConstructor(string password) { } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestConstructorExceptionUnwrapping() { ProtoBufSerializer serializer = new ProtoBufSerializer(); ExplodingDefaultConstructor x = new ExplodingDefaultConstructor("password"); serializer.Serialize(x, tempFile); try { ExplodingDefaultConstructor newX = (ExplodingDefaultConstructor)serializer.Deserialize(tempFile); Assert.Fail("Exception expected"); } catch (PersistenceException pe) { Assert.AreEqual(pe.InnerException.Message, "this constructor will always fail"); } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestRejectionJustifications() { ProtoBufSerializer serializer = new ProtoBufSerializer(); NonSerializable ns = new NonSerializable(); try { serializer.Serialize(ns, tempFile); Assert.Fail("PersistenceException expected"); } catch (PersistenceException x) { Assert.IsTrue(x.Message.Contains(new StorableSerializer().JustifyRejection(typeof(NonSerializable)))); } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestStreaming() { ProtoBufSerializer serializer = new ProtoBufSerializer(); using (MemoryStream stream = new MemoryStream()) { Root r = InitializeComplexStorable(); serializer.Serialize(r, stream); using (MemoryStream stream2 = new MemoryStream(stream.ToArray())) { Root newR = (Root)serializer.Deserialize(stream2); CompareComplexStorables(r, newR); } } } [StorableClass("4921031B-CB61-4677-97AD-9236A4CEC200")] public class HookInheritanceTestBase { [Storable] public object a; public object link; [StorableHook(HookType.AfterDeserialization)] private void relink() { link = a; } } [StorableClass("321CEE0A-5201-4CE2-B135-2343890D96BF")] public class HookInheritanceTestDerivedClass : HookInheritanceTestBase { [Storable] public object b; [StorableHook(HookType.AfterDeserialization)] private void relink() { Assert.AreSame(a, link); link = b; } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestLinkInheritance() { ProtoBufSerializer serializer = new ProtoBufSerializer(); HookInheritanceTestDerivedClass c = new HookInheritanceTestDerivedClass(); c.a = new object(); serializer.Serialize(c, tempFile); HookInheritanceTestDerivedClass newC = (HookInheritanceTestDerivedClass)serializer.Deserialize(tempFile); Assert.AreSame(c.b, c.link); } [StorableClass(StorableClassType.AllFields, "B9AB42E8-1932-425B-B4CF-F31F07EAC599")] public class AllFieldsStorable { public int Value1 = 1; [Storable] public int Value2 = 2; public int Value3 { get; private set; } public int Value4 { get; private set; } [StorableConstructor] public AllFieldsStorable(bool isDeserializing) { if (!isDeserializing) { Value1 = 12; Value2 = 23; Value3 = 34; Value4 = 56; } } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestStorableClassDiscoveryAllFields() { ProtoBufSerializer serializer = new ProtoBufSerializer(); AllFieldsStorable afs = new AllFieldsStorable(false); serializer.Serialize(afs, tempFile); AllFieldsStorable newAfs = (AllFieldsStorable)serializer.Deserialize(tempFile); Assert.AreEqual(afs.Value1, newAfs.Value1); Assert.AreEqual(afs.Value2, newAfs.Value2); Assert.AreEqual(0, newAfs.Value3); Assert.AreEqual(0, newAfs.Value4); } [StorableClass(StorableClassType.AllProperties, "CB7DC31C-AEF3-4EB8-91CA-248B767E9F92")] public class AllPropertiesStorable { public int Value1 = 1; [Storable] public int Value2 = 2; public int Value3 { get; private set; } public int Value4 { get; private set; } [StorableConstructor] public AllPropertiesStorable(bool isDeserializing) { if (!isDeserializing) { Value1 = 12; Value2 = 23; Value3 = 34; Value4 = 56; } } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestStorableClassDiscoveryAllProperties() { ProtoBufSerializer serializer = new ProtoBufSerializer(); AllPropertiesStorable afs = new AllPropertiesStorable(false); serializer.Serialize(afs, tempFile); AllPropertiesStorable newAfs = (AllPropertiesStorable)serializer.Deserialize(tempFile); Assert.AreEqual(1, newAfs.Value1); Assert.AreEqual(2, newAfs.Value2); Assert.AreEqual(afs.Value3, newAfs.Value3); Assert.AreEqual(afs.Value4, newAfs.Value4); } [StorableClass(StorableClassType.AllFieldsAndAllProperties, "0AD8D68F-E0FF-4FA8-8A72-1148CD91A2B9")] public class AllFieldsAndAllPropertiesStorable { public int Value1 = 1; [Storable] public int Value2 = 2; public int Value3 { get; private set; } public int Value4 { get; private set; } [StorableConstructor] public AllFieldsAndAllPropertiesStorable(bool isDeserializing) { if (!isDeserializing) { Value1 = 12; Value2 = 23; Value3 = 34; Value4 = 56; } } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestStorableClassDiscoveryAllFieldsAndAllProperties() { ProtoBufSerializer serializer = new ProtoBufSerializer(); AllFieldsAndAllPropertiesStorable afs = new AllFieldsAndAllPropertiesStorable(false); serializer.Serialize(afs, tempFile); AllFieldsAndAllPropertiesStorable newAfs = (AllFieldsAndAllPropertiesStorable)serializer.Deserialize(tempFile); Assert.AreEqual(afs.Value1, newAfs.Value1); Assert.AreEqual(afs.Value2, newAfs.Value2); Assert.AreEqual(afs.Value3, newAfs.Value3); Assert.AreEqual(afs.Value4, newAfs.Value4); } [StorableClass(StorableClassType.MarkedOnly, "0D94E6D4-64E3-4637-B1EE-DEF2B3F6E2E0")] public class MarkedOnlyStorable { public int Value1 = 1; [Storable] public int Value2 = 2; public int Value3 { get; private set; } public int Value4 { get; private set; } [StorableConstructor] public MarkedOnlyStorable(bool isDeserializing) { if (!isDeserializing) { Value1 = 12; Value2 = 23; Value3 = 34; Value4 = 56; } } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestStorableClassDiscoveryMarkedOnly() { ProtoBufSerializer serializer = new ProtoBufSerializer(); MarkedOnlyStorable afs = new MarkedOnlyStorable(false); serializer.Serialize(afs, tempFile); MarkedOnlyStorable newAfs = (MarkedOnlyStorable)serializer.Deserialize(tempFile); Assert.AreEqual(1, newAfs.Value1); Assert.AreEqual(afs.Value2, newAfs.Value2); Assert.AreEqual(0, newAfs.Value3); Assert.AreEqual(0, newAfs.Value4); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestLineEndings() { ProtoBufSerializer serializer = new ProtoBufSerializer(); List lineBreaks = new List { "\r\n", "\n", "\r", "\n\r", Environment.NewLine }; List lines = new List(); foreach (var br in lineBreaks) lines.Add("line1" + br + "line2"); serializer.Serialize(lines, tempFile); List newLines = (List)serializer.Deserialize(tempFile); Assert.AreEqual(lines.Count, newLines.Count); for (int i = 0; i < lineBreaks.Count; i++) { Assert.AreEqual(lines[i], newLines[i]); } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestSpecialNumbers() { ProtoBufSerializer serializer = new ProtoBufSerializer(); List specials = new List() { 1.0 / 0, -1.0 / 0, 0.0 / 0 }; Assert.IsTrue(double.IsPositiveInfinity(specials[0])); Assert.IsTrue(double.IsNegativeInfinity(specials[1])); Assert.IsTrue(double.IsNaN(specials[2])); serializer.Serialize(specials, tempFile); List newSpecials = (List)serializer.Deserialize(tempFile); Assert.IsTrue(double.IsPositiveInfinity(newSpecials[0])); Assert.IsTrue(double.IsNegativeInfinity(newSpecials[1])); Assert.IsTrue(double.IsNaN(newSpecials[2])); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestStringSplit() { string s = "1.2;2.3;3.4;;;4.9"; var l = s.EnumerateSplit(';').ToList(); Assert.AreEqual("1.2", l[0]); Assert.AreEqual("2.3", l[1]); Assert.AreEqual("3.4", l[2]); Assert.AreEqual("4.9", l[3]); } private class IdentityComparer : IEqualityComparer { public bool Equals(T x, T y) { return x.Equals(y); } public int GetHashCode(T obj) { return obj.GetHashCode(); } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestHashSetSerializer() { ProtoBufSerializer serializer = new ProtoBufSerializer(); var hashSets = new List>() { new HashSet(new[] { 1, 2, 3 }), new HashSet(new[] { 4, 5, 6 }, new IdentityComparer()), }; serializer.Serialize(hashSets, tempFile); var newHashSets = (List>)serializer.Deserialize(tempFile); Assert.IsTrue(newHashSets[0].Contains(1)); Assert.IsTrue(newHashSets[0].Contains(2)); Assert.IsTrue(newHashSets[0].Contains(3)); Assert.IsTrue(newHashSets[1].Contains(4)); Assert.IsTrue(newHashSets[1].Contains(5)); Assert.IsTrue(newHashSets[1].Contains(6)); Assert.AreEqual(newHashSets[0].Comparer.GetType(), new HashSet().Comparer.GetType()); Assert.AreEqual(newHashSets[1].Comparer.GetType(), typeof(IdentityComparer)); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestConcreteDictionarySerializer() { ProtoBufSerializer serializer = new ProtoBufSerializer(); var dictionaries = new List>() { new Dictionary(), new Dictionary(new IdentityComparer()), }; dictionaries[0].Add(1, 1); dictionaries[0].Add(2, 2); dictionaries[0].Add(3, 3); dictionaries[1].Add(4, 4); dictionaries[1].Add(5, 5); dictionaries[1].Add(6, 6); serializer.Serialize(dictionaries, tempFile); var newDictionaries = (List>)serializer.Deserialize(tempFile); Assert.IsTrue(newDictionaries[0].ContainsKey(1)); Assert.IsTrue(newDictionaries[0].ContainsKey(2)); Assert.IsTrue(newDictionaries[0].ContainsKey(3)); Assert.IsTrue(newDictionaries[1].ContainsKey(4)); Assert.IsTrue(newDictionaries[1].ContainsKey(5)); Assert.IsTrue(newDictionaries[1].ContainsKey(6)); Assert.IsTrue(newDictionaries[0].ContainsValue(1)); Assert.IsTrue(newDictionaries[0].ContainsValue(2)); Assert.IsTrue(newDictionaries[0].ContainsValue(3)); Assert.IsTrue(newDictionaries[1].ContainsValue(4)); Assert.IsTrue(newDictionaries[1].ContainsValue(5)); Assert.IsTrue(newDictionaries[1].ContainsValue(6)); Assert.AreEqual(new Dictionary().Comparer.GetType(), newDictionaries[0].Comparer.GetType()); Assert.AreEqual(typeof(IdentityComparer), newDictionaries[1].Comparer.GetType()); } [StorableClass("A9B0D7FB-0CAF-4DD7-9045-EA136F9176F7")] public class ReadOnlyFail { [Storable] public string ReadOnly { get { return "fail"; } } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestReadOnlyFail() { ProtoBufSerializer serializer = new ProtoBufSerializer(); try { serializer.Serialize(new ReadOnlyFail(), tempFile); Assert.Fail("Exception expected"); } catch (PersistenceException) { } catch { Assert.Fail("PersistenceException expected"); } } [StorableClass("2C9CC576-6823-4784-817B-37C8AF0B1C29")] public class WriteOnlyFail { [Storable] public string WriteOnly { set { throw new InvalidOperationException("this property should never be set."); } } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestWriteOnlyFail() { ProtoBufSerializer serializer = new ProtoBufSerializer(); try { serializer.Serialize(new WriteOnlyFail(), tempFile); Assert.Fail("Exception expected"); } catch (PersistenceException) { } catch { Assert.Fail("PersistenceException expected."); } } [StorableClass("8052D9E3-6DDD-4AE1-9B5B-67C6D5436512")] public class OneWayTest { public OneWayTest() { this.value = "default"; } public string value; [Storable(AllowOneWay = true)] public string ReadOnly { get { return "ReadOnly"; } } [Storable(AllowOneWay = true)] public string WriteOnly { set { this.value = value; } } } //TODO /* [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestTypeCacheExport() { ProtoBufSerializer serializer = new ProtoBufSerializer(); var test = new List>(); test.Add(new List() { 1, 2, 3 }); IEnumerable types; using (var stream = new MemoryStream()) { XmlGenerator.Serialize(test, stream, ConfigurationService.Instance.GetConfiguration(new XmlFormat()), false, out types); } List t = new List(types); // Assert.IsTrue(t.Contains(typeof(int))); not serialized as an int list is directly transformed into a string Assert.IsTrue(t.Contains(typeof(List))); Assert.IsTrue(t.Contains(typeof(List>))); Assert.AreEqual(t.Count, 2); }*/ [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TupleTest() { var t1 = Tuple.Create(1); var t2 = Tuple.Create('1', "2"); var t3 = Tuple.Create(3.0, 3f, 5); var t4 = Tuple.Create(Tuple.Create(1, 2, 3), Tuple.Create(4, 5, 6), Tuple.Create(8, 9, 10)); var tuple = Tuple.Create(t1, t2, t3, t4); XmlGenerator.Serialize(tuple, tempFile); var newTuple = XmlParser.Deserialize, Tuple, Tuple, Tuple, Tuple, Tuple>>>(tempFile); Assert.AreEqual(tuple, newTuple); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void FontTest() { ProtoBufSerializer serializer = new ProtoBufSerializer(); List fonts = new List() { new Font(FontFamily.GenericSansSerif, 12), new Font("Times New Roman", 21, FontStyle.Bold, GraphicsUnit.Pixel), new Font("Courier New", 10, FontStyle.Underline, GraphicsUnit.Document), new Font("Helvetica", 21, FontStyle.Strikeout, GraphicsUnit.Inch, 0, true), }; serializer.Serialize(fonts, tempFile); var newFonts = (List)serializer.Deserialize(tempFile); Assert.AreEqual(fonts[0], newFonts[0]); Assert.AreEqual(fonts[1], newFonts[1]); Assert.AreEqual(fonts[2], newFonts[2]); Assert.AreEqual(fonts[3], newFonts[3]); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "medium")] public void ConcurrencyTest() { ProtoBufSerializer serializer = new ProtoBufSerializer(); int n = 20; Task[] tasks = new Task[n]; for (int i = 0; i < n; i++) { tasks[i] = Task.Factory.StartNew((idx) => { byte[] data; using (var stream = new MemoryStream()) { serializer.Serialize(new GeneticAlgorithm(), stream); data = stream.ToArray(); } }, i); } Task.WaitAll(tasks); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "medium")] public void ConcurrentBitmapTest() { ProtoBufSerializer serializer = new ProtoBufSerializer(); Bitmap b = new Bitmap(300, 300); System.Random r = new System.Random(); for (int x = 0; x < b.Height; x++) { for (int y = 0; y < b.Width; y++) { b.SetPixel(x, y, Color.FromArgb(r.Next())); } } Task[] tasks = new Task[20]; byte[][] datas = new byte[tasks.Length][]; for (int i = 0; i < tasks.Length; i++) { tasks[i] = Task.Factory.StartNew((idx) => { using (var stream = new MemoryStream()) { serializer.Serialize(b, stream); datas[(int)idx] = stream.ToArray(); } }, i); } Task.WaitAll(tasks); } public class G { public class S { } public class S2 { } } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestSpecialCharacters() { ProtoBufSerializer serializer = new ProtoBufSerializer(); var s = "abc" + "\x15" + "def"; serializer.Serialize(s, tempFile); var newS = serializer.Deserialize(tempFile); Assert.AreEqual(s, newS); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestByteArray() { ProtoBufSerializer serializer = new ProtoBufSerializer(); var b = new byte[3]; b[0] = 0; b[1] = 200; b[2] = byte.MaxValue; serializer.Serialize(b, tempFile); var newB = (byte[])serializer.Deserialize(tempFile); CollectionAssert.AreEqual(b, newB); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestOptionalNumberEnumerable() { ProtoBufSerializer serializer = new ProtoBufSerializer(); var values = new List { 0, null, double.NaN, double.PositiveInfinity, double.MaxValue, 1 }; serializer.Serialize(values, tempFile); var newValues = (List)serializer.Deserialize(tempFile); CollectionAssert.AreEqual(values, newValues); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestOptionalDateTimeEnumerable() { ProtoBufSerializer serializer = new ProtoBufSerializer(); var values = new List { DateTime.MinValue, null, DateTime.Now, DateTime.Now.Add(TimeSpan.FromDays(1)), DateTime.ParseExact("10.09.2014 12:21", "dd.MM.yyyy hh:mm", CultureInfo.InvariantCulture), DateTime.MaxValue}; serializer.Serialize(values, tempFile); var newValues = (List)serializer.Deserialize(tempFile); CollectionAssert.AreEqual(values, newValues); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestStringEnumerable() { ProtoBufSerializer serializer = new ProtoBufSerializer(); var values = new List { "", null, "s", "string", string.Empty, "123", "", ")serializer.Deserialize(tempFile); CollectionAssert.AreEqual(values, newValues); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestUnicodeCharArray() { ProtoBufSerializer serializer = new ProtoBufSerializer(); var s = Encoding.UTF8.GetChars(new byte[] { 0, 1, 2, 03, 04, 05, 06, 07, 08, 09, 0xa, 0xb }); serializer.Serialize(s, tempFile); var newS = (char[])serializer.Deserialize(tempFile); CollectionAssert.AreEqual(s, newS); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestUnicode() { ProtoBufSerializer serializer = new ProtoBufSerializer(); var s = Encoding.UTF8.GetString(new byte[] { 0, 1, 2, 03, 04, 05, 06, 07, 08, 09, 0xa, 0xb }); serializer.Serialize(s, tempFile); var newS = serializer.Deserialize(tempFile); Assert.AreEqual(s, newS); } [TestMethod] [TestCategory("Persistence")] [TestProperty("Time", "short")] public void TestQueue() { ProtoBufSerializer serializer = new ProtoBufSerializer(); var q = new Queue(new[] { 1, 2, 3, 4, 0 }); serializer.Serialize(q, tempFile); var newQ = (Queue)serializer.Deserialize(tempFile); CollectionAssert.AreEqual(q, newQ); } #endregion } }