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