|  | /* | 
|  | * 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(); | 
|  | } | 
|  | } | 
|  | } | 
|  | } |