[resgen] Implement conditional resources (#if/#ifdef)
[mono.git] / mcs / class / corlib / Test / System.Threading.Tasks / TaskCompletionSourceTests.cs
1 // 
2 // TaskCompletionSourceTests.cs
3 //  
4 // Author:
5 //       Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
6 // 
7 // Copyright (c) 2009 Jérémie "Garuma" Laval
8 // 
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 // 
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 // 
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // THE SOFTWARE.
26
27 #if NET_4_0
28
29 using System;
30 using System.Threading;
31 using System.Threading.Tasks;
32
33 using NUnit.Framework;
34 #if !MOBILE
35 using NUnit.Framework.SyntaxHelpers;
36 #endif
37
38 namespace MonoTests.System.Threading.Tasks
39 {
40         [TestFixture]
41         public class TaskCompletionSourceTests
42         {
43                 TaskCompletionSource<int> completionSource;
44                 object state;
45                 
46                 [SetUp]
47                 public void Setup ()
48                 {
49                         state = new object ();
50                         completionSource = new TaskCompletionSource<int> (state, TaskCreationOptions.None);
51                 }
52                 
53                 [Test]
54                 public void CreationCheckTest ()
55                 {
56                         Assert.IsNotNull (completionSource.Task, "#1");
57                         Assert.AreEqual (TaskCreationOptions.None, completionSource.Task.CreationOptions, "#2");
58                 }
59
60                 [Test]
61                 public void CtorInvalidOptions ()
62                 {
63                         try {
64                                 new TaskCompletionSource<long> (TaskCreationOptions.LongRunning);
65                                 Assert.Fail ("#1");
66                         } catch (ArgumentOutOfRangeException) {
67                         }
68
69                         try {
70                                 new TaskCompletionSource<long> (TaskCreationOptions.PreferFairness);
71                                 Assert.Fail ("#2");
72                         } catch (ArgumentOutOfRangeException) {
73                         }
74                 }
75                 
76                 [Test]
77                 public void SetResultTest ()
78                 {
79                         Assert.IsNotNull (completionSource.Task, "#1");
80                         Assert.IsTrue (completionSource.TrySetResult (42), "#2");
81                         Assert.AreEqual (TaskStatus.RanToCompletion, completionSource.Task.Status, "#3");
82                         Assert.AreEqual (42, completionSource.Task.Result, "#4");
83                         Assert.IsFalse (completionSource.TrySetResult (43), "#5");
84                         Assert.AreEqual (TaskStatus.RanToCompletion, completionSource.Task.Status, "#6");
85                         Assert.AreEqual (42, completionSource.Task.Result, "#7");
86                         Assert.IsFalse (completionSource.TrySetCanceled (), "#8");
87                         Assert.AreEqual (TaskStatus.RanToCompletion, completionSource.Task.Status, "#9");
88                 }
89                 
90                 [Test]
91                 public void SetCanceledTest ()
92                 {
93                         Assert.IsNotNull (completionSource.Task, "#1");
94                         Assert.IsTrue (completionSource.TrySetCanceled (), "#2");
95                         Assert.AreEqual (TaskStatus.Canceled, completionSource.Task.Status, "#3");
96                         Assert.IsFalse (completionSource.TrySetResult (42), "#4");
97                         Assert.AreEqual (TaskStatus.Canceled, completionSource.Task.Status, "#5");
98
99                         try {
100                                 Console.WriteLine (completionSource.Task.Result);
101                                 Assert.Fail ("#6");
102                         } catch (AggregateException e) {
103                                 var details = (TaskCanceledException) e.InnerException;
104                                 Assert.AreEqual (completionSource.Task, details.Task, "#6e");
105                                 Assert.IsNull (details.Task.Exception, "#6e2");
106                         }
107                 }
108
109                 [Test]
110                 public void SetExceptionTest ()
111                 {
112                         Exception e = new Exception ("foo");
113                         
114                         Assert.IsNotNull (completionSource.Task, "#1");
115                         Assert.IsTrue (completionSource.TrySetException (e), "#2");
116                         Assert.AreEqual (TaskStatus.Faulted, completionSource.Task.Status, "#3");
117                         Assert.That (completionSource.Task.Exception, Is.TypeOf(typeof (AggregateException)), "#4.1");
118                         
119                         AggregateException aggr = (AggregateException)completionSource.Task.Exception;
120                         Assert.AreEqual (1, aggr.InnerExceptions.Count, "#4.2");
121                         Assert.AreEqual (e, aggr.InnerExceptions[0], "#4.3");
122                         
123                         Assert.IsFalse (completionSource.TrySetResult (42), "#5");
124                         Assert.AreEqual (TaskStatus.Faulted, completionSource.Task.Status, "#6");
125                         Assert.IsFalse (completionSource.TrySetCanceled (), "#8");
126                         Assert.AreEqual (TaskStatus.Faulted, completionSource.Task.Status, "#9");
127                 }
128
129                 [Test]
130                 public void SetExceptionInvalid ()
131                 {
132                         try {
133                                 completionSource.TrySetException (new ApplicationException[0]);
134                                 Assert.Fail ("#1");
135                         } catch (ArgumentException) {
136                         }
137
138                         try {
139                                 completionSource.TrySetException (new [] { new ApplicationException (), null });
140                                 Assert.Fail ("#2");
141                         } catch (ArgumentException) {
142                         }
143
144                         Assert.AreEqual (TaskStatus.WaitingForActivation, completionSource.Task.Status, "r1");
145                 }
146                 
147                 [Test, ExpectedException (typeof (InvalidOperationException))]
148                 public void SetResultExceptionTest ()
149                 {
150                         Assert.IsNotNull (completionSource.Task, "#1");
151                         Assert.IsTrue (completionSource.TrySetResult (42), "#2");
152                         Assert.AreEqual (TaskStatus.RanToCompletion, completionSource.Task.Status, "#3");
153                         Assert.AreEqual (42, completionSource.Task.Result, "#4");
154                         
155                         completionSource.SetResult (43);
156                 }
157
158                 [Test]
159                 public void ContinuationTest ()
160                 {
161                         bool result = false;
162                         var t = completionSource.Task.ContinueWith ((p) => { if (p.Result == 2) result = true; });
163                         Assert.AreEqual (TaskStatus.WaitingForActivation, completionSource.Task.Status, "#A");
164                         completionSource.SetResult (2);
165                         t.Wait ();
166                         Assert.AreEqual (TaskStatus.RanToCompletion, completionSource.Task.Status, "#1");
167                         Assert.AreEqual (TaskStatus.RanToCompletion, t.Status, "#2");
168                         Assert.IsTrue (result);
169                 }
170
171                 [Test]
172                 public void FaultedFutureTest ()
173                 {
174                         var thrown = new ApplicationException ();
175                         var source = new TaskCompletionSource<int> ();
176                         source.TrySetException (thrown);
177                         var f = source.Task;
178                         AggregateException ex = null;
179                         try {
180                                 f.Wait ();
181                         } catch (AggregateException e) {
182                                 ex = e;
183                         }
184
185                         Assert.IsNotNull (ex);
186                         Assert.AreEqual (thrown, ex.InnerException);
187                         Assert.AreEqual (thrown, f.Exception.InnerException);
188                         Assert.AreEqual (TaskStatus.Faulted, f.Status);
189
190                         ex = null;
191                         try {
192                                 var result = f.Result;
193                         } catch (AggregateException e) {
194                                 ex = e;
195                         }
196
197                         Assert.IsNotNull (ex);
198                         Assert.AreEqual (TaskStatus.Faulted, f.Status);
199                         Assert.AreEqual (thrown, f.Exception.InnerException);
200                         Assert.AreEqual (thrown, ex.InnerException);
201                 }
202
203                 [Test]
204                 [Ignore ("#4550, Mono GC is lame")]
205                 public void SetExceptionAndUnobservedEvent ()
206                 {
207                         bool notFromMainThread = false;
208                         var mre = new ManualResetEvent (false);
209                         int mainThreadId = Thread.CurrentThread.ManagedThreadId;
210                         TaskScheduler.UnobservedTaskException += (o, args) => {
211                                 notFromMainThread = Thread.CurrentThread.ManagedThreadId != mainThreadId;
212                                 args.SetObserved ();
213                                 mre.Set ();
214                         };
215                         var inner = new ApplicationException ();
216                         CreateFaultedTaskCompletionSource (inner);
217                         GC.Collect ();
218                         GC.WaitForPendingFinalizers ();
219
220                         Assert.IsTrue (mre.WaitOne (5000), "#1");
221                         Assert.IsTrue (notFromMainThread, "#2");
222                 }
223
224                 void CreateFaultedTaskCompletionSource (Exception inner)
225                 {
226                         var tcs = new TaskCompletionSource<int> ();
227                         tcs.SetException (inner);
228                         tcs = null;
229                 }
230
231                 [Test]
232                 public void WaitingTest ()
233                 {
234                         var tcs = new TaskCompletionSource<int> ();
235                         var task = tcs.Task;
236                         bool result = task.Wait (50);
237
238                         Assert.IsFalse (result);
239                 }
240         }
241 }
242 #endif