fe777c5c82
Former-commit-id: 6a76a29bd07d86e57c6c8da45c65ed5447d38a61
406 lines
15 KiB
C#
406 lines
15 KiB
C#
//
|
|
// DispatchRuntimeTest.cs
|
|
//
|
|
// Author:
|
|
// Atsushi Enomoto <atsushi@ximian.com>
|
|
//
|
|
// Copyright (C) 2006 Novell, Inc. http://www.novell.com
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.Serialization;
|
|
using System.ServiceModel;
|
|
using System.ServiceModel.Channels;
|
|
using System.ServiceModel.Description;
|
|
using System.ServiceModel.Dispatcher;
|
|
using System.ServiceModel.Security;
|
|
using System.Xml;
|
|
using NUnit.Framework;
|
|
using System.Collections.ObjectModel;
|
|
using SMMessage = System.ServiceModel.Channels.Message;
|
|
using System.Threading;
|
|
|
|
namespace MonoTests.System.ServiceModel.Dispatcher
|
|
{
|
|
[TestFixture]
|
|
public class DispatchRuntimeTest
|
|
{
|
|
[Test]
|
|
public void TestConstructor ()
|
|
{
|
|
// This test is rather to just detect implementation
|
|
// differences than digging in-depth meanings, so feel
|
|
// free to change if MS implementation does not make
|
|
// sense.
|
|
DispatchRuntime r = new EndpointDispatcher (
|
|
new EndpointAddress ("http://localhost:30158"), "IFoo", "urn:foo").DispatchRuntime;
|
|
Assert.AreEqual (AuditLogLocation.Default,
|
|
r.SecurityAuditLogLocation, "#1");
|
|
|
|
Assert.IsTrue (r.AutomaticInputSessionShutdown, "#2");
|
|
Assert.IsNotNull (r.CallbackClientRuntime, "#3");
|
|
Assert.IsNull (r.ExternalAuthorizationPolicies, "#4");
|
|
Assert.IsFalse (r.IgnoreTransactionMessageProperty, "#5");
|
|
Assert.IsFalse (r.ImpersonateCallerForAllOperations, "#6");
|
|
Assert.AreEqual (0, r.InputSessionShutdownHandlers.Count, "#7");
|
|
Assert.AreEqual (0, r.InstanceContextInitializers.Count, "#8");
|
|
//Assert.AreEqual (0, r.InstanceContextLifetimes.Count, "#9");
|
|
Assert.IsNull (r.InstanceProvider, "#10");
|
|
Assert.IsNull (r.InstanceContextProvider, "#10-2");
|
|
Assert.AreEqual (AuditLevel.None,
|
|
r.MessageAuthenticationAuditLevel, "#11");
|
|
Assert.AreEqual (0, r.MessageInspectors.Count, "#12");
|
|
Assert.AreEqual (0, r.Operations.Count, "#13");
|
|
Assert.IsNull (r.OperationSelector, "#14");
|
|
// This is silly, but anyways there will be similar
|
|
// functionality that just represents unix "Groups".
|
|
Assert.AreEqual (PrincipalPermissionMode.UseWindowsGroups,
|
|
r.PrincipalPermissionMode, "#15");
|
|
Assert.IsFalse (r.ReleaseServiceInstanceOnTransactionComplete, "#16");
|
|
Assert.IsNull (r.RoleProvider, "#17");
|
|
Assert.AreEqual (AuditLevel.None, r.ServiceAuthorizationAuditLevel, "#18");
|
|
Assert.IsNull (r.ServiceAuthorizationManager, "#19");
|
|
Assert.IsTrue (r.SuppressAuditFailure, "#20");
|
|
Assert.IsNull (r.SynchronizationContext, "#21");
|
|
Assert.IsFalse (r.TransactionAutoCompleteOnSessionClose, "#22");
|
|
Assert.IsNull (r.Type, "#23");
|
|
Assert.IsNotNull (r.UnhandledDispatchOperation, "#24");
|
|
DispatchOperation udo = r.UnhandledDispatchOperation;
|
|
Assert.AreEqual ("*", udo.Name, "#24-2");
|
|
Assert.AreEqual ("*", udo.Action, "#24-3");
|
|
Assert.AreEqual ("*", udo.ReplyAction, "#24-4");
|
|
Assert.IsFalse (udo.IsOneWay, "#24-5");
|
|
}
|
|
|
|
[Test]
|
|
public void TestInstanceBehavior1 ()
|
|
{
|
|
|
|
Result res = new Result ();
|
|
MessageInspectBehavior b = new MessageInspectBehavior ();
|
|
b.instanceCtxInitializer = new MyInstanceContextInitializer (res);
|
|
b.instanceCtxProvider = new MyInstanceContextProvider (null, res);
|
|
//b.instanceProvider = new MyInstanceProvider (null, res);
|
|
b.msgInspect = new MyMessageInspector (res);
|
|
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 , ";
|
|
TestInstanceBehavior (b, expected, res, 1);
|
|
Assert.IsTrue (res.Done, "done");
|
|
}
|
|
|
|
[Test]
|
|
public void TestInstanceBehavior2 ()
|
|
{
|
|
Result res = new Result ();
|
|
MessageInspectBehavior b = new MessageInspectBehavior ();
|
|
b.instanceCtxInitializer = new MyInstanceContextInitializer (res);
|
|
b.instanceCtxProvider = new MyInstanceContextProvider (null, res);
|
|
b.instanceProvider = new MyInstanceProvider (new AllActions (res), res);
|
|
b.msgInspect = new MyMessageInspector (res);
|
|
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 , ";
|
|
TestInstanceBehavior (b, expected, res, 1);
|
|
Assert.IsTrue (res.Done, "done");
|
|
}
|
|
|
|
[Test]
|
|
public void TestInstanceBehavior3 ()
|
|
{
|
|
Result res = new Result ();
|
|
MessageInspectBehavior b = new MessageInspectBehavior ();
|
|
b.instanceCtxInitializer = new MyInstanceContextInitializer (res);
|
|
|
|
InstanceContext c = new InstanceContext (new AllActions (res));
|
|
|
|
b.instanceCtxProvider = new MyInstanceContextProvider (c, res);
|
|
b.instanceProvider = new MyInstanceProvider (new AllActions (res), res);
|
|
b.msgInspect = new MyMessageInspector (res);
|
|
string expected = "GetExistingInstanceContext , InitializeInstanceContext , OperationContext , InstanceContext = Opening , Initialize , OperationContext , InstanceContext = Opening , AfterReceiveRequest , OperationContext , InstanceContext = Opened , BeforeSendReply , OperationContext , InstanceContext = Opened , ";
|
|
TestInstanceBehavior (b, expected, res, 1); Assert.IsTrue (res.Done, "done");
|
|
}
|
|
|
|
[Test]
|
|
public void TestInstanceBehavior4 ()
|
|
{
|
|
Result res = new Result ();
|
|
MessageInspectBehavior b = new MessageInspectBehavior ();
|
|
b.instanceCtxInitializer = new MyInstanceContextInitializer (res);
|
|
|
|
b.instanceCtxProvider = new MyInstanceContextProvider (null, res);
|
|
b.instanceProvider = new MyInstanceProvider (new AllActions (res), res);
|
|
b.msgInspect = new MyMessageInspector (res);
|
|
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 , ";
|
|
TestInstanceBehavior (b, expected, res, 2); Assert.IsTrue (res.Done, "done");
|
|
}
|
|
|
|
void TestInstanceBehavior (MessageInspectBehavior b, string expected, Result actual, int invocations)
|
|
{
|
|
ServiceHost h = new ServiceHost (typeof (AllActions), new Uri ("http://localhost:30158"));
|
|
try {
|
|
h.AddServiceEndpoint (typeof (IAllActions).FullName, new BasicHttpBinding (), "AllActions");
|
|
h.Description.Behaviors.Add (b);
|
|
ServiceDebugBehavior db = h.Description.Behaviors.Find<ServiceDebugBehavior> ();
|
|
db.IncludeExceptionDetailInFaults = true;
|
|
h.Open ();
|
|
foreach (ChannelDispatcher cd in h.ChannelDispatchers) {
|
|
foreach (var ed in cd.Endpoints) {
|
|
if (ed.ContractName == "IHttpGetHelpPageAndMetadataContract")
|
|
continue;
|
|
Assert.AreEqual (typeof (AllActions), ed.DispatchRuntime.Type, "Type property: " + ed.ContractName);
|
|
}
|
|
}
|
|
AllActionsProxy p = new AllActionsProxy (new BasicHttpBinding () { SendTimeout = TimeSpan.FromSeconds (5), ReceiveTimeout = TimeSpan.FromSeconds (5) }, new EndpointAddress ("http://localhost:30158/AllActions"));
|
|
|
|
for (int i = 0; i < invocations; ++i)
|
|
p.Get (10);
|
|
p.Close ();
|
|
|
|
//let ther server finish his work
|
|
Thread.Sleep (100);
|
|
Assert.AreEqual (expected, actual.string_res);
|
|
actual.Done = true;
|
|
}
|
|
finally {
|
|
h.Close ();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#region helpers
|
|
|
|
#region message inspectors
|
|
|
|
public class MessageInspectBehavior : IServiceBehavior
|
|
{
|
|
public MyMessageInspector msgInspect;
|
|
public MyInstanceContextProvider instanceCtxProvider;
|
|
public MyInstanceProvider instanceProvider;
|
|
public MyInstanceContextInitializer instanceCtxInitializer;
|
|
|
|
public void AddBindingParameters (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) {
|
|
|
|
}
|
|
|
|
public void ApplyDispatchBehavior (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
|
|
ChannelDispatcher d = serviceHostBase.ChannelDispatchers [0] as ChannelDispatcher;
|
|
d.Endpoints [0].DispatchRuntime.MessageInspectors.Add (msgInspect);
|
|
d.Endpoints [0].DispatchRuntime.InstanceContextProvider = instanceCtxProvider;
|
|
d.Endpoints [0].DispatchRuntime.InstanceProvider = instanceProvider;
|
|
d.Endpoints [0].DispatchRuntime.InstanceContextInitializers.Add (instanceCtxInitializer);
|
|
}
|
|
|
|
public void Validate (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
|
|
|
|
}
|
|
}
|
|
|
|
public class MyMessageInspector : IDispatchMessageInspector
|
|
{
|
|
Result res;
|
|
|
|
public MyMessageInspector (Result result) {
|
|
res = result;
|
|
}
|
|
#region IDispatchMessageInspector Members
|
|
|
|
public object AfterReceiveRequest (ref Message request, IClientChannel channel, InstanceContext instanceContext) {
|
|
res.string_res += "AfterReceiveRequest , ";
|
|
res.AddCurrentOperationContextInfo ();
|
|
return null;
|
|
}
|
|
|
|
public void BeforeSendReply (ref Message reply, object correlationState) {
|
|
res.string_res += "BeforeSendReply , ";
|
|
res.AddCurrentOperationContextInfo ();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region InstanceProvider
|
|
|
|
public class MyInstanceProvider : IInstanceProvider
|
|
{
|
|
object instance;
|
|
Result res;
|
|
|
|
public MyInstanceProvider (object obj, Result result) {
|
|
instance = obj;
|
|
res = result;
|
|
}
|
|
|
|
#region IInstanceProvider Members
|
|
|
|
public object GetInstance (InstanceContext instanceContext, Message message) {
|
|
res.string_res += "GetInstance1 , ";
|
|
res.AddCurrentOperationContextInfo ();
|
|
return instance;
|
|
}
|
|
|
|
public object GetInstance (InstanceContext instanceContext) {
|
|
res.string_res += "GetInstance2 , ";
|
|
res.AddCurrentOperationContextInfo ();
|
|
return instance;
|
|
}
|
|
|
|
public void ReleaseInstance (InstanceContext instanceContext, object instance) {
|
|
res.string_res += "ReleaseInstance , ";
|
|
res.AddCurrentOperationContextInfo ();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region InstanceContextProvider
|
|
|
|
public class MyInstanceContextProvider : IInstanceContextProvider
|
|
{
|
|
|
|
InstanceContext existing;
|
|
Result res;
|
|
|
|
public MyInstanceContextProvider (InstanceContext exist, Result result) {
|
|
existing = exist;
|
|
res = result;
|
|
}
|
|
|
|
#region IInstanceContextProvider Members
|
|
|
|
public InstanceContext GetExistingInstanceContext (Message message, IContextChannel channel) {
|
|
res.string_res += "GetExistingInstanceContext , ";
|
|
res.AddCurrentOperationContextInfo ();
|
|
return existing;
|
|
}
|
|
|
|
public void InitializeInstanceContext (InstanceContext instanceContext, Message message, IContextChannel channel) {
|
|
res.string_res += "InitializeInstanceContext , ";
|
|
res.AddCurrentOperationContextInfo ();
|
|
}
|
|
|
|
public bool IsIdle (InstanceContext instanceContext) {
|
|
res.string_res += "IsIdle , ";
|
|
res.AddCurrentOperationContextInfo ();
|
|
return false;
|
|
}
|
|
|
|
public void NotifyIdle (InstanceContextIdleCallback callback, InstanceContext instanceContext) {
|
|
res.string_res += "NotifyIdle , ";
|
|
res.AddCurrentOperationContextInfo ();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region InstanceContextInitializer
|
|
|
|
public class MyInstanceContextInitializer : IInstanceContextInitializer
|
|
{
|
|
Result res;
|
|
|
|
public MyInstanceContextInitializer (Result result) {
|
|
res = result;
|
|
}
|
|
|
|
public void Initialize (InstanceContext instanceContext, Message message) {
|
|
res.string_res += "Initialize , ";
|
|
res.AddCurrentOperationContextInfo ();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Helpers
|
|
|
|
public class Result
|
|
{
|
|
public bool Done;
|
|
public string string_res = "";
|
|
|
|
public void AddCurrentOperationContextInfo()
|
|
{
|
|
if (OperationContext.Current != null) {
|
|
string_res += "OperationContext , ";
|
|
if (OperationContext.Current.InstanceContext != null) {
|
|
string_res += ("InstanceContext = " + OperationContext.Current.InstanceContext.State + " , ");
|
|
//if (OperationContext.Current.InstanceContext != null)
|
|
// string_res += ("Instance = " + OperationContext.Current.InstanceContext.GetServiceInstance () + " , ");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class AllActions : IAllActions, IDisposable
|
|
{
|
|
Result res;
|
|
|
|
public AllActions () { }
|
|
|
|
public AllActions (Result result) {
|
|
res = result;
|
|
}
|
|
|
|
[OperationBehavior (ReleaseInstanceMode = ReleaseInstanceMode.BeforeAndAfterCall)]
|
|
public int Get(int i)
|
|
{
|
|
return i;
|
|
}
|
|
|
|
public void Dispose () {
|
|
if (res != null)
|
|
res.string_res += "Disposed , ";
|
|
}
|
|
}
|
|
|
|
[ServiceContract (Namespace = "http://MonoTests.System.ServiceModel.Dispatcher")]
|
|
public interface IAllActions
|
|
{
|
|
[OperationContract]
|
|
int Get(int i);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ClientProxy
|
|
|
|
public class AllActionsProxy : ClientBase<IAllActions>, IAllActions
|
|
{
|
|
public AllActionsProxy (Binding binding, EndpointAddress remoteAddress) :
|
|
base (binding, remoteAddress)
|
|
{
|
|
}
|
|
|
|
public int Get (int i) {
|
|
return base.Channel.Get (i);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
#endregion
|
|
|
|
}
|