clicache/integration-test2/SerializationTests.cs (808 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.IO; using System.Linq; using Xunit; using PdxTests; using System.Collections; using System.Collections.Generic; using Xunit.Abstractions; namespace Apache.Geode.Client.IntegrationTests { public class TestClassA : IDataSerializable { public int Id { get; set; } public string Name { get; set; } public short NumSides { get; set; } // A default constructor is required for deserialization public TestClassA() { } public TestClassA(int id, string name, short numSides) { Id = id; Name = name; NumSides = numSides; } public override string ToString() { return string.Format("TestClassA: [{0}, {1}, {2}]", Id, Name, NumSides); } public void ToData(DataOutput output) { output.WriteInt32(Id); output.WriteUTF(Name); output.WriteInt16(NumSides); } public void FromData(DataInput input) { Id = input.ReadInt32(); Name = input.ReadUTF(); NumSides = input.ReadInt16(); } public ulong ObjectSize { get { return 0; } } public static ISerializable CreateDeserializable() { return new TestClassA(); } public override bool Equals(object obj) { TestClassA other = (TestClassA)obj; if (other != null) { if (Id == other.Id && Name == other.Name && NumSides == other.NumSides) return true; else return false; } else return false; } public override int GetHashCode() { return base.GetHashCode(); } } public class TestClassB : IDataSerializable { public int Width { get; set; } public int Height { get; set; } public string Name { get; set; } // A default constructor is required for deserialization public TestClassB() { } public TestClassB(int width, int height, string name) { Width = width; Height = height; Name = name; } public override string ToString() { return string.Format("TestClassB: [{0}, {1}, {2}]", Width, Height, Name); } public void ToData(DataOutput output) { output.WriteInt32(Width); output.WriteInt32(Height); output.WriteUTF(Name); } public void FromData(DataInput input) { Width = input.ReadInt32(); Height = input.ReadInt32(); Name = input.ReadUTF(); } public ulong ObjectSize { get { return 0; } } public static ISerializable CreateDeserializable() { return new TestClassB(); } public override bool Equals(object obj) { var other = (TestClassB)obj; if (other != null) { if (Width == other.Width && Name == other.Name && Height == other.Height) return true; else return false; } else return false; } public override int GetHashCode() { return base.GetHashCode(); } } public class TestClassC : IDataSerializable { public string Color { get; set; } public string Make { get; set; } public int Year { get; set; } // A default constructor is required for deserialization public TestClassC() { } public TestClassC(string color, string make, int year) { Color = color; Make = make; Year = year; } public override string ToString() { return string.Format("TestClassC: [{0}, {1}, {2}]", Color, Make, Year); } public void ToData(DataOutput output) { output.WriteUTF(Color); output.WriteUTF(Make); output.WriteInt32(Year); } public void FromData(DataInput input) { Color = input.ReadUTF(); Make = input.ReadUTF(); Year = input.ReadInt32(); } public ulong ObjectSize { get { return 0; } } public static ISerializable CreateDeserializable() { return new TestClassC(); } public override bool Equals(object obj) { var other = (TestClassC)obj; if (Color == other.Color && Make == other.Make && Year == other.Year) return true; else return false; } public override int GetHashCode() { return base.GetHashCode(); } } public class CompositeClass : IDataSerializable { private TestClassA testclassA; private List<TestClassB> testclassBs; private List<TestClassC> testclassCs; public CompositeClass() { testclassA = new TestClassA(); testclassBs = new List<TestClassB>(); testclassCs = new List<TestClassC>(); } public TestClassA A { get { return testclassA; } set { testclassA = value; } } public List<TestClassB> Bs { get { return testclassBs; } set { testclassBs = value; } } public List<TestClassC> Cs { get { return testclassCs; } set { testclassCs = value; } } public void ToData(DataOutput output) { testclassA.ToData(output); output.WriteObject(testclassBs); output.WriteObject(testclassCs); } public void FromData(DataInput input) { testclassA.FromData(input); List<object> bs = (List<object>)input.ReadObject(); foreach (var obj in bs) { Bs.Add(obj as TestClassB); } List<object> cs = (List<object>)input.ReadObject(); foreach (var obj in cs) { Cs.Add(obj as TestClassC); } } public ulong ObjectSize { get { return 0; } } public static ISerializable CreateDeserializable() { return new CompositeClass(); } public override bool Equals(object obj) { var other = (CompositeClass)obj; if (testclassA.Equals(other.testclassA) && testclassBs.Equals(other.testclassBs) && testclassCs.Equals(other.testclassCs)) return true; else return false; } public override int GetHashCode() { return base.GetHashCode(); } } public class Order : IDataSerializable { public int OrderId { get; set; } public string Name { get; set; } public short Quantity { get; set; } // A default constructor is required for deserialization public Order() { } public Order(int orderId, string name, short quantity) { OrderId = orderId; Name = name; Quantity = quantity; } public override string ToString() { return string.Format("Order: [{0}, {1}, {2}]", OrderId, Name, Quantity); } public void ToData(DataOutput output) { output.WriteInt32(OrderId); output.WriteUTF(Name); output.WriteInt16(Quantity); } public void FromData(DataInput input) { OrderId = input.ReadInt32(); Name = input.ReadUTF(); Quantity = input.ReadInt16(); } public ulong ObjectSize { get { return 0; } } public static ISerializable CreateDeserializable() { return new Order(); } } public struct CData { #region Private members private Int32 m_first; private Int64 m_second; #endregion #region Public accessors public Int32 First { get { return m_first; } set { m_first = value; } } public Int64 Second { get { return m_second; } set { m_second = value; } } #endregion public CData(Int32 first, Int64 second) { m_first = first; m_second = second; } public static bool operator ==(CData obj1, CData obj2) { return ((obj1.m_first == obj2.m_first) && (obj1.m_second == obj2.m_second)); } public static bool operator !=(CData obj1, CData obj2) { return ((obj1.m_first != obj2.m_first) || (obj1.m_second != obj2.m_second)); } public override bool Equals(object obj) { if (obj is CData) { CData otherObj = (CData)obj; return ((m_first == otherObj.m_first) && (m_second == otherObj.m_second)); } return false; } public override int GetHashCode() { return m_first.GetHashCode() ^ m_second.GetHashCode(); } }; public class OtherType : IDataSerializable { private CData m_struct; private ExceptionType m_exType; public enum ExceptionType { None, Geode, System, // below are with inner exceptions GeodeGeode, GeodeSystem, SystemGeode, SystemSystem } public OtherType() { m_exType = ExceptionType.None; } public OtherType(Int32 first, Int64 second) : this(first, second, ExceptionType.None) { } public OtherType(Int32 first, Int64 second, ExceptionType exType) { m_struct.First = first; m_struct.Second = second; m_exType = exType; } public CData Data { get { return m_struct; } } #region IDataSerializable Members public void FromData(DataInput input) { m_struct.First = input.ReadInt32(); m_struct.Second = input.ReadInt64(); switch (m_exType) { case ExceptionType.None: break; case ExceptionType.Geode: throw new GeodeIOException("Throwing an exception"); case ExceptionType.System: throw new IOException("Throwing an exception"); case ExceptionType.GeodeGeode: throw new GeodeIOException("Throwing an exception with inner " + "exception", new CacheServerException("This is an inner exception")); case ExceptionType.GeodeSystem: throw new CacheServerException("Throwing an exception with inner " + "exception", new IOException("This is an inner exception")); case ExceptionType.SystemGeode: throw new ApplicationException("Throwing an exception with inner " + "exception", new CacheServerException("This is an inner exception")); case ExceptionType.SystemSystem: throw new ApplicationException("Throwing an exception with inner " + "exception", new IOException("This is an inner exception")); } } public void ToData(DataOutput output) { output.WriteInt32(m_struct.First); output.WriteInt64(m_struct.Second); switch (m_exType) { case ExceptionType.None: break; case ExceptionType.Geode: throw new GeodeIOException("Throwing an exception"); case ExceptionType.System: throw new IOException("Throwing an exception"); case ExceptionType.GeodeGeode: throw new GeodeIOException("Throwing an exception with inner " + "exception", new CacheServerException("This is an inner exception")); case ExceptionType.GeodeSystem: throw new CacheServerException("Throwing an exception with inner " + "exception", new IOException("This is an inner exception")); case ExceptionType.SystemGeode: throw new ApplicationException("Throwing an exception with inner " + "exception", new CacheServerException("This is an inner exception")); case ExceptionType.SystemSystem: throw new ApplicationException("Throwing an exception with inner " + "exception", new IOException("This is an inner exception")); } } public UInt64 ObjectSize { get { return (UInt32)(sizeof(Int32) + sizeof(Int64)); } } #endregion public static ISerializable CreateDeserializable() { return new OtherType(); } public override int GetHashCode() { return m_struct.First.GetHashCode() ^ m_struct.Second.GetHashCode(); } public override bool Equals(object obj) { OtherType ot = obj as OtherType; if (ot != null) { return (m_struct.Equals(ot.m_struct)); } return false; } } public class OtherType2 : IDataSerializable { private CData m_struct; private ExceptionType m_exType; public enum ExceptionType { None, Geode, System, // below are with inner exceptions GeodeGeode, GeodeSystem, SystemGeode, SystemSystem } public OtherType2() { m_exType = ExceptionType.None; } public OtherType2(Int32 first, Int64 second) : this(first, second, ExceptionType.None) { } public OtherType2(Int32 first, Int64 second, ExceptionType exType) { m_struct.First = first; m_struct.Second = second; m_exType = exType; } public CData Data { get { return m_struct; } } #region IDataSerializable Members public void FromData(DataInput input) { m_struct.First = input.ReadInt32(); m_struct.Second = input.ReadInt64(); switch (m_exType) { case ExceptionType.None: break; case ExceptionType.Geode: throw new GeodeIOException("Throwing an exception"); case ExceptionType.System: throw new IOException("Throwing an exception"); case ExceptionType.GeodeGeode: throw new GeodeIOException("Throwing an exception with inner " + "exception", new CacheServerException("This is an inner exception")); case ExceptionType.GeodeSystem: throw new CacheServerException("Throwing an exception with inner " + "exception", new IOException("This is an inner exception")); case ExceptionType.SystemGeode: throw new ApplicationException("Throwing an exception with inner " + "exception", new CacheServerException("This is an inner exception")); case ExceptionType.SystemSystem: throw new ApplicationException("Throwing an exception with inner " + "exception", new IOException("This is an inner exception")); } } public void ToData(DataOutput output) { output.WriteInt32(m_struct.First); output.WriteInt64(m_struct.Second); switch (m_exType) { case ExceptionType.None: break; case ExceptionType.Geode: throw new GeodeIOException("Throwing an exception"); case ExceptionType.System: throw new IOException("Throwing an exception"); case ExceptionType.GeodeGeode: throw new GeodeIOException("Throwing an exception with inner " + "exception", new CacheServerException("This is an inner exception")); case ExceptionType.GeodeSystem: throw new CacheServerException("Throwing an exception with inner " + "exception", new IOException("This is an inner exception")); case ExceptionType.SystemGeode: throw new ApplicationException("Throwing an exception with inner " + "exception", new CacheServerException("This is an inner exception")); case ExceptionType.SystemSystem: throw new ApplicationException("Throwing an exception with inner " + "exception", new IOException("This is an inner exception")); } } public UInt64 ObjectSize { get { return (UInt32)(sizeof(Int32) + sizeof(Int64)); } } #endregion public static ISerializable CreateDeserializable() { return new OtherType2(); } public override int GetHashCode() { return m_struct.First.GetHashCode() ^ m_struct.Second.GetHashCode(); } public override bool Equals(object obj) { OtherType2 ot = obj as OtherType2; if (ot != null) { return (m_struct.Equals(ot.m_struct)); } return false; } } [Trait("Category", "Integration")] public class SerializationTests : TestBase { public SerializationTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } private void putAndCheck(IRegion<object, object> region, object key, object value) { region[key] = value; var retrievedValue = region[key]; Assert.Equal(value, retrievedValue); } [Fact] public void BuiltInSerializableTypes() { using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1)) { Assert.True(cluster.withDebugAgent().Start()); Assert.Equal(0, cluster.Gfsh.create() .region() .withName("testRegion") .withType("REPLICATE") .execute()); var cache = cluster.CreateCache(); var region = cache.CreateRegionFactory(RegionShortcut.PROXY) .SetPoolName("default") .Create<object, object>("testRegion"); Assert.NotNull(region); putAndCheck(region, "CacheableString", "foo"); putAndCheck(region, "CacheableByte", (Byte)8); putAndCheck(region, "CacheableInt16", (Int16)16); putAndCheck(region, "CacheableInt32", (Int32)32); putAndCheck(region, "CacheableInt64", (Int64)64); putAndCheck(region, "CacheableBoolean", (Boolean)true); putAndCheck(region, "CacheableCharacter", 'c'); putAndCheck(region, "CacheableDouble", (Double)1.5); putAndCheck(region, "CacheableFloat", (float)2.5); putAndCheck(region, "CacheableStringArray", new String[] { "foo", "bar" }); putAndCheck(region, "CacheableBytes", new Byte[] { 8, 8 }); putAndCheck(region, "CacheableInt16Array", new Int16[] { 16, 16 }); putAndCheck(region, "CacheableInt32Array", new Int32[] { 32, 32 }); putAndCheck(region, "CacheableInt64Array", new Int64[] { 64, 64 }); putAndCheck(region, "CacheableBooleanArray", new Boolean[] { true, false }); putAndCheck(region, "CacheableCharacterArray", new Char[] { 'c', 'a' }); putAndCheck(region, "CacheableDoubleArray", new Double[] { 1.5, 1.7 }); putAndCheck(region, "CacheableFloatArray", new float[] { 2.5F, 2.7F }); putAndCheck(region, "CacheableDate", new DateTime()); putAndCheck(region, "CacheableHashMap", new Dictionary<int, string>() { { 1, "one" }, { 2, "two" } }); putAndCheck(region, "CacheableHashTable", new Hashtable() { { 1, "one" }, { 2, "two" } }); putAndCheck(region, "CacheableVector", new ArrayList() { "one", "two" }); putAndCheck(region, "CacheableArrayList", new List<string>() { "one", "two" }); putAndCheck(region, "CacheableLinkedList", new LinkedList<object>(new string[] { "one", "two" })); putAndCheck(region, "CacheableStack", new Stack<object>(new string[] { "one", "two" })); { var cacheableHashSet = new CacheableHashSet(); cacheableHashSet.Add("one"); cacheableHashSet.Add("two"); putAndCheck(region, "CacheableHashSet", cacheableHashSet); } { var cacheableLinkedHashSet = new CacheableLinkedHashSet(); cacheableLinkedHashSet.Add("one"); cacheableLinkedHashSet.Add("two"); putAndCheck(region, "CacheableLinkedHashSet", cacheableLinkedHashSet); } cache.TypeRegistry.RegisterPdxType(PdxType.CreateDeserializable); putAndCheck(region, "PdxType", new PdxType()); } } [Fact] public void PutGetCustomSerializableTypes() { using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1)) { Assert.True(cluster.Start()); Assert.Equal(0, cluster.Gfsh.create() .region() .withName("testRegion") .withType("REPLICATE") .execute()); var cache = cluster.CreateCache(); cache.TypeRegistry.RegisterType(Order.CreateDeserializable, 0x42); var orderRegion = cache.CreateRegionFactory(RegionShortcut.PROXY) .SetPoolName("default") .Create<int, Order>("testRegion"); Assert.NotNull(orderRegion); const int orderKey = 65; var order = new Order(orderKey, "Donuts", 12); orderRegion.Put(orderKey, order, null); var orderRetrieved = orderRegion.Get(orderKey, null); Assert.Equal(order.ToString(), orderRetrieved.ToString()); cache.Close(); } } [Fact] public void ClassAsKey() { using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1)) { Assert.Equal(cluster.Start(), true); Assert.Equal(0, cluster.Gfsh.deploy() .withJar(Config.JavaobjectJarPath) .execute()); Assert.Equal(0, cluster.Gfsh.create() .region() .withName("testRegion") .withType("REPLICATE") .execute()); Assert.Equal(0, cluster.Gfsh.executeFunction() .withId("InstantiateDataSerializable") .withMember("ClassAsKey_server_0") .execute()); var cache = cluster.CreateCache(); cache.TypeRegistry.RegisterType(PositionKey.CreateDeserializable, 21); cache.TypeRegistry.RegisterType(Position.CreateDeserializable, 22); var region = cache.CreateRegionFactory(RegionShortcut.PROXY) .SetPoolName("default") .Create<PositionKey, Position>("testRegion"); Assert.NotNull(region); var key1 = new PositionKey(1000); var key2 = new PositionKey(1000000); var key3 = new PositionKey(1000000000); var pos1 = new Position("GOOG", 23); var pos2 = new Position("IBM", 37); var pos3 = new Position("PVTL", 101); region.Put(key1, pos1); region.Put(key2, pos2); region.Put(key3, pos3); var res1 = region.Get(key1); var res2 = region.Get(key2); var res3 = region.Get(key3); Assert.True( res1.SecId == pos1.SecId && res1.SharesOutstanding == pos1.SharesOutstanding); Assert.True( res2.SecId == pos2.SecId && res2.SharesOutstanding == pos2.SharesOutstanding); Assert.True( res3.SecId == pos3.SecId && res3.SharesOutstanding == pos3.SharesOutstanding); cache.Close(); } } [Fact] public void CompositeClassWithClassAsKey() { using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 1)) { Assert.Equal(cluster.Start(), true); Assert.Equal(0, cluster.Gfsh.deploy() .withJar(Config.JavaobjectJarPath) .execute()); Assert.Equal(0, cluster.Gfsh.create() .region() .withName("testRegion") .withType("REPLICATE") .execute()); Assert.Equal(0, cluster.Gfsh.executeFunction() .withId("InstantiateDataSerializable") .withMember("CompositeClassWithClassAsKey_server_0") .execute()); var cache = cluster.CreateCache(); cache.TypeRegistry.RegisterType(PositionKey.CreateDeserializable, 21); cache.TypeRegistry.RegisterType(TestClassA.CreateDeserializable, 100); cache.TypeRegistry.RegisterType(TestClassB.CreateDeserializable, 101); cache.TypeRegistry.RegisterType(TestClassC.CreateDeserializable, 102); cache.TypeRegistry.RegisterType(CompositeClass.CreateDeserializable, 125); var region = cache.CreateRegionFactory(RegionShortcut.PROXY) .SetPoolName("default") .Create<PositionKey, CompositeClass>("testRegion"); Assert.NotNull(region); var key1 = new PositionKey(23); var key2 = new PositionKey(37); var key3 = new PositionKey(38); ICollection<PositionKey> keys = new List<PositionKey>(); keys.Add(key1); keys.Add(key2); keys.Add(key3); // First CompositeClass var cc1 = new CompositeClass(); cc1.A = new TestClassA(1, "Square", 4); cc1.Bs = new List<TestClassB>() { new TestClassB(10, 20, "Brick"), new TestClassB(11, 21, "Block"), new TestClassB(100, 200, "Stone")}; cc1.Cs = new List<TestClassC>() { new TestClassC("Red", "Volvo", 2010), new TestClassC("White", "Toyota", 2011), new TestClassC("Blue", "Nissan", 2012)}; // Second CompositeClass var cc2 = new CompositeClass(); cc2.A = new TestClassA(1, "Triangle", 3); cc2.Bs = new List<TestClassB>() { new TestClassB(100, 200, "BiggerBrick"), new TestClassB(110, 210, "BiggerBlock"), new TestClassB(1000, 2000, "BiggerStone")}; cc2.Cs = new List<TestClassC>() { new TestClassC("Gray", "Volvo", 2010), new TestClassC("Silver", "Toyota", 2011), new TestClassC("Black", "Nissan", 2012)}; // Third CompositeClass var cc3 = new CompositeClass(); cc3.A = new TestClassA(1, "Hexagon", 6); cc3.Bs = new List<TestClassB>() { new TestClassB(1000, 2000, "BiggestBrick"), new TestClassB(1100, 2100, "BiggestBlock"), new TestClassB(10000, 20000, "BiggestStone")}; cc3.Cs = new List<TestClassC>() { new TestClassC("Orange", "Volvo", 2010), new TestClassC("Yellow", "Toyota", 2011), new TestClassC("Purple", "Nissan", 2012)}; region.Put(key1, cc1); region.Put(key2, cc2); region.Put(key3, cc3); Dictionary<PositionKey, CompositeClass> ccs = new Dictionary<PositionKey, CompositeClass>(); Dictionary<PositionKey, Exception> exceptions = new Dictionary<PositionKey, Exception>(); region.GetAll(keys, ccs, exceptions, false); Assert.True(cc1.A.Equals(ccs[key1].A) && Enumerable.SequenceEqual(cc1.Bs, ccs[key1].Bs) && Enumerable.SequenceEqual(cc1.Cs, ccs[key1].Cs)); Assert.True(cc2.A.Equals(ccs[key2].A) && Enumerable.SequenceEqual(cc2.Bs, ccs[key2].Bs) && Enumerable.SequenceEqual(cc2.Cs, ccs[key2].Cs)); Assert.True(cc3.A.Equals(ccs[key3].A) && Enumerable.SequenceEqual(cc3.Bs, ccs[key3].Bs) && Enumerable.SequenceEqual(cc3.Cs, ccs[key3].Cs)); cache.Close(); } } } }