Add unit test for AggregateException.GetBaseException that works on .net but is broke...
[mono.git] / mcs / tests / test-async-13.cs
1 using System;
2 using System.Threading.Tasks;
3 using System.Threading;
4 using System.Reflection;
5 using System.Linq;
6 using System.Runtime.CompilerServices;
7
8 struct S
9 {
10         public int Value;
11         
12         public S (int a1, string a2)
13         {
14                 Value = a1;
15         }
16         
17         public void SetValue (int value)
18         {
19                 Value = value;
20         }
21         
22         public static implicit operator S (Base b)
23         {
24                 return new S (400, "a");
25         }
26         
27         public static S operator + (S a, S b)
28         {
29                 return new S () {
30                         Value = a.Value + b.Value
31                 };
32         }
33 }
34
35 enum E
36 {
37         E_1 = 1
38 }
39
40 class Base
41 {
42         public volatile int field_int;
43         protected int field_this;
44         protected int property_this_counter;
45         
46         public event Action Event;
47         
48         public Base ()
49         {
50         }
51         
52         public Base (int arg, int arg2)
53         {
54                 field_int = arg;
55         }
56         
57         public bool PropertyBool {
58                 get {
59                         return true;
60                 }
61         }
62         
63         public int PropertyInt {
64                 get {
65                         return field_int;
66                 }
67                 set {
68                         field_int += value;
69                 }
70         }
71         
72         protected Base PropertyThis {
73                 get {
74                         ++property_this_counter;
75                         return this;
76                 }
77         }
78         
79         public int this [int arg] {
80                 get {
81                         return field_this;
82                 }
83                 set {
84                         field_this += value * arg;
85                 }
86         }
87         
88         public static bool operator true (Base a)
89         {
90                 return true;
91         }
92
93         public static bool operator false (Base a)
94         {
95                 return false;
96         }
97         
98         public static Base operator & (Base a, Base b)
99         {
100                 return new Base () {
101                         field_int = 100
102                 };
103         }
104         
105         public static Base operator | (Base a, Base b)
106         {
107                 return new Base () {
108                         field_int = 200
109                 };
110         }
111         
112         protected int Call (int arg1, int arg2, int arg3)
113         {
114                 if (arg1 != 5)
115                         return 1;
116
117                 if (arg2 != -3)
118                         return 2;
119
120                 if (arg3 != 6)
121                         return 3;
122
123                 return 0;
124         }
125         
126         protected int Call(ref char ch, int arg)
127         {
128                 ch = 'z';
129                 return arg;
130         }
131         
132         public void CallBool (bool b)
133         {
134         }
135         
136         public int CallS (S s)
137         {
138                 return s.Value;
139         }
140         
141         public T[] CreateArray<T> (int size)
142         {
143                 return new T [size];
144         }
145         
146         protected static void CallRefParams (ref int i, params int[] i2)
147         {
148                 i = 5;
149         }
150         
151         protected int CallNamed (int a, int b)
152         {
153                 return a - b;
154         }
155         
156         protected void CallEvent ()
157         {
158                 Event ();
159         }
160 }
161
162 class Tester : Base
163 {
164         async Task<bool> ArrayAccessTest_1 ()
165         {
166                 bool[] b = new bool[1];
167                 b [0] = await Task.Factory.StartNew (() => true);
168                 return b[await Task.Factory.StartNew (() => 0)];
169         }
170         
171         async Task<int> ArrayAccessTest_2 ()
172         {
173                 double[] b = new double[2];
174                 b [await Task.Factory.StartNew (() => 1)] = 5.5;
175                 if (b [1] != 5.5)
176                         return 1;
177                 
178                 var d = b [await Task.Factory.StartNew (() => 1)] = 2.5;
179                 if (b [1] != 2.5)
180                         return 2;
181                 
182                 if (d != 2.5)
183                         return 3;
184                 
185                 d = b [await Task.Factory.StartNew (() => 1)] = await Task.Factory.StartNew (() => 4.4);
186                 if (d != 4.4)
187                         return 4;
188                 
189                 return 0;
190         }
191
192         async Task<int> ArrayAccessTest_3 ()
193         {
194                 decimal[] d = new decimal [4];
195                 d[1] = 4;
196                 
197                 var r = ++d[await Task.Factory.StartNew (() => 1)];
198                 if (r != 5)
199                         return 1;
200                 
201                 d [1] = 6;
202                 d [await Task.Factory.StartNew (() => 1)] += await Task.Factory.StartNew (() => 9.9m);
203                 if (d [1] != 15.9m)
204                         return 2;
205                 
206                 d [1] = 6;
207                 r =  d [await Task.Factory.StartNew (() => 1)] -= await Task.Factory.StartNew (() => 5.9m);
208                 if (d [1] != 0.1m)
209                         return 3;
210                 
211                 return 0;
212         }
213         
214         async Task<bool> ArrayAccessTest_4 ()
215         {
216                 string[] s = new string [4];
217                 s[1] = "a";
218                 
219                 s [await Task.Factory.StartNew (() => 1)] += await Task.Factory.StartNew (() => "b");
220                 return s [1] == "ab";
221         }
222         
223         async Task<bool> ArrayAccessTest_5 ()
224         {
225                 int[][] a = new int[3][];
226                 a [1] = new int [5];
227                 int index = 1;
228                 CallRefParams (ref a[await Task.Factory.StartNew (() => index++)][0], await Task.Factory.StartNew (() => 3));
229                 return a [1][0] == 5;
230         }
231
232         async Task<int> ArrayAccessTest_6 ()
233         {
234                 int value = -6;
235                 int[] a = new int[3] { 3, 6, 9 };
236                 return a [await Task.Factory.StartNew (() => (long)1)] + value;
237         }
238         
239         async Task<bool> ArrayAccessTest_7 ()
240         {
241                 short?[] s = new short?[] { 3, 2, 1 };
242                 var r = s [await Task.Factory.StartNew (() => 1)]++;
243                 return r == 2;
244         }
245
246         async Task<int> ArrayAccessTest_8 ()
247         {
248                 var s = new byte?[] { 3, 2, 1 };
249                 var r = s [await Task.Factory.StartNew (() => 1)] += await Task.Factory.StartNew (() => (byte)30);
250                 if (r != 32)
251                         return 1;
252                 
253                 if (s [1] != 32)
254                         return 2;
255                 
256                 return 0;
257         }
258
259         async Task<int> ArrayAccessTest_9 ()
260         {
261                 var s = new Base ();
262                 s.CreateArray<int> (await Task.Factory.StartNew (() => 5)) [2] += 9;
263                 s.CreateArray<int> (await Task.Factory.StartNew (() => 5)) [2] += await Task.Factory.StartNew (() => 9);
264                 
265                 var res = s.CreateArray<int> (await Task.Factory.StartNew (() => 5)) [2] += await Task.Factory.StartNew (() => 9);
266                 if (res != 9)
267                         return 1;
268
269                 s.CreateArray<S> (await Task.Factory.StartNew (() => 5)) [2] += await Task.Factory.StartNew (() => new S () { Value = 4 });
270                 return 0;
271         }
272
273         async Task<int> AssignTest_1 ()
274         {
275                 field_int = await Task.Factory.StartNew (() => 0);
276                 return field_int;
277         }
278         
279         async Task<bool> AssignTest_2 ()
280         {
281                 long? l = await Task.Factory.StartNew<sbyte?> (() => null);
282                 return l == null;
283         }
284         
285         async Task<int> AssignTest_3 ()
286         {
287                 int a = await Task.Factory.StartNew (() => 1), b = await Task.Factory.StartNew (() => 2);
288                 if (a != 1)
289                         return 1;
290                 if (b != 2)
291                         return b;
292                 
293                 return 0;
294         }
295         
296         async Task<int> BinaryTest_1 ()
297         {
298                 return await Task.Factory.StartNew (() => { Thread.Sleep (10); return 5; }) +
299                         await Task.Factory.StartNew (() => -3) +
300                         await Task.Factory.StartNew (() => -2);
301         }
302         
303         async Task<int> BinaryTest_2 ()
304         {
305                 int i = 1;
306                 var b = await Task.Factory.StartNew (() => { i += 3; return true; }) &&
307                         await Task.Factory.StartNew (() => { i += 4; return false; }) &&
308                         await Task.Factory.StartNew (() => { i += 5; return true; });
309
310                 return b ? -1 : i == 8 ? 0 : i;
311         }
312         
313         async Task<int> BinaryTest_3 ()
314         {
315                 var r = await Task.Factory.StartNew<bool?> (() => true) & await Task.Factory.StartNew<bool?> (() => null);
316                 if (r != null)
317                         return 1;
318
319                 r = await Task.Factory.StartNew<bool?> (() => null) | await Task.Factory.StartNew<bool?> (() => true);
320                 if (r != true)
321                         return 2;
322                 
323                 r = await Task.Factory.StartNew<bool?> (() => null) != await Task.Factory.StartNew<bool?> (() => true);
324                 if (r != true)
325                         return 3;
326
327                 return 0;
328         }
329         
330         async Task<int> BinaryTest_4 ()
331         {
332                 var r1 = await Task.Factory.StartNew<short?> (() => 2) * await Task.Factory.StartNew<byte?> (() => null);
333                 if (r1 != null)
334                         return 1;
335
336                 var r2 = await Task.Factory.StartNew<decimal?> (() => 100) / await Task.Factory.StartNew<decimal?> (() => null);
337                 if (r2 != null)
338                         return 2;
339                 
340                 return 0;
341         }
342         
343         async Task<int> BinaryTest_5 ()
344         {
345                 var r1 = await Task.FromResult (1) == 9;
346                 if (r1)
347                         return 1;
348                 
349                 var r2 = 1 == await Task.FromResult (1);
350                 if (!r2)
351                         return 2;
352                 
353                 return 0;
354         }
355
356         async Task<bool> BinaryTest_6 ()
357         {
358                 var t = Task.Delay (1);
359                 if (t == await Task.WhenAny(new [] { t }))
360                         return true;
361
362                 return false;
363         }
364
365         async Task<int> CallTest_1 ()
366         {
367                 return Call (
368                         await Task.Factory.StartNew (() => { Thread.Sleep (10); return 5; }),
369                         await Task.Factory.StartNew (() => -3),
370                         await Task.Factory.StartNew (() => 6));
371         }
372         
373         async Task<bool> CallTest_2 ()
374         {
375                 char ch = 'a';
376                 var r = Call (
377                         ref ch, 
378                         await Task.Factory.StartNew (() => { Thread.Sleep (10); return 5; }));
379                 
380                 return ch == 'z' && r == 5;
381         }
382
383         async Task<int> CallTest_3 ()
384         {
385                 S s = new S ();
386                 s.SetValue (await Task.Factory.StartNew (() => 10));
387                 return s.Value - 10;
388         }
389
390         async Task<bool> CallTest_4 ()
391         {
392                 return E.E_1.Equals (unchecked (await Task.Factory.StartNew (() => E.E_1)));
393         }
394
395         async Task<int> CallTest_5 ()
396         {
397                 int value = 9;
398                 return CallNamed (
399                         b: await Task.Factory.StartNew (() => value++),
400                         a: value) - 1;
401         }
402         
403         async Task<bool> CastTest_1 ()
404         {
405                 decimal value = 67;
406                 return (value - await Task.Factory.StartNew (() => 66m)) == 1;
407         }
408         
409         async Task<bool> CastTest_2 ()
410         {
411                 var t = new Tester ();
412                 return t.CallS (await Task.Factory.StartNew (() => this)) == 400;
413         }
414         
415         async Task<bool> CoalescingTest_1 ()
416         {
417                 var r = await Task.Factory.StartNew<string> (() => null)  ?? await Task.Factory.StartNew (() => "x");
418                 return r == "x";
419         }
420         
421         async Task<bool> CoalescingTest_2 ()
422         {
423                 var r = await Task.Factory.StartNew<short?> (() => null)  ?? await Task.Factory.StartNew<byte> (() => 2);
424                 return r == 2;
425         }
426         
427         async Task<int> ConditionalTest_1 ()
428         {
429                 return true ? await Task.Factory.StartNew (() => 0) : await Task.Factory.StartNew (() => 1);
430         }
431         
432         async Task<int> ConditionalTest_2 ()
433         {
434                 return PropertyBool ? await Task.Factory.StartNew (() => 0) : await Task.Factory.StartNew (() => 1);
435         }
436         
437         async Task<int> ConditionalTest_3 ()
438         {
439                 int v = 5;
440                 return v * (await Task.Factory.StartNew (() => true) ? 0 : await Task.Factory.StartNew (() => 1));
441         }
442         
443         async Task<int> ConditionalTest_4 ()
444         {
445                 int v = 5;
446                 return v * (v == 2 ? 3 : await Task.Factory.StartNew (() => 0));
447         }
448         
449         async Task<int> DelegateInvoke_4 ()
450         {
451                 Func<int, int> d = l => l - 3;
452                 int value = 1;
453                 return value + d (await Task.Factory.StartNew (() => 2));
454         }
455         
456         async Task<int> EventInvoke_1 ()
457         {
458                 int value = 0;
459                 Event += await Task.Factory.StartNew (() => {
460                         Action a = () => { value = 5; };
461                         return a;
462                 });
463                 
464                 CallEvent ();
465                 return value - 5;
466         }
467         
468         async Task<int> FieldTest_1 ()
469         {
470                 var s = new Base ();
471                 s.field_int = 3;
472                 s.field_int += await Task.Factory.StartNew (() => 6);
473                 if (s.field_int != 9)
474                         return 1;
475                 
476                 var r = s.field_int -= await Task.Factory.StartNew (() => 5);
477                 if (r != 4)
478                         return 2;
479                 
480                 if (s.field_int != 4)
481                         return 3;
482                 return 0;
483         }
484
485         async Task<bool> IndexerTest_1 ()
486         {
487                 this[2] = await Task.Factory.StartNew (() => 6);
488                 return this[2] == 12;
489         }
490
491         async Task<bool> IndexerTest_2 ()
492         {
493                 this[await Task.Factory.StartNew (() => 3)] = await Task.Factory.StartNew (() => 6);
494                 return this[3] == 18;
495         }
496         
497         async Task<int> IndexerTest_3 ()
498         {
499                 int value = -5;
500                 this[await Task.Factory.StartNew (() => value++)] += await Task.Factory.StartNew (() => 5);
501                 return this[3] + 25;
502         }
503         
504         async Task<int> IndexerTest_4 ()
505         {
506                 int value = 3;
507                 PropertyThis[await Task.Factory.StartNew (() => value++)] += await Task.Factory.StartNew (() => -5);
508                 return PropertyThis[3] + value + 11;
509         }
510         
511         async Task<int> IndexerTest_5 ()
512         {
513                 int value = 3;
514                 field_this = 6;
515                 int res = PropertyThis[await Task.Factory.StartNew (() => value++)]++;
516                 if (res != 6)
517                         return 1;
518
519                 if (PropertyThis[0] != 27)
520                         return 2;
521
522                 return PropertyThis[5] -= await Task.Factory.StartNew (() => 27);
523         }
524         
525         async Task<int> IndexerTest_6 ()
526         {
527                 var r = this[3] = await Task.Factory.StartNew (() => 9);
528                 if (r != 9)
529                         return 1;
530                 
531                 var r2 = this[await Task.Factory.StartNew (() => 55)] = await Task.Factory.StartNew (() => 8);
532
533                 if (r2 != 8)
534                         return 2;
535                 
536                 return 0;
537         }
538         
539         async Task<bool> IndexerTest_7 ()
540         {
541                 int value = -5;
542                 var res = ++this[await Task.Factory.StartNew (() => value++)];
543                 return res == 1;
544         }
545         
546         async Task<bool> IsTest_1 ()
547         {
548                 new Tester ().CallBool (await Task.Factory.StartNew (() => new Tester ()) is Base);
549                 return true;
550         }
551
552         async Task<bool> IsTest_2 ()
553         {
554                 var r = await Task.Factory.StartNew<uint?> (() => 1) is uint;
555                 return r;
556         }
557         
558         async Task<bool> LogicalUserOperator_1 ()
559         {
560                 var r = await Task.Factory.StartNew (() => new Base ()) && await Task.Factory.StartNew (() => new Base ());
561                 return r.field_int == 100;
562         }
563         
564         async Task<bool> LogicalUserOperator_2 ()
565         {
566                 var r = new Base () && await Task.Factory.StartNew (() => new Base ());
567                 return r.field_int == 100;
568         }
569         
570         async Task<bool> LogicalUserOperator_3 ()
571         {
572                 var r = await Task.Factory.StartNew (() => new Base ()) || await Task.Factory.StartNew (() => new Base ());
573                 return r.field_int == 0;
574         }
575
576         async Task<bool> NewTest_1 ()
577         {
578                 int value = 9;
579                 var b = new Base (value, await Task.Factory.StartNew (() => 33));
580                 return b.field_int == 9;
581         }
582         
583         async Task<bool> NewTest_2 ()
584         {
585                 var s = new S (await Task.Factory.StartNew (() => 77), await Task.Factory.StartNew (() => "b"));
586                 return s.Value == 77;
587         }
588         
589         async Task<int> NewInitTest_1 ()
590         {
591                 int value = 9;
592                 
593                 var b = new Base (value, await Task.Factory.StartNew (() => 33)) { };
594                 if (b.field_int != 9)
595                         return 1;
596                 
597                 b = new Base (value, await Task.Factory.StartNew (() => 11)) {
598                         field_int = await Task.Factory.StartNew (() => 12),
599                         PropertyInt = await Task.Factory.StartNew (() => 13)
600                 };
601                 
602                 if (b.field_int != 25)
603                         return 2;
604                 
605                 b = new Base () {
606                         field_int = await Task.Factory.StartNew (() => 12),
607                         PropertyInt = await Task.Factory.StartNew (() => 13)
608                 };
609
610                 if (b.field_int != 25)
611                         return 3;
612                 
613                 return 0;
614         }
615         
616         async Task<int> NewInitTest_2 ()
617         {
618                 int value = 9;
619                 
620                 var s = new S (value, await Task.Factory.StartNew (() => "x")) { };
621                 if (s.Value != 9)
622                         return 1;
623                 
624                 s = new S (value, await Task.Factory.StartNew (() => "y")) {
625                         Value = await Task.Factory.StartNew (() => 12)
626                 };
627
628                 if (s.Value != 12)
629                         return 2;
630                 
631                 s = new S () {
632                         Value = await Task.Factory.StartNew (() => 13)
633                 };
634                 
635                 if (s.Value != 13)
636                         return 3;
637                 
638                 return 0;
639         }
640
641         async Task<bool> NewArrayInitTest_1 ()
642         {
643                 var a = new int[await Task.Factory.StartNew (() => 5)];
644                 return a.Length == 5;
645         }
646         
647         async Task<bool> NewArrayInitTest_2 ()
648         {
649                 var a = new short[await Task.Factory.StartNew (() => 3), await Task.Factory.StartNew (() => 4)];
650                 return a.Length == 12;
651         }
652         
653         async Task<int> NewArrayInitTest_3 ()
654         {
655                 var a = new byte[] { await Task.Factory.StartNew (() => (byte)5) };
656                 return a [0] - 5;
657         }
658         
659         async Task<bool> NewArrayInitTest_4 ()
660         {
661                 var a = new ushort[,] {
662                         { await Task.Factory.StartNew (() => (ushort) 5), 50 },
663                         { 30, await Task.Factory.StartNew (() => (ushort) 3) }
664                 };
665                 
666                 return a [0, 0] * a [1, 1] == 15;
667         }
668         
669         async Task<int> NewArrayInitTest_5 ()
670         {
671                 var a = new S[] { await Task.Factory.StartNew (() => new S () { Value = 4 }) };
672                 return a [0].Value - 4;
673         }
674         
675         async Task<bool> NewArrayInitTest_6 ()
676         {
677                 var a = new int[] { 2, 3, 2, 3, 5, 6, 7, 2, 4, await Task.Factory.StartNew (() => 5), 11, 23, 45 };
678                 return a.Length == 13;
679         }
680         
681         async Task<bool> PropertyTest_1 ()
682         {
683                 PropertyInt = await Task.Factory.StartNew (() => 6);
684                 return PropertyInt == 6;
685         }
686         
687         async Task<int> PropertyTest_2 ()
688         {
689                 PropertyThis.PropertyInt += await Task.Factory.StartNew (() => 6);
690                 if (property_this_counter != 1)
691                         return 1;
692                 
693                 return PropertyInt - 6;
694         }
695         
696         async Task<int> PropertyTest_3 ()
697         {
698                 var r = PropertyThis.PropertyInt = await Task.Factory.StartNew (() => 9);
699                 if (r != 9)
700                         return 1;
701                 
702                 PropertyThis.PropertyInt = 4;
703                 int[] a = new int[4];
704                 a [await Task.Factory.StartNew (() => 1)] = PropertyThis.PropertyInt += await Task.Factory.StartNew (() => 8);
705                 if (a[1] != 21)
706                         return 2;
707                 
708                 if (PropertyThis.PropertyInt != 34)
709                         return 3;
710                 
711                 return 0;
712         }
713         
714         async Task<bool> StringConcatTest_1 ()
715         {
716                 return (await Task.Factory.StartNew (() => "a") +
717                         await Task.Factory.StartNew (() => "b") +
718                         await Task.Factory.StartNew (() => (string) null) == "ab");
719         }
720
721         async Task<bool> UnaryTest_1 ()
722         {
723                 long a = 1;
724                 return (a + checked (-await Task.Factory.StartNew (() => 2))) == -1;
725         }
726
727         async Task<bool> UnaryTest_2 ()
728         {
729                 short? s = 2;
730                 int value = 2;
731                 return (value * ~await Task.Factory.StartNew (() => s)) == -6;
732         }
733
734         async Task<bool> UnaryTest_3 ()
735         {
736                 var d = new decimal? [2];
737                 d[1] = 4;
738                 var r = ++d[await Task.Factory.StartNew (() => 1)];
739                 return r == 5;
740         }
741         
742         async Task<bool> VariableInitializer_1 ()
743         {
744                 int a = 2, b = await Task.Factory.StartNew (() => 1), c = await Task.Factory.StartNew (() => 1);
745                 return a == (b + c);
746         }
747
748         static bool RunTest (MethodInfo test)
749         {
750                 Console.Write ("Running test {0, -25}", test.Name);
751                 try {
752                         Task t = test.Invoke (new Tester (), null) as Task;
753                         if (!Task.WaitAll (new[] { t }, 1000)) {
754                                 Console.WriteLine ("FAILED (Timeout)");
755                                 return false;
756                         }
757
758                         var ti = t as Task<int>;
759                         if (ti != null) {
760                                 if (ti.Result != 0) {
761                                         Console.WriteLine ("FAILED (Result={0})", ti.Result);
762                                         return false;
763                                 }
764                         } else {
765                                 var tb = t as Task<bool>;
766                                 if (tb != null) {
767                                         if (!tb.Result) {
768                                                 Console.WriteLine ("FAILED (Result={0})", tb.Result);
769                                                 return false;
770                                         }
771                                 }
772                         }
773
774                         Console.WriteLine ("OK");
775                         return true;
776                 } catch (Exception e) {
777                         Console.WriteLine ("FAILED");
778                         Console.WriteLine (e.ToString ());
779                         return false;
780                 }
781         }
782
783         public static int Main ()
784         {
785                 var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
786                                         where test.GetParameters ().Length == 0 && !test.IsDefined (typeof (CompilerGeneratedAttribute), false)
787                                         orderby test.Name
788                                         select RunTest (test);
789
790                 int failures = tests.Count (a => !a);
791                 Console.WriteLine (failures + " tests failed");
792                 return failures;
793         }
794 }