Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mcs / class / corlib / Test / System.Threading / ExecutionContextTest.cs
1 //
2 // ExecutionContextTest.cs - NUnit tests for ExecutionContext
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.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 using System.Runtime.Remoting.Messaging;
29
30
31 using System;
32 using System.Security;
33 using System.Threading;
34
35 using NUnit.Framework;
36
37 namespace MonoTests.System.Threading {
38
39         [TestFixture]
40         public class ExecutionContextTest {
41
42                 static bool success;
43
44                 static void Callback (object o)
45                 {
46                         success = (bool)o;
47                 }
48
49                 public class CallContextValue : ILogicalThreadAffinative {
50                         public object Value { get; set; }
51
52                         public CallContextValue (object value)
53                         {
54                                 this.Value = value;
55                         }
56                 }
57
58                 [SetUp]
59                 public void SetUp ()
60                 {
61                         success = false;
62                 }
63
64                 [TearDown]
65                 public void TearDown ()
66                 {
67                         if (ExecutionContext.IsFlowSuppressed ())
68                                 ExecutionContext.RestoreFlow ();
69
70                         CallContext.FreeNamedDataSlot ("testlc");
71                 }
72
73                 [Test]
74                 [Category("MobileNotWorking")]
75                 public void LogicalGetData_SetData()
76                 {
77                         var value = "a";
78
79                         CallContext.SetData ("testlc", value);
80                         var capturedValue = CallContext.LogicalGetData ("testlc");
81
82                         Assert.IsNull (capturedValue);
83                 }
84                 
85                 [Test]
86                 [Category("MobileNotWorking")]
87                 public void LogicalGetData_SetDataLogicalThreadAffinative()
88                 {
89                         var value = new CallContextValue ("a");
90
91                         CallContext.SetData ("testlc", value);
92                         var capturedValue = CallContext.LogicalGetData ("testlc");
93
94                         Assert.AreEqual (value, capturedValue);
95                 }
96
97                 [Test]
98                 [Category("MobileNotWorking")]
99                 public void GetData_SetLogicalData()
100                 {
101                         var value = "a";
102
103                         CallContext.LogicalSetData ("testlc", value);
104                         var capturedValue = CallContext.GetData ("testlc");
105
106                         Assert.AreEqual (value, capturedValue);
107                 }
108
109                 [Test]
110                 [Category("MobileNotWorking")]
111                 public void CaptureLogicalCallContext()
112                 {
113                         var value = "Tester";
114                         object capturedValue = null;
115
116                         CallContext.LogicalSetData ("testlc", value);
117
118                         ExecutionContext ec = ExecutionContext.Capture ();
119                         Assert.IsNotNull (ec, "Capture");
120                         Assert.AreEqual (value, CallContext.LogicalGetData ("testlc"));
121                         CallContext.LogicalSetData ("testlc", null);
122
123                         ExecutionContext.Run (ec, new ContextCallback (new Action<object> ((data) => {
124                                 capturedValue = CallContext.LogicalGetData ("testlc");
125                         })), null);
126
127                         Assert.AreEqual (value, capturedValue);
128                         Assert.AreNotEqual (value, CallContext.LogicalGetData ("testlc"));
129                 }
130
131                 [Test]
132                 [Category ("MobileNotWorking")]
133                 public void CaptureCallContext ()
134                 {
135                         var value = new CallContextValue (true);
136                         object capturedValue = null;
137
138                         CallContext.SetData ("testlc", value);
139
140                         ExecutionContext ec = ExecutionContext.Capture ();
141                         Assert.IsNotNull (ec, "Capture");
142                         Assert.AreEqual (value, CallContext.GetData ("testlc")); 
143                         CallContext.SetData ("testlc", null);
144
145                         ExecutionContext.Run (ec, new ContextCallback (new Action<object> ((data) => {
146                                 capturedValue = CallContext.GetData ("testlc");
147                         })), null);
148
149                         Assert.AreEqual (value, capturedValue); 
150                         Assert.AreNotEqual (value, CallContext.GetData ("testlc"));
151                 }
152
153                 [Test]
154                 [Category("MobileNotWorking")]
155                 public void Capture ()
156                 {
157                         ExecutionContext ec = ExecutionContext.Capture ();
158                         Assert.IsNotNull (ec, "Capture");
159
160                         AsyncFlowControl afc = ExecutionContext.SuppressFlow ();
161                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
162                         try {
163                                 ec = ExecutionContext.Capture ();
164                                 Assert.IsNull (ec, "Capture with SuppressFlow");
165                         }
166                         finally {
167                                 afc.Undo ();
168                         }
169                 }
170
171                 [Test]
172                 [Category("MobileNotWorking")]
173                 public void Copy ()
174                 {
175                         ExecutionContext ec = ExecutionContext.Capture ();
176                         Assert.IsNotNull (ec, "Capture");
177
178                         ExecutionContext copy = ec.CreateCopy ();
179                         Assert.IsNotNull (copy, "Copy of Capture");
180
181                         Assert.IsFalse (ec.Equals (copy));
182                         Assert.IsFalse (copy.Equals (ec));
183                         Assert.IsFalse (Object.ReferenceEquals (ec, copy));
184
185                         ExecutionContext copy2nd = copy.CreateCopy ();
186                         Assert.IsNotNull (copy2nd, "2nd level copy of Capture");
187                 }
188
189                 [Test]
190                 [ExpectedException (typeof (InvalidOperationException))]
191                 // The context might be the result of capture so no exception is thrown
192                 [Category ("NotWorking")]
193                 public void Copy_FromThread ()
194                 {
195                         ExecutionContext ec = Thread.CurrentThread.ExecutionContext;
196                         Assert.IsNotNull (ec, "Thread.CurrentThread.ExecutionContext");
197
198                         ExecutionContext copy = ec.CreateCopy ();
199                 }
200
201                 [Test]
202                 [Category("MobileNotWorking")]
203                 public void IsFlowSuppressed ()
204                 {
205                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
206
207                         AsyncFlowControl afc = ExecutionContext.SuppressFlow ();
208                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-2");
209                         afc.Undo ();
210
211                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-3");
212                 }
213
214                 [Test]
215                 [ExpectedException (typeof (InvalidOperationException))]
216                 [Category("MobileNotWorking")]
217                 public void RestoreFlow_None ()
218                 {
219                         ExecutionContext.RestoreFlow ();
220                 }
221
222                 [Test]
223                 [Category("MobileNotWorking")]
224                 public void RestoreFlow_SuppressFlow ()
225                 {
226                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
227                         ExecutionContext.SuppressFlow ();
228                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-2");
229                         ExecutionContext.RestoreFlow ();
230                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-3");
231                 }
232
233                 [Test]
234                 [Category ("CAS")] // since r60298 the SecurityContext is only captured if the security manager is active
235                 public void Run () // see bug #78306 for details
236                 {
237                         Assert.IsFalse (success, "pre-check");
238                         ExecutionContext.Run (ExecutionContext.Capture (), new ContextCallback (Callback), true);
239                         Assert.IsTrue (success, "post-check");
240                 }
241
242                 [Test]
243                 [ExpectedException (typeof (InvalidOperationException))]
244                 [Category("MobileNotWorking")]
245                 public void Run_SuppressFlow ()
246                 {
247                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed ());
248                         AsyncFlowControl afc = ExecutionContext.SuppressFlow ();
249                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed ());
250                         try {
251                                 ExecutionContext.Run (ExecutionContext.Capture (), new ContextCallback (Callback), "Hello world.");
252                         }
253                         finally {
254                                 afc.Undo ();
255                         }
256                 }
257
258                 [Test]
259                 [Category("MobileNotWorking")]
260                 public void SuppressFlow ()
261                 {
262                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
263
264                         AsyncFlowControl afc = ExecutionContext.SuppressFlow ();
265                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-3");
266                         afc.Undo ();
267
268                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-4");
269                 }
270
271                 [Test]
272                 [ExpectedException (typeof (InvalidOperationException))]
273                 [Category("MobileNotWorking")]
274                 public void SuppressFlow_Two_Undo ()
275                 {
276                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
277
278                         AsyncFlowControl afc = ExecutionContext.SuppressFlow ();
279                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-2");
280
281                         AsyncFlowControl afc2 = ExecutionContext.SuppressFlow ();
282                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-3");
283                         afc2.Undo ();
284
285                         // note: afc2 Undo return to the original (not the previous) state
286                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-4");
287
288                         // we can't use the first AsyncFlowControl
289                         afc.Undo ();
290                 }
291         }
292 }
293