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