source: branches/Persistence Test/HeuristicLab.Persistence/UnitTests/UseCases.cs @ 2858

Last change on this file since 2858 was 2858, checked in by epitzer, 12 years ago

fix handling of public key token (#802)

File size: 20.0 KB
Line 
1using System;
2using System.Text;
3using System.Collections.Generic;
4using System.Linq;
5using Microsoft.VisualStudio.TestTools.UnitTesting;
6using HeuristicLab.Persistence.Core;
7using System.Collections;
8using HeuristicLab.Persistence.Default.Xml;
9using HeuristicLab.Persistence.Default.DebugString;
10using System.IO;
11using System.Reflection;
12using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
13using HeuristicLab.Persistence.Interfaces;
14using HeuristicLab.Persistence.Default.Xml.Primitive;
15using HeuristicLab.Persistence.Default.CompositeSerializers;
16using HeuristicLab.Persistence.Auxiliary;
17using System.Text.RegularExpressions;
18using HeuristicLab.Persistence.Test;
19
20namespace HeuristicLab.Persistence.UnitTest {
21
22  public class NumberTest {
23    [Storable]
24    private bool _bool = true;
25    [Storable]
26    private byte _byte = 0xFF;
27    [Storable]
28    private sbyte _sbyte = 0xF;
29    [Storable]
30    private short _short = -123;
31    [Storable]
32    private ushort _ushort = 123;
33    [Storable]
34    private int _int = -123;
35    [Storable]
36    private uint _uint = 123;
37    [Storable]
38    private long _long = 123456;
39    [Storable]
40    private ulong _ulong = 123456;
41  }
42
43  public class NonDefaultConstructorClass {
44    [Storable]
45    int value;
46    public NonDefaultConstructorClass(int value) {
47      this.value = value;
48    }
49  }
50
51  public class IntWrapper {
52
53    [Storable]
54    public int Value;
55
56    private IntWrapper() { }
57
58    public IntWrapper(int value) {
59      this.Value = value;
60    }
61
62    public override bool Equals(object obj) {
63      if (obj as IntWrapper == null)
64        return false;
65      return Value.Equals(((IntWrapper)obj).Value);
66    }
67    public override int GetHashCode() {
68      return Value.GetHashCode();
69    }
70
71  }
72
73  public class PrimitivesTest : NumberTest {
74    [Storable]
75    private char c = 'e';
76    [Storable]
77    private long[,] _long_array =
78      new long[,] { { 123, 456, }, { 789, 123 } };
79    [Storable]
80    public List<int> list = new List<int> { 1, 2, 3, 4, 5 };
81    [Storable]
82    private object o = new object();
83  }
84
85  public enum TestEnum { va1, va2, va3, va8 } ;
86
87  public class RootBase {
88    [Storable]
89    private string baseString = "   Serial  ";
90    [Storable]
91    public TestEnum myEnum = TestEnum.va3;
92  }
93
94  public class Root : RootBase {
95    [Storable]
96    public Stack<int> intStack = new Stack<int>();
97    [Storable]
98    public int[] i = new[] { 3, 4, 5, 6 };
99    [Storable(Name = "Test String")]
100    public string s;
101    [Storable]
102    public ArrayList intArray = new ArrayList(new[] { 1, 2, 3 });
103    [Storable]
104    public List<int> intList = new List<int>(new[] { 321, 312, 321 });
105    [Storable]
106    public Custom c;
107    [Storable]
108    public List<Root> selfReferences;
109    [Storable]
110    public double[,] multiDimArray = new double[,] { { 1, 2, 3 }, { 3, 4, 5 } };
111    [Storable]
112    public bool boolean = true;
113    [Storable]
114    public DateTime dateTime;
115    [Storable]
116    public KeyValuePair<string, int> kvp = new KeyValuePair<string, int>("Serial", 123);
117    [Storable]
118    public Dictionary<string, int> dict = new Dictionary<string, int>();
119    [Storable(DefaultValue = "default")]
120    public string uninitialized;
121  }
122
123  public enum SimpleEnum { one, two, three }
124  public enum ComplexEnum { one = 1, two = 2, three = 3 }
125  [FlagsAttribute]
126  public enum TrickyEnum { zero = 0, one = 1, two = 2 }
127
128  public class EnumTest {
129    [Storable]
130    public SimpleEnum simpleEnum = SimpleEnum.one;
131    [Storable]
132    public ComplexEnum complexEnum = (ComplexEnum)2;
133    [Storable]
134    public TrickyEnum trickyEnum = (TrickyEnum)15;
135  }
136
137  public class Custom {
138    [Storable]
139    public int i;
140    [Storable]
141    public Root r;
142    [Storable]
143    public string name = "<![CDATA[<![CDATA[Serial]]>]]>";
144  }
145
146  public class Manager {
147
148    public DateTime lastLoadTime;
149    [Storable]
150    private DateTime lastLoadTimePersistence {
151      get { return lastLoadTime; }
152      set { lastLoadTime = DateTime.Now; }
153    }
154    [Storable]
155    public double? dbl;
156  }
157
158  public class C {
159    [Storable]
160    public C[][] allCs;
161    [Storable]
162    public KeyValuePair<List<C>, C> kvpList;
163  }
164
165  public class NonSerializable {
166    int x;
167  }
168
169
170  [TestClass]
171  public class UseCases {
172
173    private string tempFile;
174
175    [TestInitialize()]
176    public void CreateTempFile() {
177      tempFile = Path.GetTempFileName();
178    }
179
180    [TestCleanup()]
181    public void ClearTempFile() {
182      StreamReader reader = new StreamReader(tempFile);
183      string s = reader.ReadToEnd();
184      reader.Close();
185      File.Delete(tempFile);
186    }
187
188    [TestMethod]
189    public void ComplexStorable() {
190      Root r = new Root();
191      r.intStack.Push(1);
192      r.intStack.Push(2);
193      r.intStack.Push(3);
194      r.selfReferences = new List<Root> { r, r };
195      r.c = new Custom { r = r };
196      r.dict.Add("one", 1);
197      r.dict.Add("two", 2);
198      r.dict.Add("three", 3);
199      r.myEnum = TestEnum.va1;
200      r.i = new[] { 7, 5, 6 };
201      r.s = "new value";
202      r.intArray = new ArrayList { 3, 2, 1 };
203      r.intList = new List<int> { 9, 8, 7 };
204      r.multiDimArray = new double[,] { { 5, 4, 3 }, { 1, 4, 6 } };
205      r.boolean = false;
206      r.dateTime = DateTime.Now;
207      r.kvp = new KeyValuePair<string, int>("string key", 321);
208      r.uninitialized = null;
209      XmlGenerator.Serialize(r, tempFile);
210      Root newR = (Root)XmlParser.Deserialize(tempFile);
211      Assert.AreEqual(
212        DebugStringGenerator.Serialize(r),
213        DebugStringGenerator.Serialize(newR));
214      Assert.AreSame(newR, newR.selfReferences[0]);
215      Assert.AreNotSame(r, newR);
216      Assert.AreEqual(r.myEnum, TestEnum.va1);
217      Assert.AreEqual(r.i[0], 7);
218      Assert.AreEqual(r.i[1], 5);
219      Assert.AreEqual(r.i[2], 6);
220      Assert.AreEqual(r.s, "new value");
221      Assert.AreEqual(r.intArray[0], 3);
222      Assert.AreEqual(r.intArray[1], 2);
223      Assert.AreEqual(r.intArray[2], 1);
224      Assert.AreEqual(r.intList[0], 9);
225      Assert.AreEqual(r.intList[1], 8);
226      Assert.AreEqual(r.intList[2], 7);
227      Assert.AreEqual(r.multiDimArray[0, 0], 5);
228      Assert.AreEqual(r.multiDimArray[0, 1], 4);
229      Assert.AreEqual(r.multiDimArray[0, 2], 3);
230      Assert.AreEqual(r.multiDimArray[1, 0], 1);
231      Assert.AreEqual(r.multiDimArray[1, 1], 4);
232      Assert.AreEqual(r.multiDimArray[1, 2], 6);
233      Assert.IsFalse(r.boolean);
234      Assert.IsTrue((DateTime.Now - r.dateTime).TotalSeconds < 10);
235      Assert.AreEqual(r.kvp.Key, "string key");
236      Assert.AreEqual(r.kvp.Value, 321);
237      Assert.IsNull(r.uninitialized);
238      Assert.AreEqual(newR.myEnum, TestEnum.va1);
239      Assert.AreEqual(newR.i[0], 7);
240      Assert.AreEqual(newR.i[1], 5);
241      Assert.AreEqual(newR.i[2], 6);
242      Assert.AreEqual(newR.s, "new value");
243      Assert.AreEqual(newR.intArray[0], 3);
244      Assert.AreEqual(newR.intArray[1], 2);
245      Assert.AreEqual(newR.intArray[2], 1);
246      Assert.AreEqual(newR.intList[0], 9);
247      Assert.AreEqual(newR.intList[1], 8);
248      Assert.AreEqual(newR.intList[2], 7);
249      Assert.AreEqual(newR.multiDimArray[0, 0], 5);
250      Assert.AreEqual(newR.multiDimArray[0, 1], 4);
251      Assert.AreEqual(newR.multiDimArray[0, 2], 3);
252      Assert.AreEqual(newR.multiDimArray[1, 0], 1);
253      Assert.AreEqual(newR.multiDimArray[1, 1], 4);
254      Assert.AreEqual(newR.multiDimArray[1, 2], 6);
255      Assert.AreEqual(newR.intStack.Pop(), 3);
256      Assert.AreEqual(newR.intStack.Pop(), 2);
257      Assert.AreEqual(newR.intStack.Pop(), 1);
258      Assert.IsFalse(newR.boolean);
259      Assert.IsTrue((DateTime.Now - newR.dateTime).TotalSeconds < 10);
260      Assert.AreEqual(newR.kvp.Key, "string key");
261      Assert.AreEqual(newR.kvp.Value, 321);
262      Assert.IsNull(newR.uninitialized);
263    }
264
265    [TestMethod]
266    public void SelfReferences() {
267      C c = new C();
268      C[][] cs = new C[2][];
269      cs[0] = new C[] { c };
270      cs[1] = new C[] { c };
271      c.allCs = cs;
272      c.kvpList = new KeyValuePair<List<C>, C>(new List<C> { c }, c);
273      XmlGenerator.Serialize(cs, tempFile);
274      object o = XmlParser.Deserialize(tempFile);
275      Assert.AreEqual(
276        DebugStringGenerator.Serialize(cs),
277        DebugStringGenerator.Serialize(o));
278      Assert.AreSame(c, c.allCs[0][0]);
279      Assert.AreSame(c, c.allCs[1][0]);
280      Assert.AreSame(c, c.kvpList.Key[0]);
281      Assert.AreSame(c, c.kvpList.Value);
282      C[][] newCs = (C[][])o;
283      C newC = newCs[0][0];
284      Assert.AreSame(newC, newC.allCs[0][0]);
285      Assert.AreSame(newC, newC.allCs[1][0]);
286      Assert.AreSame(newC, newC.kvpList.Key[0]);
287      Assert.AreSame(newC, newC.kvpList.Value);
288    }
289
290    [TestMethod]
291    public void ArrayCreation() {
292      ArrayList[] arrayListArray = new ArrayList[4];
293      arrayListArray[0] = new ArrayList();
294      arrayListArray[0].Add(arrayListArray);
295      arrayListArray[0].Add(arrayListArray);
296      arrayListArray[1] = new ArrayList();
297      arrayListArray[1].Add(arrayListArray);
298      arrayListArray[2] = new ArrayList();
299      arrayListArray[2].Add(arrayListArray);
300      arrayListArray[2].Add(arrayListArray);
301      Array a = Array.CreateInstance(
302                              typeof(object),
303                              new[] { 1, 2 }, new[] { 3, 4 });
304      arrayListArray[2].Add(a);
305      XmlGenerator.Serialize(arrayListArray, tempFile);
306      object o = XmlParser.Deserialize(tempFile);
307      Assert.AreEqual(
308        DebugStringGenerator.Serialize(arrayListArray),
309        DebugStringGenerator.Serialize(o));
310      ArrayList[] newArray = (ArrayList[])o;
311      Assert.AreSame(arrayListArray, arrayListArray[0][0]);
312      Assert.AreSame(arrayListArray, arrayListArray[2][1]);
313      Assert.AreSame(newArray, newArray[0][0]);
314      Assert.AreSame(newArray, newArray[2][1]);
315    }
316
317    [TestMethod]
318    public void CustomSerializationProperty() {
319      Manager m = new Manager();
320      XmlGenerator.Serialize(m, tempFile);
321      Manager newM = (Manager)XmlParser.Deserialize(tempFile);
322      Assert.AreNotEqual(
323        DebugStringGenerator.Serialize(m),
324        DebugStringGenerator.Serialize(newM));
325      Assert.AreEqual(m.dbl, newM.dbl);
326      Assert.AreEqual(m.lastLoadTime, new DateTime());
327      Assert.AreNotEqual(newM.lastLoadTime, new DateTime());
328      Assert.IsTrue((DateTime.Now - newM.lastLoadTime).TotalSeconds < 10);
329    }
330
331    [TestMethod]
332    public void Primitives() {
333      PrimitivesTest sdt = new PrimitivesTest();
334      XmlGenerator.Serialize(sdt, tempFile);
335      object o = XmlParser.Deserialize(tempFile);
336      Assert.AreEqual(
337        DebugStringGenerator.Serialize(sdt),
338        DebugStringGenerator.Serialize(o));
339    }
340
341    [TestMethod]
342    public void MultiDimensionalArray() {
343      string[,] mDimString = new string[,] {
344        {"ora", "et", "labora"},
345        {"Beten", "und", "Arbeiten"}
346      };
347      XmlGenerator.Serialize(mDimString, tempFile);
348      object o = XmlParser.Deserialize(tempFile);
349      Assert.AreEqual(
350        DebugStringGenerator.Serialize(mDimString),
351        DebugStringGenerator.Serialize(o));
352    }
353
354    public class NestedType {
355      [Storable]
356      private string value = "value";
357    }
358
359    [TestMethod]
360    public void NestedTypeTest() {
361      NestedType t = new NestedType();
362      XmlGenerator.Serialize(t, tempFile);
363      object o = XmlParser.Deserialize(tempFile);
364      Assert.AreEqual(
365        DebugStringGenerator.Serialize(t),
366        DebugStringGenerator.Serialize(o));
367    }
368
369
370    [TestMethod]
371    public void SimpleArray() {
372      string[] strings = { "ora", "et", "labora" };
373      XmlGenerator.Serialize(strings, tempFile);
374      object o = XmlParser.Deserialize(tempFile);
375      Assert.AreEqual(
376        DebugStringGenerator.Serialize(strings),
377        DebugStringGenerator.Serialize(o));
378    }
379
380    [TestMethod]
381    public void PrimitiveRoot() {
382      XmlGenerator.Serialize(12.3f, tempFile);
383      object o = XmlParser.Deserialize(tempFile);
384      Assert.AreEqual(
385        DebugStringGenerator.Serialize(12.3f),
386        DebugStringGenerator.Serialize(o));
387    }
388
389    private string formatFullMemberName(MemberInfo mi) {
390      return new StringBuilder()
391        .Append(mi.DeclaringType.Assembly.GetName().Name)
392        .Append(": ")
393        .Append(mi.DeclaringType.Namespace)
394        .Append('.')
395        .Append(mi.DeclaringType.Name)
396        .Append('.')
397        .Append(mi.Name).ToString();
398    }
399
400    [TestMethod]
401    public void CodingConventions() {
402      List<string> lowerCaseMethodNames = new List<string>();
403      List<string> lowerCaseProperties = new List<string>();
404      List<string> lowerCaseFields = new List<string>();
405      foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) {
406        if (!a.GetName().Name.StartsWith("HeuristicLab"))
407          continue;
408        foreach (Type t in a.GetTypes()) {
409          foreach (MemberInfo mi in t.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) {
410            if (mi.DeclaringType.Name.StartsWith("<>"))
411              continue;
412            if (char.IsLower(mi.Name[0])) {
413              if (mi.MemberType == MemberTypes.Field)
414                lowerCaseFields.Add(formatFullMemberName(mi));
415              if (mi.MemberType == MemberTypes.Property)
416                lowerCaseProperties.Add(formatFullMemberName(mi));
417              if (mi.MemberType == MemberTypes.Method &&
418                !mi.Name.StartsWith("get_") &&
419                !mi.Name.StartsWith("set_") &&
420                !mi.Name.StartsWith("add_") &&
421                !mi.Name.StartsWith("remove_"))
422                lowerCaseMethodNames.Add(formatFullMemberName(mi));
423            }
424          }
425        }
426      }
427      //Assert.AreEqual("", lowerCaseFields.Aggregate("", (a, b) => a + "\r\n" + b));
428      Assert.AreEqual("", lowerCaseMethodNames.Aggregate("", (a, b) => a + "\r\n" + b));
429      Assert.AreEqual("", lowerCaseProperties.Aggregate("", (a, b) => a + "\r\n" + b));
430    }
431
432    [TestMethod]
433    public void Number2StringDecomposer() {
434      NumberTest sdt = new NumberTest();
435      XmlGenerator.Serialize(sdt, tempFile,
436        new Configuration(new XmlFormat(),
437          new List<IPrimitiveSerializer> { new String2XmlSerializer() },
438          new List<ICompositeSerializer> {
439            new StorableSerializer(),
440            new Number2StringSerializer() }));
441      object o = XmlParser.Deserialize(tempFile);
442      Assert.AreEqual(
443        DebugStringGenerator.Serialize(sdt),
444        DebugStringGenerator.Serialize(o));
445    }
446
447    [TestMethod]
448    public void Enums() {
449      EnumTest et = new EnumTest();
450      et.simpleEnum = SimpleEnum.two;
451      et.complexEnum = ComplexEnum.three;
452      et.trickyEnum = TrickyEnum.two | TrickyEnum.one;
453      XmlGenerator.Serialize(et, tempFile);
454      EnumTest newEt = (EnumTest)XmlParser.Deserialize(tempFile);
455      Assert.AreEqual(et.simpleEnum, SimpleEnum.two);
456      Assert.AreEqual(et.complexEnum, ComplexEnum.three);
457      Assert.AreEqual(et.trickyEnum, (TrickyEnum)3);
458    }
459
460    [TestMethod]
461    public void TestAliasingWithOverriddenEquals() {
462      List<IntWrapper> ints = new List<IntWrapper>();
463      ints.Add(new IntWrapper(1));
464      ints.Add(new IntWrapper(1));
465      Assert.AreEqual(ints[0], ints[1]);
466      Assert.AreNotSame(ints[0], ints[1]);
467      XmlGenerator.Serialize(ints, tempFile);
468      List<IntWrapper> newInts = (List<IntWrapper>)XmlParser.Deserialize(tempFile);
469      Assert.AreEqual(newInts[0].Value, 1);
470      Assert.AreEqual(newInts[1].Value, 1);
471      Assert.AreEqual(newInts[0], newInts[1]);
472      Assert.AreNotSame(newInts[0], newInts[1]);
473    }
474
475    [TestMethod]
476    public void NonDefaultConstructorTest() {
477      NonDefaultConstructorClass c = new NonDefaultConstructorClass(1);
478      try {
479        XmlGenerator.Serialize(c, tempFile);
480        Assert.Fail("Exception not thrown");
481      } catch (PersistenceException) {
482      }
483    }
484
485    [TestMethod]
486    public void TestSavingException() {
487      List<int> list = new List<int> { 1, 2, 3 };
488      XmlGenerator.Serialize(list, tempFile);
489      NonSerializable s = new NonSerializable();
490      try {
491        XmlGenerator.Serialize(s, tempFile);
492        Assert.Fail("Exception expected");
493      } catch (PersistenceException) { }
494      List<int> newList = (List<int>)XmlParser.Deserialize(tempFile);
495      Assert.AreEqual(list[0], newList[0]);
496      Assert.AreEqual(list[1], newList[1]);
497    }
498
499    [TestMethod]
500    public void TestTypeStringConversion() {
501      string name = typeof(List<int>[]).AssemblyQualifiedName;
502      string shortName =
503        "System.Collections.Generic.List`1[[System.Int32, mscorlib]][], mscorlib";
504      Assert.AreEqual(name, TypeNameParser.Parse(name).ToString());
505      Assert.AreEqual(shortName, TypeNameParser.Parse(name).ToString(false));
506      Assert.AreEqual(shortName, typeof(List<int>[]).VersionInvariantName());
507    }
508
509    [TestMethod]
510    public void TestHexadecimalPublicKeyToken() {
511      string name = "TestClass, TestAssembly, Version=1.2.3.4, PublicKey=1234abc";
512      string shortName = "TestClass, TestAssembly";
513      Assert.AreEqual(name, TypeNameParser.Parse(name).ToString());
514      Assert.AreEqual(shortName, TypeNameParser.Parse(name).ToString(false));
515    }
516
517    [TestMethod]
518    public void TestMultipleFailure() {
519      List<NonSerializable> l = new List<NonSerializable>();
520      l.Add(new NonSerializable());
521      l.Add(new NonSerializable());
522      l.Add(new NonSerializable());
523      try {
524        Serializer s = new Serializer(l,
525          ConfigurationService.Instance.GetConfiguration(new XmlFormat()),
526          "ROOT", true);
527        StringBuilder tokens = new StringBuilder();
528        foreach (var token in s) {
529          tokens.Append(token.ToString());
530        }
531        Assert.Fail("Exception expected");
532      } catch (PersistenceException px) {
533        Assert.AreEqual(3, px.Data.Count);
534      }
535    }
536
537    [TestMethod]
538    public void TestAssemblyVersionCheck() {
539      IntWrapper i = new IntWrapper(1);
540      Serializer s = new Serializer(i, ConfigurationService.Instance.GetDefaultConfig(new XmlFormat()));
541      XmlGenerator g = new XmlGenerator();
542      StringBuilder dataString = new StringBuilder();
543      foreach (var token in s) {
544        dataString.Append(g.Format(token));
545      }
546      StringBuilder typeString = new StringBuilder();
547      foreach (var line in g.Format(s.TypeCache))
548        typeString.Append(line);
549      Deserializer d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(typeString.ToString())));
550      XmlParser p = new XmlParser(new StringReader(dataString.ToString()));
551      IntWrapper newI = (IntWrapper)d.Deserialize(p);
552      Assert.AreEqual(i.Value, newI.Value);
553
554      string newTypeString = Regex.Replace(typeString.ToString(),
555        "Version=\\d+\\.\\d+\\.\\d+\\.\\d+",
556        "Version=0.0.9999.9999");
557      try {
558        d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(newTypeString)));
559        Assert.Fail("Exception expected");
560      } catch (PersistenceException x) {
561        Assert.IsTrue(x.Message.Contains("incompatible"));
562      }
563      newTypeString = Regex.Replace(typeString.ToString(),
564        "Version=(\\d+\\.\\d+)\\.\\d+\\.\\d+",
565        "Version=$1.9999.9999");
566      try {
567        d = new Deserializer(XmlParser.ParseTypeCache(new StringReader(newTypeString)));
568        Assert.Fail("Exception expected");
569      } catch (PersistenceException x) {
570        Assert.IsTrue(x.Message.Contains("newer"));
571      }
572    }
573
574    [TestMethod]
575    public void InheritanceTest() {
576      New n = new New();
577      XmlGenerator.Serialize(n, tempFile);
578      New nn = (New)XmlParser.Deserialize(tempFile);
579      Assert.AreEqual(n.Name, nn.Name);
580      Assert.AreEqual(((Override)n).Name, ((Override)nn).Name);
581    }
582
583    [ClassInitialize]
584    public static void Initialize(TestContext testContext) {
585      ConfigurationService.Instance.Reset();
586    }
587  }
588}
Note: See TracBrowser for help on using the repository browser.