55e95b91231dc764e57ab493e1979a6b04ba5cb8
[mono.git] / mcs / class / corlib / Test / System.Runtime.Serialization / SerializationTest.cs
1 //
2 // System.Runtime.Serialization.SerializationTest.cs
3 //
4 // Author: Lluis Sanchez Gual  (lluis@ximian.com)
5 //
6 // (C) Ximian, Inc.
7 //
8
9 using System;
10 using System.Diagnostics;
11 using System.IO;
12 using System.Runtime.Serialization;
13 using System.Runtime.Serialization.Formatters.Binary;
14 using System.Reflection;
15 using System.Runtime.Remoting;
16 using System.Runtime.Remoting.Channels;
17 using System.Runtime.Remoting.Proxies;
18 using System.Runtime.Remoting.Messaging;
19 using System.Collections;
20 using NUnit.Framework;
21 using System.Text;
22
23 namespace MonoTests.System.Runtime.Serialization
24 {
25         [TestFixture]
26         public class SerializationTest
27         {
28                 MemoryStream ms;
29                 string uri;
30
31 #if FEATURE_REMOTING
32                 [Test]
33                 public void TestSerialization ()
34                 {
35                         MethodTester mt = new MethodTester();
36                         RemotingServices.Marshal (mt);
37                         uri = RemotingServices.GetObjectUri (mt);
38
39                         WriteData();
40                         ReadData();
41
42                         RemotingServices.Disconnect (mt);
43                 }
44 #endif
45
46 #if !MONOTOUCH && !MOBILE_STATIC
47                 [Test]
48                 public void DelegateSerializationTest ()
49                 {
50                         var a = new DelegateSerialization ();
51                         a.E += HandleE1;
52
53                         var d2 = Delegate.CreateDelegate (typeof(Func<StringBuilder, int>), "val", typeof(SerializationTest).GetMethod ("HandleE2"));
54                         a.E += (Func<StringBuilder, int>) d2;
55
56                         using (var ms = new MemoryStream ()) {
57                                 var fmt = new BinaryFormatter ();
58                                 fmt.Serialize (ms, a);
59                                 ms.Flush ();
60
61                                 ms.Seek (0, SeekOrigin.Begin);
62                                 var a2 = (DelegateSerialization) fmt.Deserialize (ms);
63                                 a2.Test ();
64                         }
65                 }
66 #endif
67
68                 static int HandleE1 (StringBuilder arg)
69                 {
70                         arg.Append ("E1");
71                         return 1;
72                 }
73
74                 public static int HandleE2 (object o, StringBuilder arg)
75                 {
76                         arg.Append ("E2|");
77                         arg.Append (o);
78                         return 2;
79                 }
80
81 #if FEATURE_REMOTING
82                 void WriteData ()
83                 {
84                         StreamingContext context = new StreamingContext (StreamingContextStates.Other);
85                         SurrogateSelector sel = new SurrogateSelector();
86                         sel.AddSurrogate (typeof (Point), context, new PointSurrogate());
87                         sel.AddSurrogate (typeof (FalseISerializable), context, new FalseISerializableSurrogate());
88
89                         List list = CreateTestData();
90                         BinderTester_A bta = CreateBinderTestData();
91
92                         ms = new MemoryStream();
93                         BinaryFormatter f = new BinaryFormatter (sel, new StreamingContext(StreamingContextStates.Other));
94                         f.Serialize (ms, list);
95                         ProcessMessages (ms, null);
96                         f.Serialize (ms, bta);
97                         ms.Flush ();
98                         ms.Position = 0;
99                 }
100
101                 void ReadData()
102                 {
103                         StreamingContext context = new StreamingContext (StreamingContextStates.Other);
104                         SurrogateSelector sel = new SurrogateSelector();
105                         sel.AddSurrogate (typeof (Point), context, new PointSurrogate());
106                         sel.AddSurrogate (typeof (FalseISerializable), context, new FalseISerializableSurrogate());
107
108                         BinaryFormatter f = new BinaryFormatter (sel, context);
109
110                         object list = f.Deserialize (ms);
111
112                         object[][] originalMsgData = null;
113                         IMessage[] calls = null;
114                         IMessage[] resps = null;
115
116                         originalMsgData = ProcessMessages (null, null);
117
118                         calls = new IMessage[originalMsgData.Length];
119                         resps = new IMessage[originalMsgData.Length];
120
121
122                         for (int n=0; n<originalMsgData.Length; n++)
123                         {
124                                 calls[n] = (IMessage) f.Deserialize (ms);
125                                 resps[n] = (IMessage) f.DeserializeMethodResponse (ms, null, (IMethodCallMessage)calls[n]);
126                         }
127
128                         f.Binder = new TestBinder ();
129                         object btbob = f.Deserialize (ms);
130
131                         ms.Close();
132
133                         List expected = CreateTestData ();
134                         List actual = (List) list;
135                         expected.CheckEquals (actual, "List");
136
137                         for (int i = 0; i < actual.children.Length - 1; ++i)
138                                 if (actual.children [i].next != actual.children [i+1])
139                                         Assert.Fail ("Deserialization did not restore pointer graph");
140
141                         BinderTester_A bta = CreateBinderTestData();
142                         Assert.AreEqual (btbob.GetType(), typeof (BinderTester_B), "BinderTest.class");
143                         BinderTester_B btb = btbob as BinderTester_B;
144                         if (btb != null)
145                         {
146                                 Assert.AreEqual (btb.x, bta.x, "BinderTest.x");
147                                 Assert.AreEqual (btb.y, bta.y, "BinderTest.y");
148                         }
149                         
150                         CheckMessages ("MethodCall", originalMsgData, ProcessMessages (null, calls));
151                         CheckMessages ("MethodResponse", originalMsgData, ProcessMessages (null, resps));
152                 }
153 #endif
154                 BinderTester_A CreateBinderTestData ()
155                 {
156                         BinderTester_A bta = new BinderTester_A();
157                         bta.x = 11;
158                         bta.y = "binder tester";
159                         return bta;
160                 }
161
162                 List CreateTestData()
163                 {
164                         List list = new List();
165                         list.name = "my list";
166                         list.values = new SomeValues();
167                         list.values.Init();
168
169                         ListItem item1 = new ListItem();
170                         ListItem item2 = new ListItem();
171                         ListItem item3 = new ListItem();
172
173                         item1.label = "value label 1";
174                         item1.next = item2;
175                         item1.value.color = 111;
176                         item1.value.point = new Point();
177                         item1.value.point.x = 11;
178                         item1.value.point.y = 22;
179
180                         item2.label = "value label 2";
181                         item2.next = item3;
182                         item2.value.color = 222;
183
184                         item2.value.point = new Point();
185                         item2.value.point.x = 33;
186                         item2.value.point.y = 44;
187
188                         item3.label = "value label 3";
189                         item3.value.color = 333;
190                         item3.value.point = new Point();
191                         item3.value.point.x = 55;
192                         item3.value.point.y = 66;
193
194                         list.children = new ListItem[3];
195
196                         list.children[0] = item1;
197                         list.children[1] = item2;
198                         list.children[2] = item3;
199
200                         return list;
201                 }
202
203
204                 object[][] ProcessMessages (Stream stream, IMessage[] messages)
205                 {
206                         object[][] results = new object[9][];
207
208                         AuxProxy prx = new AuxProxy (stream, uri);
209                         MethodTester mt = (MethodTester)prx.GetTransparentProxy();
210                         object res;
211
212                         if (messages != null) prx.SetTestMessage (messages[0]);
213                         res = mt.OverloadedMethod();
214                         results[0] = new object[] {res};
215
216                         if (messages != null) prx.SetTestMessage (messages[1]);
217                         res = mt.OverloadedMethod(22);
218                         results[1] = new object[] {res};
219
220                         if (messages != null) prx.SetTestMessage (messages[2]);
221                         int[] par1 = new int[] {1,2,3};
222                         res = mt.OverloadedMethod(par1);
223                         results[2] = new object[] { res, par1 };
224
225                         if (messages != null) prx.SetTestMessage (messages[3]);
226                         mt.NoReturn();
227
228                         if (messages != null) prx.SetTestMessage (messages[4]);
229                         res = mt.Simple ("hello",44);
230                         results[4] = new object[] { res };
231
232                         if (messages != null) prx.SetTestMessage (messages[5]);
233                         res = mt.Simple2 ('F');
234                         results[5] = new object[] { res };
235
236                         if (messages != null) prx.SetTestMessage (messages[6]);
237                         char[] par2 = new char[] { 'G' };
238                         res = mt.Simple3 (par2);
239                         results[6] = new object[] { res, par2 };
240
241                         if (messages != null) prx.SetTestMessage (messages[7]);
242                         res = mt.Simple3 (null);
243                         results[7] = new object[] { res };
244
245                         if (messages != null) prx.SetTestMessage (messages[8]);
246
247                         SimpleClass b = new SimpleClass ('H');
248                         res = mt.SomeMethod (123456, b);
249                         results[8] = new object[] { res, b };
250
251                         return results;
252                 }
253
254                 void CheckMessages (string label, object[][] original, object[][] serialized)
255                 {
256                         for (int n=0; n<original.Length; n++)
257                                 EqualsArray (label + " " + n, original[n], serialized[n]);
258                 }
259
260                 public static void AssertEquals(string message, Object expected, Object actual)
261                 {
262                         if (expected != null && expected.GetType().IsArray)
263                                 EqualsArray (message, (Array)expected, (Array)actual);
264                         else
265                                 Assert.AreEqual (expected, actual, message);
266                 }
267
268                 public static void EqualsArray (string message, object oar1, object oar2)
269                 {
270                         if (oar1 == null || oar2 == null || !(oar1 is Array) || !(oar2 is Array))
271                         {
272                                 Assert.AreEqual (oar1, oar2, message);
273                                 return;
274                         }
275
276                         Array ar1 = (Array) oar1;
277                         Array ar2 = (Array) oar2;
278
279                         Assert.AreEqual (ar1.Length, ar2.Length, message + ".Length");
280
281                         for (int n=0; n<ar1.Length; n++)
282                         {
283                                 object av1 = ar1.GetValue(n);
284                                 object av2 = ar2.GetValue(n);
285                                 SerializationTest.AssertEquals (message + "[" + n + "]", av1, av2);
286                         }
287                 }
288         }
289
290
291
292         class PointSurrogate: ISerializationSurrogate
293         {
294                 public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
295                 {
296                         Point p = (Point) obj;
297                         info.AddValue ("xv",p.x);
298                         info.AddValue ("yv",p.y);
299                 }
300
301                 public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
302                 {
303                         typeof (Point).GetField ("x").SetValue (obj, info.GetInt32 ("xv"));
304                         typeof (Point).GetField ("y").SetValue (obj, info.GetInt32 ("yv"));
305                         return obj;
306                 }
307         }
308
309         [Serializable]
310         public class List
311         {
312                 public string name = null;
313                 public ListItem[] children = null; 
314                 public SomeValues values;
315
316                 public void CheckEquals (List val, string context)
317                 {
318                         Assert.AreEqual (name, val.name, context + ".name");
319                         values.CheckEquals (val.values, context + ".values");
320
321                         Assert.AreEqual (children.Length, val.children.Length, context + ".children.Length");
322
323                         for (int n=0; n<children.Length; n++)
324                                 children[n].CheckEquals (val.children[n], context + ".children[" + n + "]");
325                 }
326         }
327
328         [Serializable]
329         public class ListItem: ISerializable
330         {
331                 public ListItem()
332                 {
333                 }
334
335                 ListItem (SerializationInfo info, StreamingContext ctx)
336                 {
337                         next = (ListItem)info.GetValue ("next", typeof (ListItem));
338                         value = (ListValue)info.GetValue ("value", typeof (ListValue));
339                         label = info.GetString ("label");
340                 }
341
342                 public void GetObjectData (SerializationInfo info, StreamingContext ctx)
343                 {
344                         info.AddValue ("next", next);
345                         info.AddValue ("value", value);
346                         info.AddValue ("label", label);
347                 }
348
349                 public void CheckEquals (ListItem val, string context)
350                 {
351                         Assert.AreEqual (label, val.label, context + ".label");
352                         value.CheckEquals (val.value, context + ".value");
353
354                         if (next == null) {
355                                 Assert.IsNull (val.next, context + ".next == null");
356                         } else {
357                                 Assert.IsNotNull (val.next, context + ".next != null");
358                                 next.CheckEquals (val.next, context + ".next");
359                         }
360                 }
361                 
362                 public override bool Equals(object obj)
363                 {
364                         ListItem val = (ListItem)obj;
365                         if ((next == null || val.next == null) && (next != val.next)) return false;
366                         if (next == null) return true;
367                         if (!next.Equals(val.next)) return false;
368                         return value.Equals (val.value) && label == val.label;
369                 }
370
371                 public override int GetHashCode ()
372                 {
373                         return base.GetHashCode ();
374                 }
375
376                 public ListItem next;
377                 public ListValue value;
378                 public string label;
379         }
380
381         [Serializable]
382         public struct ListValue
383         {
384                 public int color;
385                 public Point point;
386                 
387                 public override bool Equals(object obj)
388                 {
389                         ListValue val = (ListValue)obj;
390                         return (color == val.color && point.Equals(val.point));
391                 }
392
393                 public void CheckEquals (ListValue val, string context)
394                 {
395                         Assert.AreEqual (color, val.color, context + ".color");
396                         point.CheckEquals (val.point, context + ".point");
397                 }
398
399                 public override int GetHashCode ()
400                 {
401                         return base.GetHashCode ();
402                 }
403         }
404
405         public struct Point
406         {
407                 public int x;
408                 public int y;
409
410                 public override bool Equals(object obj)
411                 {
412                         Point p = (Point)obj;
413                         return (x == p.x && y == p.y);
414                 }
415
416                 public void CheckEquals (Point p, string context)
417                 {
418                         Assert.AreEqual (x, p.x, context + ".x");
419                         Assert.AreEqual (y, p.y, context + ".y");
420                 }
421
422                 public override int GetHashCode ()
423                 {
424                         return base.GetHashCode ();
425                 }
426         }
427
428         [Serializable]
429         public class FalseISerializable : ISerializable
430         {
431                 public int field;
432                 
433                 public FalseISerializable (int n)
434                 {
435                         field = n;
436                 }
437                 
438                 public void GetObjectData(SerializationInfo info, StreamingContext context)
439                 {
440                         throw new InvalidOperationException ("Serialize:We should not pass here.");
441                 }
442                 
443                 public FalseISerializable (SerializationInfo info, StreamingContext context)
444                 {
445                         throw new InvalidOperationException ("Deserialize:We should not pass here.");
446                 }
447         }
448         
449         public class FalseISerializableSurrogate : ISerializationSurrogate
450         {
451                 public void GetObjectData (object obj, SerializationInfo info, StreamingContext context)
452                 {
453                         info.AddValue("field", Convert.ToString (((FalseISerializable)obj).field));
454                 }
455                 
456                 public object SetObjectData (object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
457                 {
458                         ((FalseISerializable)obj).field = Convert.ToInt32 (info.GetValue("field", typeof(string)));
459                         return obj;
460                 }
461         }
462
463         [Serializable]
464         public class SimpleClass
465         {
466                 public SimpleClass (char v) { val = v; }
467
468                 public override bool Equals(object obj)
469                 {
470                         if (obj == null) return false;
471                         return val == ((SimpleClass)obj).val;
472                 }
473
474                 public override int GetHashCode()
475                 {
476                         return val.GetHashCode();
477                 }
478
479                 public int SampleCall (string str, SomeValues sv, ref int acum)
480                 {
481                         acum += (int)val;
482                         return (int)val;
483                 }
484
485                 public char val;
486         }
487
488         enum IntEnum { aaa, bbb, ccc }
489         enum ByteEnum: byte { aaa=221, bbb=3, ccc=44 }
490
491         delegate int SampleDelegate (string str, SomeValues sv, ref int acum);
492
493         [Serializable]
494         public class SomeValues
495         {
496                 Type _type;
497                 Type _type2;
498                 DBNull _dbnull;
499                 Assembly _assembly;
500                 IntEnum _intEnum;
501                 ByteEnum _byteEnum;
502
503                 bool _bool;
504                 bool _bool2;
505                 byte _byte;
506                 char _char;
507                 DateTime _dateTime;
508                 decimal _decimal;
509                 double _double;
510                 short _short;
511                 int _int;
512                 long _long;
513                 sbyte _sbyte;
514                 float _float;
515                 ushort _ushort;
516                 uint _uint;
517                 ulong _ulong;
518
519                 object[] _objects;
520                 string[] _strings;
521                 int[] _ints;
522                 public int[,,] _intsMulti;
523                 int[][] _intsJagged;
524                 SimpleClass[] _simples;
525                 SimpleClass[,] _simplesMulti;
526                 SimpleClass[][] _simplesJagged;
527                 double[] _doubles;
528                 object[] _almostEmpty;
529
530                 object[] _emptyObjectArray;
531                 Type[] _emptyTypeArray;
532                 SimpleClass[] _emptySimpleArray;
533                 int[] _emptyIntArray;
534                 string[] _emptyStringArray;
535                 Point[] _emptyPointArray;
536
537
538                 SampleDelegate _sampleDelegate;
539                 SampleDelegate _sampleDelegate2;
540                 SampleDelegate _sampleDelegate3;
541                 SampleDelegate _sampleDelegateStatic;
542                 SampleDelegate _sampleDelegateCombined;
543
544                 SimpleClass _shared1;
545                 SimpleClass _shared2;
546                 SimpleClass _shared3;
547                 
548                 FalseISerializable _falseSerializable;
549
550                 public void Init()
551                 {
552                         _type = typeof (string);
553                         _type2 = typeof (SomeValues);
554                         _dbnull = DBNull.Value;
555                         _assembly = typeof (SomeValues).Assembly;
556                         _intEnum = IntEnum.bbb;
557                         _byteEnum = ByteEnum.ccc;
558                         _bool = true;
559                         _bool2 = false;
560                         _byte = 254;
561                         _char = 'A';
562                         _dateTime = new DateTime (1972,7,13,1,20,59);
563                         _decimal = (decimal)101010.10101;
564                         _double = 123456.6789;
565                         _short = -19191;
566                         _int = -28282828;
567                         _long = 37373737373;
568                         _sbyte = -123;
569                         _float = (float)654321.321;
570                         _ushort = 61616;
571                         _uint = 464646464;
572                         _ulong = 55555555;
573
574                         Point p = new Point();
575                         p.x = 56; p.y = 67;
576                         object boxedPoint = p;
577
578                         long i = 22;
579                         object boxedLong = i;
580
581                         _objects = new object[] { "string", (int)1234, null , /*boxedPoint, boxedPoint,*/ boxedLong, boxedLong};
582                         _strings = new string[] { "an", "array", "of", "strings","I","repeat","an", "array", "of", "strings" };
583                         _ints = new int[] { 4,5,6,7,8 };
584                         _intsMulti = new int[2,3,4] { { {1,2,3,4},{5,6,7,8},{9,10,11,12}}, { {13,14,15,16},{17,18,19,20},{21,22,23,24} } };
585                         _intsJagged = new int[2][] { new int[3] {1,2,3}, new int[2] {4,5} };
586                         _simples = new SimpleClass[] { new SimpleClass('a'),new SimpleClass('b'),new SimpleClass('c') };
587                         _simplesMulti = new SimpleClass[2,3] {{new SimpleClass('d'),new SimpleClass('e'),new SimpleClass('f')}, {new SimpleClass('g'),new SimpleClass('j'),new SimpleClass('h')}};
588                         _simplesJagged = new SimpleClass[2][] { new SimpleClass[1] { new SimpleClass('i') }, new SimpleClass[2] {null, new SimpleClass('k')}};
589                         _almostEmpty = new object[2000];
590                         _almostEmpty[1000] = 4;
591
592                         _emptyObjectArray = new object[0];
593                         _emptyTypeArray = new Type[0];
594                         _emptySimpleArray = new SimpleClass[0];
595                         _emptyIntArray = new int[0];
596                         _emptyStringArray = new string[0];
597                         _emptyPointArray = new Point[0];
598
599                         _doubles = new double[] { 1010101.101010, 292929.29292, 3838383.38383, 4747474.474, 56565.5656565, 0, Double.NaN, Double.MaxValue, Double.MinValue, Double.NegativeInfinity, Double.PositiveInfinity };
600
601                         _sampleDelegate = new SampleDelegate(SampleCall);
602                         _sampleDelegate2 = new SampleDelegate(_simples[0].SampleCall);
603                         _sampleDelegate3 = new SampleDelegate(new SimpleClass('x').SampleCall);
604                         _sampleDelegateStatic = new SampleDelegate(SampleStaticCall);
605                         _sampleDelegateCombined = (SampleDelegate)Delegate.Combine (new Delegate[] {_sampleDelegate, _sampleDelegate2, _sampleDelegate3, _sampleDelegateStatic });
606
607                         // This is to test that references are correctly solved
608                         _shared1 = new SimpleClass('A');
609                         _shared2 = new SimpleClass('A');
610                         _shared3 = _shared1;
611                         
612                         _falseSerializable = new FalseISerializable (2);
613                 }
614
615                 public int SampleCall (string str, SomeValues sv, ref int acum)
616                 {
617                         acum += _int;
618                         return _int;
619                 }
620
621                 public static int SampleStaticCall (string str, SomeValues sv, ref int acum)
622                 {
623                         acum += 99;
624                         return 99;
625                 }
626
627                 public void CheckEquals (SomeValues obj, string context)
628                 {
629                         Assert.AreEqual (_type, obj._type, context + "._type");
630                         Assert.AreEqual (_type2, obj._type2, context + "._type2");
631                         Assert.AreEqual (_dbnull, obj._dbnull, context + "._dbnull");
632                         Assert.AreEqual (_assembly, obj._assembly, context + "._assembly");
633
634                         Assert.AreEqual (_intEnum, obj._intEnum, context + "._intEnum");
635                         Assert.AreEqual (_byteEnum, obj._byteEnum, context + "._byteEnum");
636                         Assert.AreEqual (_bool, obj._bool, context + "._bool");
637                         Assert.AreEqual (_bool2, obj._bool2, context + "._bool2");
638                         Assert.AreEqual (_byte, obj._byte, context + "._byte");
639                         Assert.AreEqual (_char, obj._char, context + "._char");
640                         Assert.AreEqual (_dateTime, obj._dateTime, context + "._dateTime");
641                         Assert.AreEqual (_decimal, obj._decimal, context + "._decimal");
642                         Assert.AreEqual (_double, obj._double, context + "._double");
643                         Assert.AreEqual (_short, obj._short, context = "._short");
644                         Assert.AreEqual (_int, obj._int, context + "._int");
645                         Assert.AreEqual (_long, obj._long, context + "._long");
646                         Assert.AreEqual (_sbyte, obj._sbyte, context + "._sbyte");
647                         Assert.AreEqual (_float, obj._float, context + "._float");
648                         Assert.AreEqual (_ushort, obj._ushort, context + "._ushort");
649                         Assert.AreEqual (_uint, obj._uint, context + "._uint");
650                         Assert.AreEqual (_ulong, obj._ulong, context + "._ulong");
651
652                         SerializationTest.EqualsArray (context + "._objects", _objects, obj._objects);
653                         SerializationTest.EqualsArray (context + "._strings", _strings, obj._strings);
654                         SerializationTest.EqualsArray (context + "._doubles", _doubles, obj._doubles);
655                         SerializationTest.EqualsArray (context + "._ints", _ints, obj._ints);
656                         SerializationTest.EqualsArray (context + "._simples", _simples, obj._simples);
657                         SerializationTest.EqualsArray (context + "._almostEmpty", _almostEmpty, obj._almostEmpty);
658
659                         SerializationTest.EqualsArray (context + "._emptyObjectArray", _emptyObjectArray, obj._emptyObjectArray);
660                         SerializationTest.EqualsArray (context + "._emptyTypeArray", _emptyTypeArray, obj._emptyTypeArray);
661                         SerializationTest.EqualsArray (context + "._emptySimpleArray", _emptySimpleArray, obj._emptySimpleArray);
662                         SerializationTest.EqualsArray (context + "._emptyIntArray", _emptyIntArray, obj._emptyIntArray);
663                         SerializationTest.EqualsArray (context + "._emptyStringArray", _emptyStringArray, obj._emptyStringArray);
664                         SerializationTest.EqualsArray (context + "._emptyPointArray", _emptyPointArray, obj._emptyPointArray);
665
666                         for (int i=0; i<2; i++)
667                                 for (int j=0; j<3; j++)
668                                         for (int k=0; k<4; k++)
669                                                 SerializationTest.AssertEquals("SomeValues._intsMulti[" + i + "," + j + "," + k + "]", _intsMulti[i,j,k], obj._intsMulti[i,j,k]);
670
671                         for (int i=0; i<_intsJagged.Length; i++)
672                                 for (int j=0; j<_intsJagged[i].Length; j++)
673                                         SerializationTest.AssertEquals ("SomeValues._intsJagged[" + i + "][" + j + "]", _intsJagged[i][j], obj._intsJagged[i][j]);
674
675                         for (int i=0; i<2; i++)
676                                 for (int j=0; j<3; j++)
677                                         SerializationTest.AssertEquals ("SomeValues._simplesMulti[" + i + "," + j + "]", _simplesMulti[i,j], obj._simplesMulti[i,j]);
678
679                         for (int i=0; i<_simplesJagged.Length; i++)
680                                 SerializationTest.EqualsArray ("SomeValues._simplesJagged", _simplesJagged[i], obj._simplesJagged[i]);
681
682                         int acum = 0;
683                         SerializationTest.AssertEquals ("SomeValues._sampleDelegate", _sampleDelegate ("hi", this, ref acum), _int);
684                         SerializationTest.AssertEquals ("SomeValues._sampleDelegate_bis", _sampleDelegate ("hi", this, ref acum), obj._sampleDelegate ("hi", this, ref acum));
685
686                         SerializationTest.AssertEquals ("SomeValues._sampleDelegate2", _sampleDelegate2 ("hi", this, ref acum), (int)_simples[0].val);
687                         SerializationTest.AssertEquals ("SomeValues._sampleDelegate2_bis", _sampleDelegate2 ("hi", this, ref acum), obj._sampleDelegate2 ("hi", this, ref acum));
688
689                         SerializationTest.AssertEquals ("SomeValues._sampleDelegate3", _sampleDelegate3 ("hi", this, ref acum), (int)'x');
690                         SerializationTest.AssertEquals ("SomeValues._sampleDelegate3_bis", _sampleDelegate3 ("hi", this, ref acum), obj._sampleDelegate3 ("hi", this, ref acum));
691
692                         SerializationTest.AssertEquals ("SomeValues._sampleDelegateStatic", _sampleDelegateStatic ("hi", this, ref acum), 99);
693                         SerializationTest.AssertEquals ("SomeValues._sampleDelegateStatic_bis", _sampleDelegateStatic ("hi", this, ref acum), obj._sampleDelegateStatic ("hi", this, ref acum));
694
695                         int acum1 = 0;
696                         int acum2 = 0;
697                         _sampleDelegateCombined ("hi", this, ref acum1);
698                         obj._sampleDelegateCombined ("hi", this, ref acum2);
699
700                         SerializationTest.AssertEquals ("_sampleDelegateCombined", acum1, _int + (int)_simples[0].val + (int)'x' + 99);
701                         SerializationTest.AssertEquals ("_sampleDelegateCombined_bis", acum1, acum2);
702
703                         SerializationTest.AssertEquals ("SomeValues._shared1", _shared1, _shared2);
704                         SerializationTest.AssertEquals ("SomeValues._shared1_bis", _shared1, _shared3);
705
706                         _shared1.val = 'B';
707                         SerializationTest.AssertEquals ("SomeValues._shared2", _shared2.val, 'A');
708                         SerializationTest.AssertEquals ("SomeValues._shared3", _shared3.val, 'B');
709                         
710                         SerializationTest.AssertEquals ("SomeValues._falseSerializable", _falseSerializable.field, 2);
711                 }
712         }
713
714         class MethodTester : MarshalByRefObject
715         {
716                 public int OverloadedMethod ()
717                 {
718                         return 123456789;
719                 }
720
721                 public int OverloadedMethod (int a)
722                 {
723                         return a+2;
724                 }
725
726                 public int OverloadedMethod (int[] a)
727                 {
728                         return a.Length;
729                 }
730
731                 public void NoReturn ()
732                 {}
733
734                 public string Simple (string a, int b)
735                 {
736                         return a + b;
737                 }
738
739                 public SimpleClass Simple2 (char c)
740                 {
741                         return new SimpleClass(c);
742                 }
743
744                 public SimpleClass Simple3 (char[] c)
745                 {
746                         if (c != null) return new SimpleClass(c[0]);
747                         else return null;
748                 }
749
750                 public int SomeMethod (int a, SimpleClass b)
751                 {
752                         object[] d;
753                         string c = "hi";
754                         int r = a + c.Length;
755                         c = "bye";
756                         d = new object[3];
757                         d[1] = b;
758                         return r;
759                 }
760         }
761
762         class AuxProxy: RealProxy
763         {
764                 public static bool useHeaders = false;
765                 Stream _stream;
766                 string _uri;
767                 IMethodMessage _testMsg;
768
769                 public AuxProxy(Stream stream, string uri): base(typeof(MethodTester))
770                 {
771                         _stream = stream;
772                         _uri = uri;
773                 }
774
775                 public void SetTestMessage (IMessage msg)
776                 {
777                         _testMsg = (IMethodMessage)msg;
778                         _testMsg.Properties["__Uri"] = _uri;
779                 }
780
781                 public override IMessage Invoke(IMessage msg)
782                 {
783                         IMethodCallMessage call = (IMethodCallMessage)msg;
784                         if (call.MethodName.StartsWith ("Initialize")) return new ReturnMessage(null,null,0,null,(IMethodCallMessage)msg);
785
786                         call.Properties["__Uri"] = _uri;
787
788                         if (_stream != null)
789                         {
790                                 SerializeCall (call);
791                                 IMessage response = ChannelServices.SyncDispatchMessage (call);
792                                 SerializeResponse (response);
793                                 return response;
794                         }
795                         else if (_testMsg != null)
796                         {
797                                 if (_testMsg is IMethodCallMessage)
798                                         return ChannelServices.SyncDispatchMessage (_testMsg);
799                                 else
800                                         return _testMsg;
801                         }
802                         else
803                                 return ChannelServices.SyncDispatchMessage (call);
804                 }
805
806                 void SerializeCall (IMessage call)
807                 {
808                         RemotingSurrogateSelector rss = new RemotingSurrogateSelector();
809                         var fmt = new BinaryFormatter (rss, new StreamingContext(StreamingContextStates.Remoting));
810                         fmt.Serialize (_stream, call, GetHeaders());
811                 }
812
813                 void SerializeResponse (IMessage resp)
814                 {
815                         RemotingSurrogateSelector rss = new RemotingSurrogateSelector();
816                         var fmt = new BinaryFormatter (rss, new StreamingContext(StreamingContextStates.Remoting));
817                         fmt.Serialize (_stream, resp, GetHeaders());
818                 }
819
820                 Header[] GetHeaders()
821                 {
822                         Header[] hs = null;
823                         if (useHeaders)
824                         {
825                                 hs = new Header[1];
826                                 hs[0] = new Header("unom",new SimpleClass('R'));
827                         }
828                         return hs;
829                 }
830         }
831
832         public class TestBinder : SerializationBinder
833         {
834                 public override Type BindToType (string assemblyName, string typeName)
835                 {
836                         if (typeName.IndexOf("BinderTester_A") != -1)
837                                 typeName = typeName.Replace ("BinderTester_A", "BinderTester_B");
838
839                         return Assembly.Load (assemblyName).GetType (typeName);
840                 }
841         }
842
843         [Serializable]
844         public class BinderTester_A
845         {
846                 public int x;
847                 public string y;
848         }
849
850         [Serializable]
851         public class BinderTester_B
852         {
853                 public string y;
854                 public int x;
855         }
856
857         [Serializable]
858         class DelegateSerialization
859         {
860                 public event Func<StringBuilder, int> E;
861
862                 public void Test ()
863                 {
864                         var sb = new StringBuilder ();
865                         Assert.AreEqual (2, E (sb), "#1");
866                         Assert.AreEqual ("E1E2|val", sb.ToString (), "#2");
867                 }
868         }
869
870 }