Merge pull request #1909 from esdrubal/reflection
[mono.git] / mcs / class / corlib / Test / System.Runtime.Remoting.Messaging / CallContextTest.cs
1 //
2 // CallContexTest.cs
3 //
4 // Authors:
5 //      Marek Safar  <marek.safar@gmail.com>
6 //  Chris F Carroll <chris.carroll@unforgettable.me.uk>
7 //
8 // Copyright (C) 2014 Xamarin Inc (http://www.xamarin.com)
9 // Copyright (C) 2013 Chris F Carroll (http://cafe-encounter.net)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System;
32 using System.Collections;
33 using System.Collections.Generic;
34 using NUnit.Framework;
35 using System.Runtime.Remoting.Messaging;
36 using System.Threading;
37 using System.Threading.Tasks;
38
39 namespace MonoTests.System.Runtime.Remoting.Messaging
40 {
41         [TestFixture]
42         public class CallContextTest
43         {
44                 public class Holder : ILogicalThreadAffinative
45                 {
46                         public string Value { get; set; }
47                 }
48
49                 const string SlotName = "Test";
50
51                 [Test]
52                 public void CallContextPropagation_Thread ()
53                 {
54                         bool passed = false;
55                         var t = new Thread (() => {
56                                 var h = CallContext.GetData (SlotName) as Holder;
57                                 passed = h == null;
58                                 CallContext.FreeNamedDataSlot (SlotName);
59                         });
60                         t.Start ();
61                         t.Join ();
62                         Assert.IsTrue (passed, "#1");
63
64                         var holder = new Holder {
65                                 Value = "Hello World"
66                         };
67                         CallContext.SetData (SlotName, holder);
68
69                         t = new Thread (() => {
70                                 var h = CallContext.GetData (SlotName) as Holder;
71                                 passed = h == holder;
72                                 CallContext.FreeNamedDataSlot (SlotName);
73                         });
74                         t.Start ();
75                         t.Join ();
76                         CallContext.FreeNamedDataSlot (SlotName);
77
78                         Assert.IsTrue (passed, "#2");
79                 }
80
81                 [Test]
82                 public void CallContextPropagation_ThreadPool ()
83                 {
84                         var holder = new Holder {
85                                 Value = "Hello World"
86                         };
87                         CallContext.SetData (SlotName, holder);
88
89                         bool passed = false;
90                         var mre = new ManualResetEvent (false);
91                         ThreadPool.QueueUserWorkItem(x => {
92                                 var h = CallContext.GetData (SlotName) as Holder;
93                                 passed = h == holder;
94                                 CallContext.FreeNamedDataSlot (SlotName);
95                                 mre.Set ();
96                         });
97
98                         Assert.IsTrue (mre.WaitOne (3000), "#1");
99                         Assert.IsTrue (passed, "#2");
100
101                         CallContext.FreeNamedDataSlot (SlotName);
102                 }
103
104                 [Test]
105                 public void CallContextPropagation_Not_ThreadPool ()
106                 {
107                         CallContext.SetData (SlotName, "x");
108
109                         bool passed = false;
110                         var mre = new ManualResetEvent (false);
111                         ThreadPool.QueueUserWorkItem(x => {
112                                 var h = (string)CallContext.GetData (SlotName);
113                                 passed = h == null;
114                                 CallContext.FreeNamedDataSlot (SlotName);
115                                 mre.Set ();
116                         });
117
118                         Assert.IsTrue (mre.WaitOne (3000), "#1");
119                         Assert.IsTrue (passed, "#2");
120
121                         CallContext.FreeNamedDataSlot (SlotName);
122                 }
123
124                 [Test]
125                 public void CallContextPropagation_Task ()
126                 {
127                         var holder = new Holder {
128                                 Value = "Hello World"
129                         };
130                         CallContext.SetData (SlotName, holder);
131                         
132                         bool passed = false;
133                         var t = Task.Factory.StartNew(() => {
134                                 var h = CallContext.GetData (SlotName) as Holder;
135                                 passed = h == holder;
136                                 CallContext.FreeNamedDataSlot (SlotName);
137                         });
138
139                         Assert.IsTrue (t.Wait (3000), "#1");
140                         Assert.IsTrue (passed, "#2");
141
142                         CallContext.FreeNamedDataSlot (SlotName);
143                 }
144
145                 [Test]
146                 public void CallContextPropagation_TaskContinuation ()
147                 {
148                         string d1 = null;
149                         string d2 = null;
150                         Console.WriteLine("Current thread: {0}", Thread.CurrentThread.ManagedThreadId);
151
152                         var ct = Thread.CurrentThread.ManagedThreadId;
153                         CallContext.LogicalSetData ("d1", "logicalData");
154                         CallContext.SetData ("d2", "data2");
155                         var t = Task.Factory.StartNew (() => {
156                                 }).ContinueWith (task => {
157                                         d1 = (string) CallContext.LogicalGetData ("d1");
158                                         d2 = (string) CallContext.GetData ("d2");
159                                 }, TaskContinuationOptions.ExecuteSynchronously);
160
161                         Assert.IsTrue (t.Wait (3000), "#0");
162                         Assert.AreEqual ("logicalData", d1, "#1");
163                         Assert.IsNull (d2, "#2");
164
165                         CallContext.FreeNamedDataSlot ("d1");
166                         CallContext.FreeNamedDataSlot ("d2");
167                 }
168
169                 [Test]
170                 public void FreeNamedDataSlot_ShouldClearLogicalData ()
171                 {
172                         CallContext.LogicalSetData ("slotkey", "illogical");
173                         CallContext.FreeNamedDataSlot ("slotkey");
174
175                         Assert.IsNull (CallContext.LogicalGetData ("slotkey"), "Illogical slot should be null");
176                         Assert.IsNull (CallContext.GetData ("slotkey"), "Illogical slot should be null");
177                 }
178
179                 [Test]
180                 public void FreeNamedDataSlot_ShouldClearIllogicalData ()
181                 {
182                         CallContext.SetData ("slotkey", "illogical");
183                         CallContext.FreeNamedDataSlot ("slotkey");
184
185                         Assert.IsNull (CallContext.LogicalGetData ("slotkey"), "Illogical slot should be null");
186                         Assert.IsNull (CallContext.GetData ("slotkey"), "Illogical slot should be null");
187                 }
188
189                 [Test]
190                 public void FreeNamedDataSlot_ShouldClearBothLogicalAndIllogicalData ()
191                 {
192                         CallContext.LogicalSetData ("slotkey","logical");
193                         CallContext.SetData ("slotkey", "illogical");
194                         CallContext.FreeNamedDataSlot ("slotkey");
195
196                         Assert.IsNull (CallContext.LogicalGetData ("slotkey"), "Illogical slot should be null");
197                         Assert.IsNull (CallContext.GetData ("slotkey"), "Illogical slot should be null");
198                 }
199         }
200 }