[sgen] Clear the card table in the finishing pause
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel.Dispatcher / DispatchRuntimeTest.cs
1 //
2 // DispatchRuntimeTest.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2006 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
29 using System;
30 using System.Collections.Generic;
31 using System.Runtime.Serialization;
32 using System.ServiceModel;
33 using System.ServiceModel.Channels;
34 using System.ServiceModel.Description;
35 using System.ServiceModel.Dispatcher;
36 using System.ServiceModel.Security;
37 using System.Xml;
38 using NUnit.Framework;
39 using System.Collections.ObjectModel;
40 using SMMessage = System.ServiceModel.Channels.Message;
41 using System.Threading;
42
43 namespace MonoTests.System.ServiceModel.Dispatcher
44 {
45         [TestFixture]
46         public class DispatchRuntimeTest
47         {
48                 [Test]
49                 public void TestConstructor ()
50                 {
51                         // This test is rather to just detect implementation 
52                         // differences than digging in-depth meanings, so feel
53                         // free to change if MS implementation does not make 
54                         // sense.
55                         DispatchRuntime r = new EndpointDispatcher (
56                                 new EndpointAddress ("http://localhost:30158"), "IFoo", "urn:foo").DispatchRuntime;
57                         Assert.AreEqual (AuditLogLocation.Default,
58                                          r.SecurityAuditLogLocation, "#1");
59
60                         Assert.IsTrue (r.AutomaticInputSessionShutdown, "#2");
61                         Assert.IsNotNull (r.CallbackClientRuntime, "#3");
62                         Assert.IsNull (r.ExternalAuthorizationPolicies, "#4");
63                         Assert.IsFalse (r.IgnoreTransactionMessageProperty, "#5");
64                         Assert.IsFalse (r.ImpersonateCallerForAllOperations, "#6");
65                         Assert.AreEqual (0, r.InputSessionShutdownHandlers.Count, "#7");
66                         Assert.AreEqual (0, r.InstanceContextInitializers.Count, "#8");
67                         //Assert.AreEqual (0, r.InstanceContextLifetimes.Count, "#9");
68                         Assert.IsNull (r.InstanceProvider, "#10");
69                         Assert.IsNull (r.InstanceContextProvider, "#10-2");
70                         Assert.AreEqual (AuditLevel.None,
71                                          r.MessageAuthenticationAuditLevel, "#11");
72                         Assert.AreEqual (0, r.MessageInspectors.Count, "#12");
73                         Assert.AreEqual (0, r.Operations.Count, "#13");
74                         Assert.IsNull (r.OperationSelector, "#14");
75                         // This is silly, but anyways there will be similar 
76                         // functionality that just represents unix "Groups".
77                         Assert.AreEqual (PrincipalPermissionMode.UseWindowsGroups,
78                                          r.PrincipalPermissionMode, "#15");
79                         Assert.IsFalse (r.ReleaseServiceInstanceOnTransactionComplete, "#16");
80                         Assert.IsNull (r.RoleProvider, "#17");
81                         Assert.AreEqual (AuditLevel.None, r.ServiceAuthorizationAuditLevel, "#18");
82                         Assert.IsNull (r.ServiceAuthorizationManager, "#19");
83                         Assert.IsTrue (r.SuppressAuditFailure, "#20");
84                         Assert.IsNull (r.SynchronizationContext, "#21");
85                         Assert.IsFalse (r.TransactionAutoCompleteOnSessionClose, "#22");
86                         Assert.IsNull (r.Type, "#23");
87                         Assert.IsNotNull (r.UnhandledDispatchOperation, "#24");
88                         DispatchOperation udo = r.UnhandledDispatchOperation;
89                         Assert.AreEqual ("*", udo.Name, "#24-2");
90                         Assert.AreEqual ("*", udo.Action, "#24-3");
91                         Assert.AreEqual ("*", udo.ReplyAction, "#24-4");
92                         Assert.IsFalse (udo.IsOneWay, "#24-5");
93                 }
94
95                 [Test]
96                 public void TestInstanceBehavior1 ()
97                 {
98                         
99                         Result res = new Result ();
100                         MessageInspectBehavior b = new MessageInspectBehavior ();
101                         b.instanceCtxInitializer = new MyInstanceContextInitializer (res);
102                         b.instanceCtxProvider = new MyInstanceContextProvider (null, res);
103                         //b.instanceProvider = new MyInstanceProvider (null, res);
104                         b.msgInspect = new MyMessageInspector (res);
105                         string expected = "GetExistingInstanceContext , InitializeInstanceContext , OperationContext , InstanceContext = Opening , Initialize , OperationContext , InstanceContext = Opening , AfterReceiveRequest , OperationContext , InstanceContext = Opened , BeforeSendReply , OperationContext , InstanceContext = Opened , IsIdle , OperationContext , InstanceContext = Opened , NotifyIdle , OperationContext , InstanceContext = Opened , ";
106                         TestInstanceBehavior (b, expected, res, 1);
107                         Assert.IsTrue (res.Done, "done");
108                 }
109
110                 [Test]
111                 public void TestInstanceBehavior2 ()
112                 {
113                         Result res = new Result ();
114                         MessageInspectBehavior b = new MessageInspectBehavior ();
115                         b.instanceCtxInitializer = new MyInstanceContextInitializer (res);
116                         b.instanceCtxProvider = new MyInstanceContextProvider (null, res);
117                         b.instanceProvider = new MyInstanceProvider (new AllActions (res), res);
118                         b.msgInspect = new MyMessageInspector (res);
119                         string expected = "GetExistingInstanceContext , InitializeInstanceContext , OperationContext , InstanceContext = Opening , Initialize , OperationContext , InstanceContext = Opening , AfterReceiveRequest , OperationContext , InstanceContext = Opened , GetInstance1 , OperationContext , InstanceContext = Opened , BeforeSendReply , OperationContext , InstanceContext = Opened , ReleaseInstance , OperationContext , InstanceContext = Opened , IsIdle , OperationContext , InstanceContext = Opened , NotifyIdle , OperationContext , InstanceContext = Opened , ";
120                         TestInstanceBehavior (b, expected, res, 1);
121                         Assert.IsTrue (res.Done, "done");
122                 }
123
124                 [Test]
125                 public void TestInstanceBehavior3 ()
126                 {
127                         Result res = new Result ();
128                         MessageInspectBehavior b = new MessageInspectBehavior ();
129                         b.instanceCtxInitializer = new MyInstanceContextInitializer (res);
130
131                         InstanceContext c = new InstanceContext (new AllActions (res));
132                         
133                         b.instanceCtxProvider = new MyInstanceContextProvider (c, res);
134                         b.instanceProvider = new MyInstanceProvider (new AllActions (res), res);
135                         b.msgInspect = new MyMessageInspector (res);
136                         string expected = "GetExistingInstanceContext , InitializeInstanceContext , OperationContext , InstanceContext = Opening , Initialize , OperationContext , InstanceContext = Opening , AfterReceiveRequest , OperationContext , InstanceContext = Opened , BeforeSendReply , OperationContext , InstanceContext = Opened , ";
137                         TestInstanceBehavior (b, expected, res, 1);                                     Assert.IsTrue (res.Done, "done");
138                 }
139
140                 [Test]
141                 public void TestInstanceBehavior4 ()
142                 {
143                         Result res = new Result ();
144                         MessageInspectBehavior b = new MessageInspectBehavior ();
145                         b.instanceCtxInitializer = new MyInstanceContextInitializer (res);      
146                 
147                         b.instanceCtxProvider = new MyInstanceContextProvider (null, res);
148                         b.instanceProvider = new MyInstanceProvider (new AllActions (res), res);
149                         b.msgInspect = new MyMessageInspector (res);
150                         string expected = "GetExistingInstanceContext , InitializeInstanceContext , OperationContext , InstanceContext = Opening , Initialize , OperationContext , InstanceContext = Opening , AfterReceiveRequest , OperationContext , InstanceContext = Opened , GetInstance1 , OperationContext , InstanceContext = Opened , BeforeSendReply , OperationContext , InstanceContext = Opened , ReleaseInstance , OperationContext , InstanceContext = Opened , IsIdle , OperationContext , InstanceContext = Opened , NotifyIdle , OperationContext , InstanceContext = Opened , GetExistingInstanceContext , InitializeInstanceContext , OperationContext , InstanceContext = Opening , Initialize , OperationContext , InstanceContext = Opening , AfterReceiveRequest , OperationContext , InstanceContext = Opened , GetInstance1 , OperationContext , InstanceContext = Opened , BeforeSendReply , OperationContext , InstanceContext = Opened , ReleaseInstance , OperationContext , InstanceContext = Opened , IsIdle , OperationContext , InstanceContext = Opened , NotifyIdle , OperationContext , InstanceContext = Opened , ";
151                         TestInstanceBehavior (b, expected, res, 2);                                     Assert.IsTrue (res.Done, "done");
152                 }
153
154                 void TestInstanceBehavior (MessageInspectBehavior b, string expected, Result actual, int invocations)
155                 {
156                         ServiceHost h = new ServiceHost (typeof (AllActions), new Uri ("http://localhost:30158"));
157                         try {
158                                 h.AddServiceEndpoint (typeof (IAllActions).FullName, new BasicHttpBinding (), "AllActions");
159                                 h.Description.Behaviors.Add (b);
160                                 ServiceDebugBehavior db = h.Description.Behaviors.Find<ServiceDebugBehavior> ();
161                                 db.IncludeExceptionDetailInFaults = true;
162                                 h.Open ();
163                                 foreach (ChannelDispatcher cd in h.ChannelDispatchers) {
164                                         foreach (var ed in cd.Endpoints) {
165                                                 if (ed.ContractName == "IHttpGetHelpPageAndMetadataContract")
166                                                         continue;
167                                                 Assert.AreEqual (typeof (AllActions), ed.DispatchRuntime.Type, "Type property: " + ed.ContractName);
168                                         }
169                                 }
170                                 AllActionsProxy p = new AllActionsProxy (new BasicHttpBinding () { SendTimeout = TimeSpan.FromSeconds (5), ReceiveTimeout = TimeSpan.FromSeconds (5) }, new EndpointAddress ("http://localhost:30158/AllActions"));
171
172                                 for (int i = 0; i < invocations; ++i)
173                                         p.Get (10);
174                                 p.Close ();
175
176                                 //let ther server finish his work
177                                 Thread.Sleep (100);
178                                 Assert.AreEqual (expected, actual.string_res);
179                                 actual.Done = true;
180                         }
181                         finally {                               
182                                 h.Close ();
183                         }
184                 }
185         }
186
187
188 #region helpers
189
190         #region message inspectors
191
192         public class MessageInspectBehavior : IServiceBehavior
193         {
194                 public MyMessageInspector msgInspect;
195                 public MyInstanceContextProvider instanceCtxProvider;
196                 public MyInstanceProvider instanceProvider;
197                 public MyInstanceContextInitializer instanceCtxInitializer;
198
199                 public void AddBindingParameters (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) {
200                         
201                 }
202
203                 public void ApplyDispatchBehavior (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
204                         ChannelDispatcher d = serviceHostBase.ChannelDispatchers [0] as ChannelDispatcher;
205                         d.Endpoints [0].DispatchRuntime.MessageInspectors.Add (msgInspect);
206                         d.Endpoints [0].DispatchRuntime.InstanceContextProvider = instanceCtxProvider;
207                         d.Endpoints [0].DispatchRuntime.InstanceProvider = instanceProvider;
208                         d.Endpoints [0].DispatchRuntime.InstanceContextInitializers.Add (instanceCtxInitializer);
209                 }
210
211                 public void Validate (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
212                         
213                 }
214         }
215
216         public class MyMessageInspector : IDispatchMessageInspector
217         {
218                 Result res;
219
220                 public MyMessageInspector (Result result) {
221                         res = result;
222                 }
223                 #region IDispatchMessageInspector Members
224
225                 public object AfterReceiveRequest (ref Message request, IClientChannel channel, InstanceContext instanceContext) {
226                         res.string_res += "AfterReceiveRequest , ";
227                         res.AddCurrentOperationContextInfo ();
228                         return null;
229                 }
230
231                 public void BeforeSendReply (ref Message reply, object correlationState) {
232                         res.string_res += "BeforeSendReply , ";
233                         res.AddCurrentOperationContextInfo ();
234                 }
235
236                 #endregion
237         }
238
239         #endregion
240
241         #region InstanceProvider
242
243         public class MyInstanceProvider : IInstanceProvider
244         {               
245                 object instance;
246                 Result res;
247
248                 public MyInstanceProvider (object obj, Result result) {
249                         instance = obj;
250                         res = result;
251                 }
252
253                 #region IInstanceProvider Members
254
255                 public object GetInstance (InstanceContext instanceContext, Message message) {
256                         res.string_res += "GetInstance1 , ";
257                         res.AddCurrentOperationContextInfo ();
258                         return instance;
259                 }
260
261                 public object GetInstance (InstanceContext instanceContext) {
262                         res.string_res += "GetInstance2 , ";
263                         res.AddCurrentOperationContextInfo ();
264                         return instance;
265                 }
266
267                 public void ReleaseInstance (InstanceContext instanceContext, object instance) {
268                         res.string_res += "ReleaseInstance , ";
269                         res.AddCurrentOperationContextInfo ();
270                 }
271
272                 #endregion
273         }
274
275         #endregion
276
277         #region InstanceContextProvider
278
279         public class MyInstanceContextProvider : IInstanceContextProvider
280         {
281
282                 InstanceContext existing;
283                 Result res;
284
285                 public MyInstanceContextProvider (InstanceContext exist, Result result) {
286                         existing = exist;
287                         res = result;
288                 }
289
290                 #region IInstanceContextProvider Members
291
292                 public InstanceContext GetExistingInstanceContext (Message message, IContextChannel channel) {
293                         res.string_res += "GetExistingInstanceContext , ";
294                         res.AddCurrentOperationContextInfo ();
295                         return existing;
296                 }
297
298                 public void InitializeInstanceContext (InstanceContext instanceContext, Message message, IContextChannel channel) {
299                         res.string_res += "InitializeInstanceContext , ";
300                         res.AddCurrentOperationContextInfo ();
301                 }
302
303                 public bool IsIdle (InstanceContext instanceContext) {
304                         res.string_res += "IsIdle , ";
305                         res.AddCurrentOperationContextInfo ();
306                         return false;
307                 }
308
309                 public void NotifyIdle (InstanceContextIdleCallback callback, InstanceContext instanceContext) {
310                         res.string_res += "NotifyIdle , ";
311                         res.AddCurrentOperationContextInfo ();                  
312                 }
313
314                 #endregion
315         }
316
317         #endregion
318
319         #region InstanceContextInitializer
320
321         public class MyInstanceContextInitializer : IInstanceContextInitializer
322         {
323                 Result res;
324
325                 public MyInstanceContextInitializer (Result result) {
326                         res = result;
327                 }
328
329                 public void Initialize (InstanceContext instanceContext, Message message) {
330                         res.string_res += "Initialize , ";
331                         res.AddCurrentOperationContextInfo ();
332                 }
333         }
334
335         #endregion
336
337         #region Helpers
338
339         public class Result
340         {
341                 public bool Done;
342                 public string string_res = "";
343
344                 public void AddCurrentOperationContextInfo()
345                 {
346                         if (OperationContext.Current != null) {
347                                 string_res += "OperationContext , ";
348                                 if (OperationContext.Current.InstanceContext != null) {
349                                         string_res += ("InstanceContext = " + OperationContext.Current.InstanceContext.State + " , ");
350                                         //if (OperationContext.Current.InstanceContext != null)
351                                         //    string_res += ("Instance = " + OperationContext.Current.InstanceContext.GetServiceInstance () + " , ");
352                                 }
353                         }
354                 }
355         }
356
357         class AllActions : IAllActions, IDisposable
358         {
359                 Result res;
360
361                 public AllActions () { }
362
363                 public AllActions (Result result) {
364                         res = result;
365                 }
366
367                 [OperationBehavior (ReleaseInstanceMode = ReleaseInstanceMode.BeforeAndAfterCall)]
368                 public int Get(int i)
369                 {
370                         return i;
371                 }
372
373                 public void Dispose () {
374                         if (res != null)
375                                 res.string_res += "Disposed , ";
376                 }
377         }
378
379         [ServiceContract (Namespace = "http://MonoTests.System.ServiceModel.Dispatcher")]
380         public interface IAllActions
381         {               
382                 [OperationContract]             
383                 int Get(int i);
384         }
385
386         #endregion
387
388         #region ClientProxy
389         
390         public class AllActionsProxy : ClientBase<IAllActions>, IAllActions
391         {
392                 public AllActionsProxy (Binding binding, EndpointAddress remoteAddress) :
393                         base (binding, remoteAddress)
394                 {
395                 }
396
397                 public int Get (int i) {
398                         return base.Channel.Get (i);
399                 }
400         }       
401
402         #endregion
403 #endregion
404
405 }