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 #if !MOBILE && !XAMMAC_4_5 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] TestConstructor()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] TestInstanceBehavior1()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] TestInstanceBehavior2()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] TestInstanceBehavior3()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] TestInstanceBehavior4()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 TestInstanceBehavior(MessageInspectBehavior b, string expected, Result actual, int invocations)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 AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)202 public void AddBindingParameters (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { 203 204 } 205 ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)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 Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)214 public void Validate (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { 215 216 } 217 } 218 219 public class MyMessageInspector : IDispatchMessageInspector 220 { 221 Result res; 222 MyMessageInspector(Result result)223 public MyMessageInspector (Result result) { 224 res = result; 225 } 226 #region IDispatchMessageInspector Members 227 AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)228 public object AfterReceiveRequest (ref Message request, IClientChannel channel, InstanceContext instanceContext) { 229 res.string_res += "AfterReceiveRequest , "; 230 res.AddCurrentOperationContextInfo (); 231 return null; 232 } 233 BeforeSendReply(ref Message reply, object correlationState)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 MyInstanceProvider(object obj, Result result)251 public MyInstanceProvider (object obj, Result result) { 252 instance = obj; 253 res = result; 254 } 255 256 #region IInstanceProvider Members 257 GetInstance(InstanceContext instanceContext, Message message)258 public object GetInstance (InstanceContext instanceContext, Message message) { 259 res.string_res += "GetInstance1 , "; 260 res.AddCurrentOperationContextInfo (); 261 return instance; 262 } 263 GetInstance(InstanceContext instanceContext)264 public object GetInstance (InstanceContext instanceContext) { 265 res.string_res += "GetInstance2 , "; 266 res.AddCurrentOperationContextInfo (); 267 return instance; 268 } 269 ReleaseInstance(InstanceContext instanceContext, object instance)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 MyInstanceContextProvider(InstanceContext exist, Result result)288 public MyInstanceContextProvider (InstanceContext exist, Result result) { 289 existing = exist; 290 res = result; 291 } 292 293 #region IInstanceContextProvider Members 294 GetExistingInstanceContext(Message message, IContextChannel channel)295 public InstanceContext GetExistingInstanceContext (Message message, IContextChannel channel) { 296 res.string_res += "GetExistingInstanceContext , "; 297 res.AddCurrentOperationContextInfo (); 298 return existing; 299 } 300 InitializeInstanceContext(InstanceContext instanceContext, Message message, IContextChannel channel)301 public void InitializeInstanceContext (InstanceContext instanceContext, Message message, IContextChannel channel) { 302 res.string_res += "InitializeInstanceContext , "; 303 res.AddCurrentOperationContextInfo (); 304 } 305 IsIdle(InstanceContext instanceContext)306 public bool IsIdle (InstanceContext instanceContext) { 307 res.string_res += "IsIdle , "; 308 res.AddCurrentOperationContextInfo (); 309 return false; 310 } 311 NotifyIdle(InstanceContextIdleCallback callback, InstanceContext instanceContext)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 MyInstanceContextInitializer(Result result)328 public MyInstanceContextInitializer (Result result) { 329 res = result; 330 } 331 Initialize(InstanceContext instanceContext, Message message)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 AddCurrentOperationContextInfo()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 AllActions()364 public AllActions () { } 365 AllActions(Result result)366 public AllActions (Result result) { 367 res = result; 368 } 369 370 [OperationBehavior (ReleaseInstanceMode = ReleaseInstanceMode.BeforeAndAfterCall)] Get(int i)371 public int Get(int i) 372 { 373 return i; 374 } 375 Dispose()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] Get(int i)386 int Get(int i); 387 } 388 389 #endregion 390 391 #region ClientProxy 392 393 public class AllActionsProxy : ClientBase<IAllActions>, IAllActions 394 { AllActionsProxy(Binding binding, EndpointAddress remoteAddress)395 public AllActionsProxy (Binding binding, EndpointAddress remoteAddress) : 396 base (binding, remoteAddress) 397 { 398 } 399 Get(int i)400 public int Get (int i) { 401 return base.Channel.Get (i); 402 } 403 } 404 405 #endregion 406 #endregion 407 408 } 409 #endif 410