Implemented overloaded versions of Parse and TryParse functions for BigInteger.
[mono.git] / mcs / class / corlib / Test / System.Threading.Tasks / TaskFactoryTest.cs
1 //
2 // TaskFactoryTest.cs
3 //
4 // Authors:
5 //       Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
6 //       Marek Safar <marek.safar@gmail.com>
7 // 
8 // Copyright (c) 2010 Jérémie "Garuma" Laval
9 // Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28 //
29 //
30
31 #if NET_4_0
32
33 using System;
34 using System.Threading;
35 using System.Threading.Tasks;
36 using System.Collections.Generic;
37
38 using NUnit.Framework;
39 #if !MOBILE
40 using NUnit.Framework.SyntaxHelpers;
41 #endif
42
43 namespace MonoTests.System.Threading.Tasks
44 {
45         [TestFixture]
46         public class TaskFactoryTests
47         {
48                 class CompletedAsyncResult : IAsyncResult
49                 {
50                         public object AsyncState
51                         {
52                                 get { throw new NotImplementedException (); }
53                         }
54
55                         public WaitHandle AsyncWaitHandle
56                         {
57                                 get { throw new NotImplementedException (); }
58                         }
59
60                         public bool CompletedSynchronously
61                         {
62                                 get { throw new NotImplementedException (); }
63                         }
64
65                         public bool IsCompleted
66                         {
67                                 get { return true; }
68                         }
69                 }
70
71                 class TestAsyncResult : IAsyncResult
72                 {
73                         WaitHandle wh = new ManualResetEvent (true);
74
75                         public object AsyncState
76                         {
77                                 get { throw new NotImplementedException (); }
78                         }
79
80                         public WaitHandle AsyncWaitHandle
81                         {
82                                 get
83                                 {
84                                         return wh;
85                                 }
86                         }
87
88                         public bool CompletedSynchronously
89                         {
90                                 get { throw new NotImplementedException (); }
91                         }
92
93                         public bool IsCompleted
94                         {
95                                 get { return false; }
96                         }
97                 }
98
99                 class TestScheduler : TaskScheduler
100                 {
101                         public bool ExecutedInline { get; set; }
102
103                         protected override void QueueTask (Task task)
104                         {
105                                 throw new NotImplementedException ();
106                         }
107
108                         protected override bool TryDequeue (Task task)
109                         {
110                                 throw new NotImplementedException ();
111                         }
112
113                         protected override bool TryExecuteTaskInline (Task task, bool taskWasPreviouslyQueued)
114                         {
115                                 if (taskWasPreviouslyQueued)
116                                         throw new ArgumentException ("taskWasPreviouslyQueued");
117
118                                 if (task.Status != TaskStatus.WaitingToRun)
119                                         throw new ArgumentException ("task.Status");
120
121                                 ExecutedInline = true;
122                                 return TryExecuteTask (task);
123                         }
124
125                         protected override IEnumerable<Task> GetScheduledTasks ()
126                         {
127                                 throw new NotImplementedException ();
128                         }
129                 }
130
131
132                 TaskFactory factory;
133
134                 [SetUp]
135                 public void Setup ()
136                 {
137                         this.factory = Task.Factory;
138                 }
139
140                 [Test]
141                 public void StartNewTest ()
142                 {
143                         bool result = false;
144                         factory.StartNew (() => result = true).Wait ();
145                         Assert.IsTrue (result);
146                 }
147
148                 [Test]
149                 public void NoDefaultScheduler ()
150                 {
151                         Assert.IsNull (factory.Scheduler, "#1");
152                 }
153
154                 [Test]
155                 public void ContinueWhenAll_Simple ()
156                 {
157                         var mre = new ManualResetEventSlim (false);
158
159                         Task[] tasks = new Task[3];
160                         tasks[0] = new Task (() => { Thread.Sleep (0); Assert.IsTrue (mre.Wait (3000)); });
161                         tasks[1] = new Task (() => { Assert.IsTrue (mre.Wait (3000)); });
162                         tasks[2] = new Task (() => { Assert.IsTrue (mre.Wait (3000)); });
163
164                         bool ran = false;
165                         Task cont = factory.ContinueWhenAll (tasks, ts => {
166                                 Assert.AreEqual (tasks, ts, "#0");
167                                 ran = true;
168                         });
169
170                         foreach (Task t in tasks)
171                                 t.Start ();
172
173                         mre.Set ();
174
175                         Assert.IsTrue (cont.Wait (1000), "#1");
176                         Assert.IsTrue (ran, "#2");
177                 }
178
179                 [Test]
180                 public void ContinueWhenAll_WithMixedCompletionState ()
181                 {
182                         var mre = new ManualResetEventSlim ();
183                         var task = Task.Factory.StartNew (() => mre.Wait (200));
184                         var contFailed = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnFaulted);
185                         var contCanceled = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnCanceled);
186                         var contSuccess = task.ContinueWith (t => {}, TaskContinuationOptions.OnlyOnRanToCompletion);
187                         bool ran = false;
188
189                         var cont = Task.Factory.ContinueWhenAll (new Task[] { contFailed, contCanceled, contSuccess }, _ => ran = true);
190
191                         mre.Set ();
192                         cont.Wait (200);
193
194                         Assert.IsTrue (ran);
195                         Assert.AreEqual (TaskStatus.RanToCompletion, cont.Status);
196                 }
197
198                 [Test]
199                 public void ContinueWhenAll_InvalidArguments ()
200                 {
201                         try {
202                                 factory.ContinueWhenAll (null, delegate { });
203                                 Assert.Fail ("#1");
204                         } catch (ArgumentNullException) {
205                         }
206
207                         try {
208                                 factory.ContinueWhenAll (new Task[0], delegate { });
209                                 Assert.Fail ("#2");
210                         } catch (ArgumentException) {
211                         }
212
213                         try {
214                                 factory.ContinueWhenAll (new Task[] { null }, delegate { });
215                                 Assert.Fail ("#3");
216                         } catch (ArgumentException) {
217                         }
218
219                         var tasks = new Task [] {
220                                 factory.StartNew (delegate {})
221                         };
222
223                         try {
224                                 factory.ContinueWhenAll (tasks, null);
225                                 Assert.Fail ("#4");
226                         } catch (ArgumentException) {
227                         }
228
229                         try {
230                                 factory.ContinueWhenAll (tasks, delegate { }, CancellationToken.None, TaskContinuationOptions.None, null);
231                                 Assert.Fail ("#5");
232                         } catch (ArgumentException) {
233                         }
234
235                         try {
236                                 factory.ContinueWhenAll (tasks, delegate { }, CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, null);
237                                 Assert.Fail ("#6");
238                         } catch (ArgumentException) {
239                         }
240                 }
241
242                 [Test]
243                 public void ContinueWhenAll_WithExceptions ()
244                 {
245                         var t1 = Task.Factory.StartNew (() => { throw new ApplicationException ("Foo"); });
246                         var t2 = Task.Factory.StartNew (() => { throw new ApplicationException ("Bar"); });
247
248                         var cont = Task.Factory.ContinueWhenAll (new[] { t1, t2 }, delegate {});
249                         cont.Wait (200);
250
251                         Assert.IsTrue (t1.IsFaulted);
252                         Assert.IsTrue (t2.IsFaulted);
253                         Assert.AreEqual (TaskStatus.RanToCompletion, cont.Status);
254                 }
255
256                 [Test]
257                 public void ContinueWhenAny_Simple ()
258                 {
259                         var t1 = new ManualResetEvent (false);
260                         var t2 = new ManualResetEvent (false);
261
262                         var tasks = new Task[2] {
263                                 Task.Factory.StartNew (() => { t1.WaitOne (3000); }),
264                                 Task.Factory.StartNew (() => { t2.WaitOne (3000); })
265                         };
266
267                         bool ran = false;
268                         var ct = new CancellationToken ();
269                         Task cont = factory.ContinueWhenAny (tasks, t => {
270                                 Assert.AreEqual (tasks[0], t, "#1");
271                                 ran = true;
272                         }, ct);
273
274                         Assert.AreEqual (TaskStatus.WaitingForActivation, cont.Status, "#2");
275
276                         t1.Set ();
277
278                         Assert.IsTrue (cont.Wait (2000), "#10");
279                         Assert.IsTrue (ran, "#11");
280
281                         t2.Set ();
282                 }
283
284                 [Test]
285                 public void ContinueWhenAny_WithResult ()
286                 {
287                         var tcs = new TaskCompletionSource<int>();
288                         tcs.SetResult(1);
289                         Task[] tasks = new[] { tcs.Task };
290                         var res = Task.Factory.ContinueWhenAny (tasks, l => 4);
291                         Assert.AreEqual (4, res.Result);
292                 }
293
294                 [Test]
295                 public void ContinueWhenAny_InvalidArguments ()
296                 {
297                         try {
298                                 factory.ContinueWhenAny (null, delegate { });
299                                 Assert.Fail ("#1");
300                         } catch (ArgumentNullException) {
301                         }
302
303                         try {
304                                 factory.ContinueWhenAny (new Task[0], delegate { });
305                                 Assert.Fail ("#2");
306                         } catch (ArgumentException) {
307                         }
308
309                         try {
310                                 factory.ContinueWhenAny (new Task[] { null }, delegate { });
311                                 Assert.Fail ("#3");
312                         } catch (ArgumentException) {
313                         }
314
315                         var tasks = new Task [] {
316                                 factory.StartNew (delegate {})
317                         };
318
319                         try {
320                                 factory.ContinueWhenAny (tasks, null);
321                                 Assert.Fail ("#4");
322                         } catch (ArgumentException) {
323                         }
324
325                         try {
326                                 factory.ContinueWhenAny (tasks, delegate { }, CancellationToken.None, TaskContinuationOptions.None, null);
327                                 Assert.Fail ("#5");
328                         } catch (ArgumentException) {
329                         }
330
331                         try {
332                                 factory.ContinueWhenAny (tasks, delegate { }, CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, null);
333                                 Assert.Fail ("#6");
334                         } catch (ArgumentException) {
335                         }
336                 }
337
338                 [Test]
339                 public void FromAsyncBeginInvoke_WithResult ()
340                 {
341                         bool result = false;
342
343                         Func<int, int> func = (i) => {
344                                 Assert.IsTrue (Thread.CurrentThread.IsThreadPoolThread);
345                                 result = true; return i + 3;
346                         };
347
348                         var task = factory.FromAsync<int, int> (func.BeginInvoke, func.EndInvoke, 1, "state", TaskCreationOptions.AttachedToParent);
349                         Assert.IsTrue (task.Wait (5000), "#1");
350                         Assert.IsTrue (result, "#2");
351                         Assert.AreEqual (4, task.Result, "#3");
352                         Assert.AreEqual ("state", (string) task.AsyncState, "#4");
353                         Assert.AreEqual (TaskCreationOptions.AttachedToParent, task.CreationOptions, "#5");
354                 }
355
356                 [Test]
357                 public void FromAsyncBeginMethod_DirectResult ()
358                 {
359                         bool result = false;
360                         bool continuationTest = false;
361
362                         Func<int, int> func = (i) => { result = true; return i + 3; };
363                         Task<int> task = factory.FromAsync<int> (func.BeginInvoke (1, delegate { }, null), func.EndInvoke);
364                         var cont = task.ContinueWith (_ => continuationTest = true, TaskContinuationOptions.ExecuteSynchronously);
365                         task.Wait ();
366                         cont.Wait ();
367
368                         Assert.IsTrue (result);
369                         Assert.IsTrue (continuationTest);
370                         Assert.AreEqual (4, task.Result);
371                 }
372
373                 [Test]
374                 public void FromAsyncBeginMethod_Exception ()
375                 {
376                         bool result = false;
377                         bool continuationTest = false;
378
379                         Func<int, int> func = (i) => { result = true; throw new ApplicationException ("bleh"); };
380                         Task<int> task = factory.FromAsync<int, int> (func.BeginInvoke, func.EndInvoke, 1, null);
381                         var cont = task.ContinueWith (_ => continuationTest = true, TaskContinuationOptions.ExecuteSynchronously);
382                         try {
383                                 task.Wait (2000);
384                         } catch { }
385                         Assert.IsTrue (cont.Wait (2000), "#1");
386
387                         Assert.IsTrue (result);
388                         Assert.IsTrue (continuationTest);
389                         Assert.IsNotNull (task.Exception);
390                         var agg = task.Exception;
391                         Assert.AreEqual (1, agg.InnerExceptions.Count);
392                         Assert.That (agg.InnerExceptions[0], Is.TypeOf (typeof (ApplicationException)));
393                         Assert.AreEqual (TaskStatus.Faulted, task.Status);
394
395                         try {
396                                 var a = task.Result;
397                                 Assert.Fail ();
398                         } catch (AggregateException) {
399                         }
400                 }
401
402                 [Test]
403                 public void FromAsync_ArgumentsCheck ()
404                 {
405                         var result = new CompletedAsyncResult ();
406                         try {
407                                 factory.FromAsync (null, l => { });
408                                 Assert.Fail ("#1");
409                         } catch (ArgumentNullException) {
410                         }
411
412                         try {
413                                 factory.FromAsync (result, null);
414                                 Assert.Fail ("#2");
415                         } catch (ArgumentNullException) {
416                         }
417
418                         try {
419                                 factory.FromAsync (result, l => { }, TaskCreationOptions.LongRunning);
420                                 Assert.Fail ("#3");
421                         } catch (ArgumentOutOfRangeException) {
422                         }
423
424                         try {
425                                 factory.FromAsync (result, l => { }, TaskCreationOptions.PreferFairness);
426                                 Assert.Fail ("#4");
427                         } catch (ArgumentOutOfRangeException) {
428                         }
429
430                         try {
431                                 factory.FromAsync (result, l => { }, TaskCreationOptions.None, null);
432                                 Assert.Fail ("#5");
433                         } catch (ArgumentNullException) {
434                         }
435
436                         try {
437                                 factory.FromAsync (null, l => { }, null, TaskCreationOptions.None);
438                                 Assert.Fail ("#6");
439                         } catch (ArgumentNullException) {
440                         }
441
442                         try {
443                                 factory.FromAsync ((a, b) => null, l => { }, null, TaskCreationOptions.LongRunning);
444                                 Assert.Fail ("#7");
445                         } catch (ArgumentOutOfRangeException) {
446                         }
447                 }
448
449                 [Test]
450                 public void FromAsync_Completed ()
451                 {
452                         var completed = new CompletedAsyncResult ();
453                         bool? valid = null;
454
455                         Action<IAsyncResult> end = l => {
456                                 Assert.IsFalse (Thread.CurrentThread.IsThreadPoolThread, "#2");
457                                 valid = l == completed;
458                         };
459                         Task task = factory.FromAsync (completed, end);
460                         Assert.IsTrue (valid == true, "#1");
461                 }
462
463                 [Test]
464                 public void FromAsync_CompletedWithException ()
465                 {
466                         var completed = new CompletedAsyncResult ();
467
468                         Action<IAsyncResult> end = l => {
469                                 throw new ApplicationException ();
470                         };
471                         Task task = factory.FromAsync (completed, end);
472                         Assert.AreEqual (TaskStatus.Faulted, task.Status, "#1");
473                 }
474
475                 [Test]
476                 public void FromAsync_CompletedCanceled ()
477                 {
478                         var completed = new CompletedAsyncResult ();
479
480                         Action<IAsyncResult> end = l => {
481                                 throw new OperationCanceledException ();
482                         };
483                         Task task = factory.FromAsync (completed, end);
484                         Assert.AreEqual (TaskStatus.Canceled, task.Status, "#1");
485                         Assert.IsNull (task.Exception, "#2");
486                 }
487
488                 [Test]
489                 public void FromAsync_SimpleAsyncResult ()
490                 {
491                         var result = new TestAsyncResult ();
492                         bool called = false;
493
494                         var task = factory.FromAsync (result, l => {
495                                 called = true;
496                         });
497
498                         Assert.IsTrue (task.Wait (1000), "#1");
499                         Assert.IsTrue (called, "#2");
500                 }
501
502                 [Test]
503                 public void FromAsync_ResultException ()
504                 {
505                         var result = new TestAsyncResult ();
506
507                         var task = factory.FromAsync (result, l => {
508                                 throw new ApplicationException ();
509                         });
510
511                         try {
512                                 Assert.IsFalse (task.Wait (1000), "#1");
513                         } catch (AggregateException) {
514                         }
515
516                         Assert.AreEqual (TaskStatus.Faulted, task.Status, "#2");
517                 }
518
519                 [Test]
520                 public void FromAsync_ReturnInt ()
521                 {
522                         var result = new TestAsyncResult ();
523                         bool called = false;
524
525                         var task = factory.FromAsync<int> (result, l => {
526                                 called = true;
527                                 return 4;
528                         });
529
530                         Assert.IsTrue (task.Wait (1000), "#1");
531                         Assert.IsTrue (called, "#2");
532                         Assert.AreEqual (4, task.Result, "#3");
533                 }
534
535                 [Test]
536                 public void FromAsync_Scheduler_Explicit ()
537                 {
538                         var result = new TestAsyncResult ();
539                         bool called = false;
540                         var scheduler = new TestScheduler ();
541
542                         var task = factory.FromAsync (result, l => {
543                                 called = true;
544                         }, TaskCreationOptions.None, scheduler);
545
546                         Assert.IsTrue (task.Wait (5000), "#1");
547                         Assert.IsTrue (called, "#2");
548                         Assert.IsTrue (scheduler.ExecutedInline, "#3");
549                 }
550
551                 [Test]
552                 public void FromAsync_Scheduler_Implicit ()
553                 {
554                         var result = new TestAsyncResult ();
555                         bool called = false;
556                         var scheduler = new TestScheduler ();
557
558                         factory = new TaskFactory (scheduler);
559
560                         Task task = factory.FromAsync (result, l => {
561                                 Assert.IsTrue (Thread.CurrentThread.IsThreadPoolThread, "#6");
562                                 called = true;
563                         }, TaskCreationOptions.AttachedToParent);
564
565                         Assert.AreEqual (TaskCreationOptions.AttachedToParent, task.CreationOptions, "#1");
566                         Assert.IsNull (task.AsyncState, "#2");
567                         Assert.IsTrue (task.Wait (5000), "#3");
568                         Assert.IsTrue (called, "#4");
569                         Assert.IsTrue (scheduler.ExecutedInline, "#5");
570                 }
571
572                 [Test]
573                 public void FromAsync_BeginCallback ()
574                 {
575                         bool called = false;
576                         bool called2 = false;
577
578                         var task = factory.FromAsync (
579                                 (a, b, c) => {
580                                         if (a != "h")
581                                                 Assert.Fail ("#10");
582
583                                         if ((TaskCreationOptions) c != TaskCreationOptions.AttachedToParent)
584                                                 Assert.Fail ("#11");
585
586                                         Assert.IsFalse (Thread.CurrentThread.IsThreadPoolThread, "#12");
587
588                                         called2 = true;
589                                         b.Invoke (null);
590                                         return null;
591                                 },
592                                 l => {
593                                         called = true;
594                                 },
595                                 "h", TaskCreationOptions.AttachedToParent);
596
597                         Assert.AreEqual (TaskCreationOptions.None, task.CreationOptions, "#1");
598                         Assert.AreEqual (TaskCreationOptions.AttachedToParent, (TaskCreationOptions) task.AsyncState, "#2");
599                         Assert.IsTrue (task.Wait (5000), "#3");
600                         Assert.IsTrue (called, "#4");
601                         Assert.IsTrue (called2, "#5");
602                 }
603
604                 [Test]
605                 public void StartNewCancelled ()
606                 {
607                         var cts = new CancellationTokenSource ();
608                         cts.Cancel ();
609
610                         var task = factory.StartNew (() => Assert.Fail ("Should never be called"), cts.Token);
611                         try {
612                                 task.Start ();
613                         } catch (InvalidOperationException) {
614                         }
615
616                         Assert.IsTrue (task.IsCanceled, "#2");
617                 }
618         }
619 }
620 #endif