X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FTest%2FSystem.Runtime.Serialization.Formatters.Binary%2FBinaryFormatterTest.cs;h=6d4b997fb45317b67a5c928e23f97d46332aa4e8;hb=e82dc02e27ea872f3f1bd19d8a6c9770ae12716d;hp=3173e57ecbc7a241b33fa593f17de9f1bc482dc1;hpb=f1f8b8a867c800b21b6a03767252403c2f72cae2;p=mono.git diff --git a/mcs/class/corlib/Test/System.Runtime.Serialization.Formatters.Binary/BinaryFormatterTest.cs b/mcs/class/corlib/Test/System.Runtime.Serialization.Formatters.Binary/BinaryFormatterTest.cs index 3173e57ecbc..6d4b997fb45 100644 --- a/mcs/class/corlib/Test/System.Runtime.Serialization.Formatters.Binary/BinaryFormatterTest.cs +++ b/mcs/class/corlib/Test/System.Runtime.Serialization.Formatters.Binary/BinaryFormatterTest.cs @@ -32,13 +32,15 @@ using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters; using System.Runtime.Serialization.Formatters.Binary; +using System.Reflection; using NUnit.Framework; -namespace MonoTests.System.Runtime.Serialization.Formatters.Binary { - +namespace MonoTests.System.Runtime.Serialization.Formatters.Binary +{ [Serializable] - public class SerializationTest { + public class SerializationTest + { private int integer; [NonSerialized] private bool boolean; @@ -60,7 +62,47 @@ namespace MonoTests.System.Runtime.Serialization.Formatters.Binary { } } - class SurrogateSelector: ISurrogateSelector { + namespace NestedA + { + [Serializable] + public class QualifiedFieldTest + { + int value = 0; + + public int ValueA { + get { return value; } + set { this.value = value; } + } + } + } + + namespace NestedB + { + [Serializable] + public class QualifiedFieldTest : NestedA.QualifiedFieldTest + { + int value = 0; + + public int ValueB { + get { return value; } + set { this.value = value; } + } + } + } + + [Serializable] + public class QualifiedFieldTest : NestedB.QualifiedFieldTest + { + int value = 0; + + public int Value { + get { return value; } + set { this.value = value; } + } + } + + class SurrogateSelector: ISurrogateSelector + { public void ChainSelector (ISurrogateSelector selector) { } @@ -109,18 +151,206 @@ namespace MonoTests.System.Runtime.Serialization.Formatters.Binary { } } - [TestFixture] - public class BinaryFormatterTest { + [Serializable] + class Foo + { + private int privateFoo; + protected int familyFoo; + protected internal int familyANDAssemFoo; + public int publicFoo; + internal int assemblyFoo; + + public int PrivateFoo { + get { return privateFoo; } + } + + public int FamilyFoo { + get { return familyFoo; } + } + + public int FamilyANDAssemFoo { + get { return familyANDAssemFoo; } + } + + public int PublicFoo { + get { return publicFoo; } + } + + public int AssemblyFoo { + get { return assemblyFoo; } + } + public virtual void Init () + { + privateFoo = 1; + familyFoo = 2; + familyANDAssemFoo = 4; + publicFoo = 8; + assemblyFoo = 16; + } + } + + [Serializable] + class Bar : Foo + { + private int privateBar; + protected int familyBar; + protected internal int familyANDAssemBar; + public int publicBar; + internal int assemblyBar; + + public int PrivateBar { + get { return privateBar; } + } + + public int FamilyBar { + get { return familyBar; } + } + + public int FamilyANDAssemBar { + get { return familyANDAssemBar; } + } + + public int PublicBar { + get { return publicBar; } + } + + public int AssemblyBar { + get { return assemblyBar; } + } + + public override void Init () + { + privateBar = 1; + familyBar = 2; + familyANDAssemBar = 4; + publicBar = 8; + assemblyBar = 16; + + base.Init (); + } + } + + [Serializable] + public class Comparable + { + public int Foo { + get; + set; + } + + public override bool Equals (object obj) + { + var other = obj as Comparable; + if (other == null) + return false; + return other.Foo == Foo; + } + + public override int GetHashCode () + { + return Foo; + } + } + + class Class + { + public string Name; + + public virtual Instance NewInstance() + { + return new Instance { Class = this }; + } + } + + class Instance + { + public Class Class; + } + + + [Serializable] + class ClassSerializationProxy : IObjectReference + { + string className; + + public ClassSerializationProxy (Class klass) + { + this.className = klass.Name; + } + + public object GetRealObject(StreamingContext context) + { + return new Class { Name = className }; + } + } + + [Serializable] + class ObjectStreamClass : Class, IObjectReference, ISerializable + { + Class klass; + + public ObjectStreamClass (Class klass) + { + this.klass = klass; + } + + public ObjectStreamClass(SerializationInfo info, StreamingContext context) + { + klass = (Class)info.GetValue("0", typeof(object)); + } + + public object GetRealObject (StreamingContext context) + { + return this; + } + + public void GetObjectData (SerializationInfo info, StreamingContext context) + { + info.AddValue ("0", new ClassSerializationProxy (klass)); + } + + public override Instance NewInstance() + { + return klass.NewInstance(); + } + } + + [Serializable] + class DynamicProxy: IObjectReference, ISerializable + { + Instance obj; + + public DynamicProxy (Instance obj) + { + this.obj = obj; + } + + public DynamicProxy (SerializationInfo info, StreamingContext context) + { + ObjectStreamClass osc = (ObjectStreamClass) info.GetValue("0", typeof(object)); + obj = osc.NewInstance(); + } + + public object GetRealObject (StreamingContext context) + { + return obj; + } + + public void GetObjectData (SerializationInfo info, StreamingContext context) + { + info.AddValue ("0", new ObjectStreamClass (obj.Class)); + } + } + + [TestFixture] + public class BinaryFormatterTest + { [Test] public void Constructor_Default () { BinaryFormatter bf = new BinaryFormatter (); -#if NET_2_0 Assert.AreEqual (FormatterAssemblyStyle.Simple, bf.AssemblyFormat, "AssemblyFormat"); -#else - Assert.AreEqual (FormatterAssemblyStyle.Full, bf.AssemblyFormat, "AssemblyFormat"); -#endif Assert.IsNull (bf.Binder, "Binder"); Assert.AreEqual (StreamingContextStates.All, bf.Context.State, "Context"); Assert.AreEqual (TypeFilterLevel.Full, bf.FilterLevel, "FilterLevel"); @@ -133,11 +363,7 @@ namespace MonoTests.System.Runtime.Serialization.Formatters.Binary { { SurrogateSelector ss = new SurrogateSelector (); BinaryFormatter bf = new BinaryFormatter (ss, new StreamingContext (StreamingContextStates.CrossMachine)); -#if NET_2_0 Assert.AreEqual (FormatterAssemblyStyle.Simple, bf.AssemblyFormat, "AssemblyFormat"); -#else - Assert.AreEqual (FormatterAssemblyStyle.Full, bf.AssemblyFormat, "AssemblyFormat"); -#endif Assert.IsNull (bf.Binder, "Binder"); Assert.AreEqual (StreamingContextStates.CrossMachine, bf.Context.State, "Context"); Assert.AreEqual (TypeFilterLevel.Full, bf.FilterLevel, "FilterLevel"); @@ -145,14 +371,29 @@ namespace MonoTests.System.Runtime.Serialization.Formatters.Binary { Assert.AreEqual (FormatterTypeStyle.TypesAlways, bf.TypeFormat, "TypeFormat"); } - public Stream GetSerializedStream () + [Test] + public void Inheritance () { - SerializationTest test = new SerializationTest (true, Int32.MinValue); - BinaryFormatter bf = new BinaryFormatter (); MemoryStream ms = new MemoryStream (); - bf.Serialize (ms, test); + BinaryFormatter bf = new BinaryFormatter (); + + Bar bar = new Bar (); + bar.Init (); + + bf.Serialize (ms, bar); ms.Position = 0; - return ms; + + Bar clone = (Bar) bf.Deserialize (ms); + Assert.AreEqual (bar.PrivateBar, clone.PrivateBar, "#1"); + Assert.AreEqual (bar.FamilyBar, clone.FamilyBar, "#2"); + Assert.AreEqual (bar.FamilyANDAssemBar, clone.FamilyANDAssemBar, "#3"); + Assert.AreEqual (bar.PublicBar, clone.PublicBar, "#4"); + Assert.AreEqual (bar.AssemblyBar, clone.AssemblyBar, "#5"); + Assert.AreEqual (bar.PrivateFoo, clone.PrivateFoo, "#6"); + Assert.AreEqual (bar.FamilyFoo, clone.FamilyFoo, "#7"); + Assert.AreEqual (bar.FamilyANDAssemFoo, clone.FamilyANDAssemFoo, "#8"); + Assert.AreEqual (bar.PublicFoo, clone.PublicFoo, "#9"); + Assert.AreEqual (bar.AssemblyFoo, clone.AssemblyFoo, "#10"); } [Test] @@ -189,12 +430,9 @@ namespace MonoTests.System.Runtime.Serialization.Formatters.Binary { bf.Deserialize(ms); Assert.AreEqual (2, ThisObjectReference.Count, "#2"); Assert.AreEqual (0, NewObjectReference.Count, "#3"); - try - { + try { bf.Deserialize(ms); - } - catch (SerializationException e) - { + } catch (SerializationException) { } Assert.AreEqual (101, NewObjectReference.Count, "#4"); } @@ -224,5 +462,265 @@ namespace MonoTests.System.Runtime.Serialization.Formatters.Binary { for (int i = 0; i < e.Length; ++i) Assert.AreEqual (e [i], a [i], names [i]); } + + [Test] + public void GenericArray () + { + Comparable [] a = new Comparable [1]; + a [0] = new Comparable (); + + BinaryFormatter bf = new BinaryFormatter (); + MemoryStream ms = new MemoryStream (); + + bf.Serialize (ms, a); + + ms.Position = 0; + Comparable [] b = (Comparable []) bf.Deserialize (ms); + + Assert.AreEqual (a.Length, b.Length, "#1"); + Assert.AreEqual (a [0], b [0], "#2"); + } + + public Stream GetSerializedStream () + { + SerializationTest test = new SerializationTest (true, Int32.MinValue); + BinaryFormatter bf = new BinaryFormatter (); + MemoryStream ms = new MemoryStream (); + bf.Serialize (ms, test); + ms.Position = 0; + return ms; + } + + [Test] + public void QualifiedField() + { + QualifiedFieldTest a = new QualifiedFieldTest (); + a.ValueA = 1; + a.ValueB = 2; + a.Value = 3; + Stream ms = new MemoryStream (); + BinaryFormatter bf = new BinaryFormatter (); + bf.Serialize(ms, a); + ms.Position = 0; + QualifiedFieldTest b = (QualifiedFieldTest)bf.Deserialize (ms); + Assert.AreEqual (a.ValueA, b.ValueA, "#1"); + Assert.AreEqual (a.ValueB, b.ValueB, "#2"); + Assert.AreEqual (a.Value, b.Value, "#3"); + } + +#if NET_4_0 + [Test] + public void SerializationBindToName () + { + BinaryFormatter bf = new BinaryFormatter (); + bf.AssemblyFormat = FormatterAssemblyStyle.Full; + bf.Binder = new SimpleSerializationBinder (); + MemoryStream ms = new MemoryStream (); + + SimpleSerializableObject o = new SimpleSerializableObject (); + o.Name = "MonoObject"; + o.Id = 666; + + bf.Serialize (ms, o); + ms.Position = 0; + + o = (SimpleSerializableObject)bf.Deserialize (ms); + Assert.AreEqual ("MonoObject", o.Name); + Assert.AreEqual (666, o.Id); + } + + class SimpleSerializationBinder : SerializationBinder + { + public override Type BindToType (string assemblyName, string typeName) + { + // We *should* be getting a SimpleSerializableObject2 instance + // Otherwise it means we are not getting called our BindToName method. + if (!typeName.EndsWith ("SimpleSerializableObject2")) + Assert.Fail ("#BindToType-TypeName"); + + // We are also supposed to be getting a 9.9.9.9 version here, + // and if we get a different version, it likely means BindToName was called. + AssemblyName aname = Assembly.GetExecutingAssembly ().GetName (); + aname.Version = new Version (9, 9, 9, 9); + if (aname.ToString () != assemblyName) + Assert.Fail ("#BindToType-AssemblyName"); + + // No need to call Type.GetType + return typeof (SimpleSerializableObject); + } + + public override void BindToName (Type serializedType, out string assemblyName, out string typeName) + { + AssemblyName aname = Assembly.GetExecutingAssembly ().GetName (); + aname.Version = new Version (9, 9, 9, 9); + + // Serialize mapping to this same assembly with 9.9.9.9 version + // and a different type name. + assemblyName = aname.ToString (); + typeName = serializedType.FullName.Replace ("SimpleSerializableObject", "SimpleSerializableObject2"); + } + } + + [Serializable] + class SimpleSerializableObject + { + public string Name { get; set; } + public int Id { get; set; } + } + + [Test] + public void SerializationBindToName2 () + { + BinaryFormatter bf = new BinaryFormatter (); + bf.AssemblyFormat = FormatterAssemblyStyle.Full; + bf.Binder = new SimpleSerializationBinder2 (); + MemoryStream ms = new MemoryStream (); + + SimpleISerializableObject o = new SimpleISerializableObject (); + o.Name = "MonoObject"; + o.Id = 666; + + bf.Serialize (ms, o); + ms.Position = 0; + + o = (SimpleISerializableObject)bf.Deserialize (ms); + Assert.AreEqual ("MonoObject", o.Name); + Assert.AreEqual (666, o.Id); + + ms.Close (); + } + + [Test] + public void NestedObjectReferences () + { + MemoryStream ms = new MemoryStream (); + + var cls = new Class { Name = "MyClass" }; + var ob = cls.NewInstance (); + + BinaryFormatter bf = new BinaryFormatter(); + bf.Serialize (ms, new DynamicProxy (ob)); + + ms.Position = 0; + + Instance ins = (Instance) bf.Deserialize (ms); + Assert.AreEqual ("MyClass", ins.Class.Name); + } + + class SimpleSerializationBinder2 : SerializationBinder + { + public override void BindToName (Type serializedType, out string assemblyName, out string typeName) + { + AssemblyName aname = Assembly.GetExecutingAssembly ().GetName (); + aname.Version = new Version (9, 9, 9, 9); + + // Serialize mapping to this same assembly with 9.9.9.9 version + // and a different type name. + assemblyName = aname.ToString (); + typeName = serializedType.FullName.Replace ("SimpleISerializableObject", "SimpleISerializableObject2"); + } + + public override Type BindToType (string assemblyName, string typeName) + { + // We *should* be getting a SimpleISerializableObject2 instance + if (!typeName.EndsWith ("SimpleISerializableObject2")) + Assert.Fail ("#BindToType-TypeName"); + + // We are also supposed to be getting a 9.9.9.9 version here, + // and if we get a different version, it likely means BindToName was called. + AssemblyName aname = Assembly.GetExecutingAssembly ().GetName (); + aname.Version = new Version (9, 9, 9, 9); + if (aname.ToString () != assemblyName) + Assert.Fail ("#BindToType-AssemblyName"); + + return typeof (SimpleISerializableObject); + } + } + + [Serializable] + class SimpleISerializableObject : ISerializable + { + public string Name { get; set; } + public int Id { get; set; } + + public SimpleISerializableObject () + { + } + + protected SimpleISerializableObject (SerializationInfo info, StreamingContext context) + { + Name = info.GetString ("Name"); + Id = info.GetInt32 ("Id"); + } + + public void GetObjectData (SerializationInfo info, StreamingContext context) + { + info.AddValue ("Name", Name); + info.AddValue ("Id", Id); + } + } + + [Serializable] + public class OtherClass + { + } + + [Serializable] + public class BaseClass + { + public OtherClass Other { get; set; } + } + + public class CustomSerBinder: SerializationBinder + { + public override void BindToName (Type serializedType, out string assemblyName, out string typeName) + { + assemblyName = null; + if (serializedType == typeof (BaseClass)) + typeName = "base"; + else if (serializedType == typeof (OtherClass)) + typeName = "other"; + else + throw new ArgumentException ("Unknown type", "serializedType"); + } + + public override Type BindToType (string assemblyName, string typeName) + { + switch (typeName) { + case "base": + return typeof (BaseClass); + case "other": + return typeof (OtherClass); + default: + throw new ArgumentException ("Unknown type name", "typeName"); + } + } + } + + [Test] + public void BinderShouldBeUsedForProperties () + { + using (var serStream = new MemoryStream ()) { + var binder = new CustomSerBinder (); + + // serialize + var original = new BaseClass () { + Other = new OtherClass () + }; + var formatter = new BinaryFormatter (); + formatter.Binder = binder; + formatter.Serialize (serStream, original); + + // deserialize, making sure we're using a new formatter, just to be thorough + formatter = new BinaryFormatter (); + formatter.Binder = binder; + serStream.Seek (0, SeekOrigin.Begin); + var deserialized = formatter.Deserialize (serStream); + + Assert.AreEqual (original.GetType (), deserialized.GetType ()); + Assert.AreEqual (original.Other.GetType (), ((BaseClass)deserialized).Other.GetType ()); + } + } +#endif } }