Merge pull request #799 from kebby/master
[mono.git] / mcs / class / corlib / Test / System.Runtime.CompilerServices / YieldAwaitableTest.cs
1 //
2 // YieldAwaitebleTest.cs
3 //
4 // Authors:
5 //      Marek Safar  <marek.safar@gmail.com>
6 //
7 // Copyright (C) 2011 Xamarin, Inc (http://www.xamarin.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 #if NET_4_5
30
31 using System;
32 using System.Collections.Generic;
33 using NUnit.Framework;
34 using System.Runtime.CompilerServices;
35 using System.Threading.Tasks;
36 using System.Threading;
37
38 namespace MonoTests.System.Runtime.CompilerServices
39 {
40         [TestFixture]
41         public class YieldAwaitableTest
42         {
43                 class MyScheduler : TaskScheduler
44                 {
45                         protected override IEnumerable<Task> GetScheduledTasks ()
46                         {
47                                 throw new NotImplementedException ();
48                         }
49
50                         protected override void QueueTask (Task task)
51                         {
52                                 TryExecuteTask (task);
53                         }
54
55                         protected override bool TryExecuteTaskInline (Task task, bool taskWasPreviouslyQueued)
56                         {
57                                 throw new NotImplementedException ();
58                         }
59                 }
60
61                 class MyContext : SynchronizationContext
62                 {
63                         public int Started;
64                         public int Completed;
65                         public int PostCounter;
66                         public int SendCounter;
67
68                         public override void OperationStarted ()
69                         {
70                                 ++Started;
71                                 base.OperationStarted ();
72                         }
73
74                         public override void OperationCompleted ()
75                         {
76                                 ++Completed;
77                                 base.OperationCompleted ();
78                         }
79
80                         public override void Post (SendOrPostCallback d, object state)
81                         {
82                                 ++PostCounter;
83                                 base.Post (d, state);
84                         }
85
86                         public override void Send (SendOrPostCallback d, object state)
87                         {
88                                 ++SendCounter;
89                                 base.Send (d, state);
90                         }
91                 }
92
93                 YieldAwaitable.YieldAwaiter a;
94                 SynchronizationContext sc;
95
96                 [SetUp]
97                 public void Setup ()
98                 {
99                         sc = SynchronizationContext.Current;
100                         a = new YieldAwaitable ().GetAwaiter ();
101                 }
102
103                 [TearDown]
104                 public void TearDown ()
105                 {
106                         SynchronizationContext.SetSynchronizationContext (sc);
107                 }
108
109                 [Test]
110                 public void IsCompleted ()
111                 {
112                         Assert.IsFalse (a.IsCompleted, "#1");
113                         a.GetResult ();
114                         Assert.IsFalse (a.IsCompleted, "#1");
115                 }
116
117                 [Test]
118                 public void OnCompleted_1 ()
119                 {
120                         try {
121                                 a.OnCompleted (null);
122                                 Assert.Fail ("#1");
123                         } catch (ArgumentException) {
124                         }
125                 }
126
127                 [Test]
128                 public void OnCompleted_2 ()
129                 {
130                         TaskScheduler scheduler = null;
131                         SynchronizationContext.SetSynchronizationContext (null);
132
133                         var mre = new ManualResetEvent (false);
134
135                         a.OnCompleted (() => {
136                                 scheduler = TaskScheduler.Current;
137                                 mre.Set ();
138                         });
139
140                         Assert.IsTrue (mre.WaitOne (1000), "#1");
141                         Assert.AreEqual (TaskScheduler.Current, scheduler, "#2");
142                 }
143
144                 [Test]
145                 public void OnCompleted_3 ()
146                 {
147                         var scheduler = new MyScheduler ();
148                         TaskScheduler ran_scheduler = null;
149                         SynchronizationContext.SetSynchronizationContext (null);                        
150
151                         var t = Task.Factory.StartNew (() => {
152                                 var mre = new ManualResetEvent (false);
153
154                                 a.OnCompleted (() => {
155                                         ran_scheduler = TaskScheduler.Current;
156                                         mre.Set ();
157                                 });
158
159                                 mre.WaitOne (1000);
160
161                         }, CancellationToken.None, TaskCreationOptions.None, scheduler);
162
163                         Assert.IsTrue (t.Wait (1000), "#1");
164                         Assert.AreEqual (scheduler, ran_scheduler, "#2");
165                 }
166
167                 [Test]
168                 public void OnCompleted_4 ()
169                 {
170                         SynchronizationContext context_ran = null;
171                         var mre = new ManualResetEvent (false);
172
173                         var context = new MyContext ();
174                         SynchronizationContext.SetSynchronizationContext (context);
175                         a.OnCompleted (() => {
176                                 context_ran = SynchronizationContext.Current;
177                                 mre.Set ();
178                         });
179
180                         Assert.IsTrue (mre.WaitOne (1000), "#1");
181                         Assert.IsNull (context_ran, "#2");
182                 }
183         }
184 }
185
186 #endif