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