Skip to content

Commit 9f2997c

Browse files
maca88fredericDelaporte
authored andcommitted
Make cache types serialization friendly (#1776)
1 parent 27e47da commit 9f2997c

25 files changed

+1044
-121
lines changed
Lines changed: 377 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System;
12+
using System.Collections.Generic;
13+
using System.Globalization;
14+
using System.IO;
15+
using System.Linq;
16+
using System.Runtime.Serialization;
17+
using System.Runtime.Serialization.Formatters.Binary;
18+
using System.Text;
19+
using System.Xml;
20+
using System.Xml.Linq;
21+
using NHibernate.Cache;
22+
using NHibernate.Cache.Entry;
23+
using NHibernate.Engine;
24+
using NHibernate.Intercept;
25+
using NHibernate.Properties;
26+
using NHibernate.Type;
27+
using NSubstitute;
28+
using NUnit.Framework;
29+
30+
namespace NHibernate.Test.CacheTest
31+
{
32+
using System.Threading.Tasks;
33+
[TestFixture]
34+
public class SerializationFixtureAsync
35+
{
36+
private static readonly List<System.Type> KnownTypes = new List<System.Type>
37+
{
38+
typeof(AnyType.ObjectTypeCacheEntry),
39+
typeof(DateTimeOffset),
40+
typeof(TimeSpan),
41+
typeof(UnfetchedLazyProperty),
42+
typeof(UnknownBackrefProperty),
43+
typeof(object[]),
44+
typeof(CacheEntry),
45+
typeof(CacheLock),
46+
typeof(CachedItem),
47+
typeof(CollectionCacheEntry)
48+
};
49+
50+
[Test]
51+
public async Task TestCacheEntrySerializationAsync()
52+
{
53+
var item = CreateCacheEntry();
54+
var copy = await (TestDataContractSerializerAsync(item));
55+
CheckCacheEntry(item, copy);
56+
57+
copy = TestBinaryFormatter(item);
58+
CheckCacheEntry(item, copy);
59+
}
60+
61+
[Test]
62+
public async Task TestCollectionCacheEntrySerializationAsync()
63+
{
64+
var item = CreateCollectionCacheEntry();
65+
var copy = await (TestDataContractSerializerAsync(item));
66+
CheckCollectionCacheEntry(item, copy);
67+
68+
copy = TestBinaryFormatter(item);
69+
CheckCollectionCacheEntry(item, copy);
70+
}
71+
72+
[Test]
73+
public async Task TestCachedItemSerializationAsync()
74+
{
75+
// CacheEntry
76+
var item = CreateCachedItem(CreateCacheEntry());
77+
var copy = await (TestDataContractSerializerAsync(item));
78+
CheckCachedItem(item, copy);
79+
80+
copy = TestBinaryFormatter(item);
81+
CheckCachedItem(item, copy);
82+
83+
// CollectionCacheEntry
84+
item = CreateCachedItem(CreateCollectionCacheEntry());
85+
copy = await (TestDataContractSerializerAsync(item));
86+
CheckCachedItem(item, copy);
87+
88+
copy = TestBinaryFormatter(item);
89+
CheckCachedItem(item, copy);
90+
}
91+
92+
[Test]
93+
public async Task TestCacheLockSerializationAsync()
94+
{
95+
var item = new CacheLock
96+
{
97+
Version = 3.5m,
98+
Id = 100,
99+
Timeout = 999,
100+
UnlockTimestamp = 444,
101+
Multiplicity = 5,
102+
WasLockedConcurrently = false
103+
};
104+
var copy = await (TestDataContractSerializerAsync(item));
105+
CheckCacheLock(item, copy);
106+
107+
copy = TestBinaryFormatter(item);
108+
CheckCacheLock(item, copy);
109+
}
110+
111+
[Test]
112+
public async Task TestAnyTypeObjectTypeCacheEntrySerializationAsync()
113+
{
114+
var item = CreateObjectTypeCacheEntry();
115+
var copy = await (TestDataContractSerializerAsync(item));
116+
CheckObjectTypeCacheEntry(item, copy);
117+
118+
copy = TestBinaryFormatter(item);
119+
CheckObjectTypeCacheEntry(item, copy);
120+
}
121+
122+
123+
[Serializable]
124+
public class MyEntity
125+
{
126+
public int Id { get; set; }
127+
}
128+
129+
private CachedItem CreateCachedItem(object value)
130+
{
131+
return new CachedItem
132+
{
133+
Version = 55L,
134+
Value = value,
135+
FreshTimestamp = 500
136+
};
137+
}
138+
139+
private CacheEntry CreateCacheEntry()
140+
{
141+
return new CacheEntry
142+
{
143+
DisassembledState = GetAllKnownTypeValues(),
144+
Version = 55,
145+
Subclass = "Test",
146+
AreLazyPropertiesUnfetched = true
147+
};
148+
}
149+
150+
private CollectionCacheEntry CreateCollectionCacheEntry()
151+
{
152+
return new CollectionCacheEntry
153+
{
154+
State = GetAllKnownTypeValues()
155+
};
156+
}
157+
158+
private object[] GetAllKnownTypeValues()
159+
{
160+
var entityName = nameof(MyEntity);
161+
var xmlDoc = new XmlDocument();
162+
xmlDoc.LoadXml("<Root>XmlDoc</Root>");
163+
var types = new Dictionary<IType, object>
164+
{
165+
{NHibernateUtil.AnsiString, "test"},
166+
{NHibernateUtil.Binary, new byte[] {1, 2, 3, 4}},
167+
{NHibernateUtil.BinaryBlob, new byte[] {1, 2, 3, 4}},
168+
{NHibernateUtil.Boolean, true},
169+
{NHibernateUtil.Byte, (byte) 1},
170+
{NHibernateUtil.Character, 'a'},
171+
{NHibernateUtil.CultureInfo, CultureInfo.CurrentCulture},
172+
{NHibernateUtil.DateTime, DateTime.Now},
173+
{NHibernateUtil.DateTimeNoMs, DateTime.Now},
174+
{NHibernateUtil.LocalDateTime, DateTime.Now},
175+
{NHibernateUtil.UtcDateTime, DateTime.UtcNow},
176+
{NHibernateUtil.LocalDateTimeNoMs, DateTime.Now},
177+
{NHibernateUtil.UtcDateTimeNoMs, DateTime.UtcNow},
178+
{NHibernateUtil.DateTimeOffset, DateTimeOffset.Now},
179+
{NHibernateUtil.Date, DateTime.Today},
180+
{NHibernateUtil.Decimal, 2.5m},
181+
{NHibernateUtil.Double, 2.5d},
182+
{NHibernateUtil.Currency, 2.5m},
183+
{NHibernateUtil.Guid, Guid.NewGuid()},
184+
{NHibernateUtil.Int16, (short) 1},
185+
{NHibernateUtil.Int32, 3},
186+
{NHibernateUtil.Int64, 3L},
187+
{NHibernateUtil.SByte, (sbyte) 1},
188+
{NHibernateUtil.UInt16, (ushort) 1},
189+
{NHibernateUtil.UInt32, (uint) 1},
190+
{NHibernateUtil.UInt64, (ulong) 1},
191+
{NHibernateUtil.Single, 1.1f},
192+
{NHibernateUtil.String, "test"},
193+
{NHibernateUtil.StringClob, "test"},
194+
{NHibernateUtil.Time, DateTime.Now},
195+
{NHibernateUtil.Ticks, DateTime.Now},
196+
{NHibernateUtil.TimeAsTimeSpan, TimeSpan.FromMilliseconds(15)},
197+
{NHibernateUtil.TimeSpan, TimeSpan.FromMilliseconds(1234)},
198+
{NHibernateUtil.DbTimestamp, DateTime.Now},
199+
{NHibernateUtil.TrueFalse, false},
200+
{NHibernateUtil.YesNo, true},
201+
{NHibernateUtil.Class, typeof(IType)},
202+
{NHibernateUtil.ClassMetaType, entityName},
203+
{NHibernateUtil.Serializable, new MyEntity {Id = 1}},
204+
{NHibernateUtil.Object, new MyEntity {Id = 10}},
205+
{NHibernateUtil.AnsiChar, 'a'},
206+
{NHibernateUtil.XmlDoc, xmlDoc},
207+
{NHibernateUtil.XDoc, XDocument.Parse("<Root>XDoc</Root>")},
208+
{NHibernateUtil.Uri, new Uri("http://test.com")}
209+
};
210+
211+
var sessionImpl = Substitute.For<ISessionImplementor>();
212+
sessionImpl.BestGuessEntityName(Arg.Any<object>()).Returns(o => o[0].GetType().Name);
213+
sessionImpl.GetContextEntityIdentifier(Arg.Is<object>(o => o is MyEntity)).Returns(o => ((MyEntity) o[0]).Id);
214+
return TypeHelper.Disassemble(
215+
types.Values.ToArray(),
216+
types.Keys.Cast<ICacheAssembler>().ToArray(),
217+
null,
218+
sessionImpl,
219+
null)
220+
.Concat(
221+
new[]
222+
{
223+
LazyPropertyInitializer.UnfetchedProperty,
224+
BackrefPropertyAccessor.Unknown
225+
})
226+
.ToArray();
227+
}
228+
229+
private AnyType.ObjectTypeCacheEntry CreateObjectTypeCacheEntry()
230+
{
231+
return new AnyType.ObjectTypeCacheEntry
232+
{
233+
Id = 100,
234+
EntityName = "Test"
235+
};
236+
}
237+
238+
private void CheckCacheEntry(CacheEntry original, CacheEntry copy)
239+
{
240+
Assert.That(copy.Version, Is.EqualTo(original.Version));
241+
Assert.That(copy.Version, Is.TypeOf(original.Version.GetType()));
242+
Assert.That(copy.Subclass, Is.EqualTo(original.Subclass));
243+
Assert.That(copy.AreLazyPropertiesUnfetched, Is.EqualTo(original.AreLazyPropertiesUnfetched));
244+
for (var i = 0; i < copy.DisassembledState.Length; i++)
245+
{
246+
Assert.That(copy.DisassembledState[i], Is.TypeOf(original.DisassembledState[i].GetType()));
247+
if (original.DisassembledState[i] is AnyType.ObjectTypeCacheEntry originalAnyType)
248+
{
249+
var copyAnyType = (AnyType.ObjectTypeCacheEntry) copy.DisassembledState[i];
250+
CheckObjectTypeCacheEntry(originalAnyType, copyAnyType);
251+
}
252+
else
253+
{
254+
Assert.That(copy.DisassembledState[i], Is.EqualTo(original.DisassembledState[i]));
255+
}
256+
}
257+
}
258+
259+
private void CheckCachedItem(CachedItem original, CachedItem copy)
260+
{
261+
Assert.That(copy.Version, Is.EqualTo(original.Version));
262+
Assert.That(copy.Version, Is.TypeOf(original.Version.GetType()));
263+
Assert.That(copy.Value, Is.TypeOf(original.Value.GetType()));
264+
switch (original.Value)
265+
{
266+
case CacheEntry cacheEntry:
267+
CheckCacheEntry(cacheEntry, (CacheEntry) copy.Value);
268+
break;
269+
case CollectionCacheEntry colleectionCacheEntry:
270+
CheckCollectionCacheEntry(colleectionCacheEntry, (CollectionCacheEntry) copy.Value);
271+
break;
272+
default:
273+
Assert.That(copy.Value, Is.EqualTo(original.Value));
274+
break;
275+
}
276+
Assert.That(copy.FreshTimestamp, Is.EqualTo(original.FreshTimestamp));
277+
}
278+
279+
private void CheckCollectionCacheEntry(CollectionCacheEntry original, CollectionCacheEntry copy)
280+
{
281+
Assert.That(copy.State, Is.TypeOf(original.State.GetType()));
282+
283+
var originalArray = original.State;
284+
var copyArray = copy.State;
285+
286+
for (var i = 0; i < copyArray.Length; i++)
287+
{
288+
Assert.That(copyArray[i], Is.TypeOf(originalArray[i].GetType()));
289+
if (originalArray[i] is AnyType.ObjectTypeCacheEntry originalAnyType)
290+
{
291+
var copyAnyType = (AnyType.ObjectTypeCacheEntry) copyArray[i];
292+
CheckObjectTypeCacheEntry(originalAnyType, copyAnyType);
293+
}
294+
else
295+
{
296+
Assert.That(copyArray[i], Is.EqualTo(originalArray[i]));
297+
}
298+
}
299+
}
300+
301+
private void CheckCacheLock(CacheLock original, CacheLock copy)
302+
{
303+
Assert.That(copy.Version, Is.EqualTo(original.Version));
304+
Assert.That(copy.Version, Is.TypeOf(original.Version.GetType()));
305+
Assert.That(copy.Id, Is.EqualTo(original.Id));
306+
Assert.That(copy.Multiplicity, Is.EqualTo(original.Multiplicity));
307+
Assert.That(copy.Timeout, Is.EqualTo(original.Timeout));
308+
Assert.That(copy.UnlockTimestamp, Is.EqualTo(original.UnlockTimestamp));
309+
Assert.That(copy.WasLockedConcurrently, Is.EqualTo(original.WasLockedConcurrently));
310+
}
311+
312+
private void CheckObjectTypeCacheEntry(AnyType.ObjectTypeCacheEntry original, AnyType.ObjectTypeCacheEntry copy)
313+
{
314+
Assert.That(copy.Id, Is.EqualTo(original.Id));
315+
Assert.That(copy.EntityName, Is.EqualTo(original.EntityName));
316+
}
317+
318+
private static async Task<T> TestDataContractSerializerAsync<T>(T obj)
319+
{
320+
var xml = await (DataContractSerializerToXmlAsync(obj));
321+
obj = DataContractSerializerFromXml<T>(xml);
322+
Assert.That(xml, Is.EqualTo(await (DataContractSerializerToXmlAsync(obj))));
323+
return obj;
324+
}
325+
326+
private static T TestBinaryFormatter<T>(T obj)
327+
{
328+
var bytes = BinaryFormatterToBinary(obj);
329+
obj = BinaryFormatterFromBinary<T>(bytes);
330+
Assert.That(bytes, Is.EqualTo(BinaryFormatterToBinary(obj)));
331+
return obj;
332+
}
333+
334+
private static async Task<string> DataContractSerializerToXmlAsync<T>(T obj)
335+
{
336+
using (var memoryStream = new MemoryStream())
337+
using (var reader = new StreamReader(memoryStream))
338+
{
339+
var serializer = new DataContractSerializer(typeof(T), KnownTypes);
340+
serializer.WriteObject(memoryStream, obj);
341+
memoryStream.Position = 0;
342+
return await (reader.ReadToEndAsync());
343+
}
344+
}
345+
346+
private static T DataContractSerializerFromXml<T>(string xml)
347+
{
348+
using (var stream = new MemoryStream())
349+
{
350+
var data = Encoding.UTF8.GetBytes(xml);
351+
stream.Write(data, 0, data.Length);
352+
stream.Position = 0;
353+
var deserializer = new DataContractSerializer(typeof(T), KnownTypes);
354+
return (T) deserializer.ReadObject(stream);
355+
}
356+
}
357+
358+
private static byte[] BinaryFormatterToBinary<T>(T obj)
359+
{
360+
var serializer = new BinaryFormatter();
361+
using (var stream = new MemoryStream())
362+
{
363+
serializer.Serialize(stream, obj);
364+
return stream.ToArray();
365+
}
366+
}
367+
368+
private static T BinaryFormatterFromBinary<T>(byte[] value)
369+
{
370+
var serializer = new BinaryFormatter();
371+
using (var stream = new MemoryStream(value))
372+
{
373+
return (T)serializer.Deserialize(stream);
374+
}
375+
}
376+
}
377+
}

0 commit comments

Comments
 (0)