Add unit test for AggregateException.GetBaseException that works on .net but is broke...
[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
72                 [Test]
73                 [Category ("MobileNotWorking")]
74                 public void CaptureCallContext ()
75                 {
76                         var value = new CallContextValue (true);
77                         object capturedValue = null;
78
79                         CallContext.SetData ("testlc", value);
80
81                         ExecutionContext ec = ExecutionContext.Capture ();
82                         Assert.IsNotNull (ec, "Capture");
83                         Assert.AreEqual (value, CallContext.GetData ("testlc")); 
84                         CallContext.SetData ("testlc", null);
85
86                         ExecutionContext.Run (ec, new ContextCallback (new Action<object> ((data) => {
87                                 capturedValue = CallContext.GetData ("testlc");
88                         })), null);
89
90                         Assert.AreEqual (value, capturedValue); 
91                         Assert.AreNotEqual (value, CallContext.GetData ("testlc"));
92                 }
93
94                 [Test]
95                 public void Capture ()
96                 {
97                         ExecutionContext ec = ExecutionContext.Capture ();
98                         Assert.IsNotNull (ec, "Capture");
99
100                         AsyncFlowControl afc = ExecutionContext.SuppressFlow ();
101                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
102                         try {
103                                 ec = ExecutionContext.Capture ();
104                                 Assert.IsNull (ec, "Capture with SuppressFlow");
105                         }
106                         finally {
107                                 afc.Undo ();
108                         }
109                 }
110
111                 [Test]
112                 public void Copy ()
113                 {
114                         ExecutionContext ec = ExecutionContext.Capture ();
115                         Assert.IsNotNull (ec, "Capture");
116
117                         ExecutionContext copy = ec.CreateCopy ();
118                         Assert.IsNotNull (copy, "Copy of Capture");
119
120                         Assert.IsFalse (ec.Equals (copy));
121                         Assert.IsFalse (copy.Equals (ec));
122                         Assert.IsFalse (Object.ReferenceEquals (ec, copy));
123
124                         ExecutionContext copy2nd = copy.CreateCopy ();
125                         Assert.IsNotNull (copy2nd, "2nd level copy of Capture");
126                 }
127
128                 [Test]
129                 [ExpectedException (typeof (InvalidOperationException))]
130                 // The context might be the result of capture so no exception is thrown
131                 [Category ("NotWorking")]
132                 public void Copy_FromThread ()
133                 {
134                         ExecutionContext ec = Thread.CurrentThread.ExecutionContext;
135                         Assert.IsNotNull (ec, "Thread.CurrentThread.ExecutionContext");
136
137                         ExecutionContext copy = ec.CreateCopy ();
138                 }
139
140                 [Test]
141                 public void IsFlowSuppressed ()
142                 {
143                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
144
145                         AsyncFlowControl afc = ExecutionContext.SuppressFlow ();
146                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-2");
147                         afc.Undo ();
148
149                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-3");
150                 }
151
152                 [Test]
153                 [ExpectedException (typeof (InvalidOperationException))]
154                 public void RestoreFlow_None ()
155                 {
156                         ExecutionContext.RestoreFlow ();
157                 }
158
159                 [Test]
160                 public void RestoreFlow_SuppressFlow ()
161                 {
162                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
163                         ExecutionContext.SuppressFlow ();
164                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-2");
165                         ExecutionContext.RestoreFlow ();
166                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-3");
167                 }
168
169                 [Test]
170                 [Category ("CAS")] // since r60298 the SecurityContext is only captured if the security manager is active
171                 public void Run () // see bug #78306 for details
172                 {
173                         Assert.IsFalse (success, "pre-check");
174                         ExecutionContext.Run (ExecutionContext.Capture (), new ContextCallback (Callback), true);
175                         Assert.IsTrue (success, "post-check");
176                 }
177
178                 [Test]
179                 [ExpectedException (typeof (InvalidOperationException))]
180                 public void Run_SuppressFlow ()
181                 {
182                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed ());
183                         AsyncFlowControl afc = ExecutionContext.SuppressFlow ();
184                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed ());
185                         try {
186                                 ExecutionContext.Run (ExecutionContext.Capture (), new ContextCallback (Callback), "Hello world.");
187                         }
188                         finally {
189                                 afc.Undo ();
190                         }
191                 }
192
193                 [Test]
194                 public void SuppressFlow ()
195                 {
196                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
197
198                         AsyncFlowControl afc = ExecutionContext.SuppressFlow ();
199                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-3");
200                         afc.Undo ();
201
202                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-4");
203                 }
204
205                 [Test]
206                 [ExpectedException (typeof (InvalidOperationException))]
207                 public void SuppressFlow_Two_Undo ()
208                 {
209                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
210
211                         AsyncFlowControl afc = ExecutionContext.SuppressFlow ();
212                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-2");
213
214                         AsyncFlowControl afc2 = ExecutionContext.SuppressFlow ();
215                         Assert.IsTrue (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-3");
216                         afc2.Undo ();
217
218                         // note: afc2 Undo return to the original (not the previous) state
219                         Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-4");
220
221                         // we can't use the first AsyncFlowControl
222                         afc.Undo ();
223                 }
224         }
225 }
226
227 #endif