Xamarin Public Jenkins (auto-signing) e46a49ecf1 Imported Upstream version 5.10.0.47
Former-commit-id: d0813289fa2d35e1f8ed77530acb4fb1df441bc0
2018-01-24 17:04:36 +00:00

469 lines
15 KiB
C#

#if !MOBILE && !XAMMAC_4_5
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using NUnit.Framework;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using MonoTests.Helpers;
namespace MonoTests.System.ServiceModel.Dispatcher
{
[TestFixture]
public class ChannelDispatcherTest
{
[Test]
public void ConstructorNullBindingName ()
{
new ChannelDispatcher (new MyChannelListener (new Uri ("urn:foo")), null);
new ChannelDispatcher (new MyChannelListener (new Uri ("urn:foo")), null, null);
}
[Test]
public void ServiceThrottle ()
{
var cd = new ChannelDispatcher (new MyChannelListener<IReplyChannel> (new Uri ("urn:foo")));
var st = cd.ServiceThrottle;
Assert.IsNull (st, "#0");
var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
ServiceHost h = new ServiceHost (typeof (TestContract), uri);
h.AddServiceEndpoint (typeof (TestContract).FullName, new BasicHttpBinding (), "address");
h.ChannelDispatchers.Add (cd);
Assert.IsNull (st, "#1");
var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
Assert.IsNull (ed.ChannelDispatcher, "#1-2");
ed.DispatchRuntime.Type = typeof (TestContract);
cd.Endpoints.Add (ed);
Assert.AreEqual (cd, ed.ChannelDispatcher, "#1-3");
cd.MessageVersion = MessageVersion.Default;
{
cd.Open (TimeSpan.FromSeconds (10));
try {
Assert.IsNull (st, "#2");
// so, can't really test actual slot values as it is null.
} finally {
cd.Close (TimeSpan.FromSeconds (10));
}
return;
}
}
[Test]
public void Collection_Add_Remove () {
Console.WriteLine ("STart test Collection_Add_Remove");
var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
ServiceHost h = new ServiceHost (typeof (TestContract), uri);
h.AddServiceEndpoint (typeof (TestContract).FullName, new BasicHttpBinding (), "address");
MyChannelDispatcher d = new MyChannelDispatcher (new MyChannelListener (uri));
h.ChannelDispatchers.Add (d);
Assert.IsTrue (d.Attached, "#1");
h.ChannelDispatchers.Remove (d);
Assert.IsFalse (d.Attached, "#2");
h.ChannelDispatchers.Insert (0, d);
Assert.IsTrue (d.Attached, "#3");
h.ChannelDispatchers.Add (new MyChannelDispatcher (new MyChannelListener (uri)));
h.ChannelDispatchers.Clear ();
Assert.IsFalse (d.Attached, "#4");
}
[Test]
public void EndpointDispatcherAddTest ()
{
var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
MyChannelDispatcher d = new MyChannelDispatcher (new MyChannelListener (uri));
d.Endpoints.Add (new EndpointDispatcher (new EndpointAddress (uri), "", ""));
}
[Test]
[ExpectedException (typeof (InvalidOperationException))]
public void EndpointDispatcherAddTest2 () {
var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
MyChannelDispatcher d = new MyChannelDispatcher (new MyChannelListener (uri));
d.Endpoints.Add (new EndpointDispatcher (new EndpointAddress (uri), "", ""));
d.Open (); // the dispatcher must be attached.
}
[Test]
[ExpectedException (typeof (InvalidOperationException))]
public void EndpointDispatcherAddTest3 ()
{
var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
ServiceHost h = new ServiceHost (typeof (TestContract), uri);
MyChannelDispatcher d = new MyChannelDispatcher (new MyChannelListener (uri));
d.Endpoints.Add (new EndpointDispatcher (new EndpointAddress (uri), "", ""));
h.ChannelDispatchers.Add (d);
d.Open (); // missing MessageVersion
}
[Test]
[ExpectedException (typeof (InvalidOperationException))] // i.e. it is thrown synchronously in current thread.
public void EndpointDispatcherAddTest4 ()
{
var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
ServiceHost h = new ServiceHost (typeof (TestContract), uri);
var listener = new MyChannelListener (uri);
MyChannelDispatcher d = new MyChannelDispatcher (listener);
var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
Assert.IsNotNull (ed.DispatchRuntime, "#1");
Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#2");
Assert.IsNull (ed.DispatchRuntime.InstanceContextProvider, "#3");
Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#3.2");
Assert.IsNull (ed.DispatchRuntime.SingletonInstanceContext, "#4");
d.Endpoints.Add (ed);
d.MessageVersion = MessageVersion.Default;
h.ChannelDispatchers.Add (d);
// it misses DispatchRuntime.Type, which seems set
// automatically when the dispatcher is created in
// ordinal process but need to be set manually in this case.
try {
d.Open ();
try {
// should not reach here, but in case it didn't, it must be closed.
d.Close (TimeSpan.FromSeconds (10));
} catch {
}
} finally {
Assert.AreEqual (CommunicationState.Opened, listener.State, "#5");
}
}
[Test]
[ExpectedException (typeof (InvalidOperationException))] // i.e. it is thrown synchronously in current thread.
public void EndpointDispatcherAddTest5 ()
{
var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
ServiceHost h = new ServiceHost (typeof (TestContract), uri);
var binding = new BasicHttpBinding ();
var listener = new MyChannelListener (uri);
MyChannelDispatcher d = new MyChannelDispatcher (listener);
var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
d.Endpoints.Add (ed);
ed.DispatchRuntime.Type = typeof (TestContract); // different from Test4
d.MessageVersion = MessageVersion.Default;
h.ChannelDispatchers.Add (d);
// It rejects "unrecognized type" of the channel listener.
// Test6 uses IChannelListener<IReplyChannel> and works.
d.Open ();
// should not reach here, but in case it didn't, it must be closed.
d.Close (TimeSpan.FromSeconds (10));
}
[Test]
public void EndpointDispatcherAddTest6 ()
{
var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
ServiceHost h = new ServiceHost (typeof (TestContract), uri);
var binding = new BasicHttpBinding ();
var listener = new MyChannelListener<IReplyChannel> (uri);
MyChannelDispatcher d = new MyChannelDispatcher (listener);
var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
d.Endpoints.Add (ed);
Assert.IsFalse (d.Attached, "#x1");
ed.DispatchRuntime.Type = typeof (TestContract);
d.MessageVersion = MessageVersion.Default;
h.ChannelDispatchers.Add (d);
Assert.IsTrue (d.Attached, "#x2");
d.Open (); // At this state, it does *not* call AcceptChannel() yet.
Assert.IsFalse (listener.AcceptChannelTried, "#1");
Assert.IsFalse (listener.WaitForChannelTried, "#2");
Assert.IsNotNull (ed.DispatchRuntime, "#3");
Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#4");
Assert.IsNull (ed.DispatchRuntime.InstanceContextProvider, "#5"); // it is not still set after ChannelDispatcher.Open().
Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#5.2");
Assert.IsNull (ed.DispatchRuntime.SingletonInstanceContext, "#6");
d.Close (); // we don't have to even close it.
}
[Test]
[ExpectedException (typeof (InvalidOperationException))]
public void EndpointDispatcherAddTest7 ()
{
var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
ServiceHost h = new ServiceHost (typeof (TestContract), uri);
var binding = new BasicHttpBinding ();
var listener = new MyChannelListener<IReplyChannel> (uri);
MyChannelDispatcher d = new MyChannelDispatcher (listener);
var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
d.Endpoints.Add (ed);
ed.DispatchRuntime.Type = typeof (TestContract);
d.MessageVersion = MessageVersion.Default;
// add service endpoint to open the host (unlike all tests above).
h.AddServiceEndpoint (typeof (TestContract),
new BasicHttpBinding (), uri.ToString ());
h.ChannelDispatchers.Clear ();
h.ChannelDispatchers.Add (d);
d.Open (); // At this state, it does *not* call AcceptChannel() yet.
// This rejects already-opened ChannelDispatcher.
h.Open (TimeSpan.FromSeconds (10));
// should not reach here, but in case it didn't, it must be closed.
h.Close (TimeSpan.FromSeconds (10));
}
[Test]
[Category ("NotWorking")]
// Validating duplicate listen URI causes this regression.
// Since it is niche, I rather fixed ServiceHostBase to introduce validation.
// It is probably because this code doesn't use ServiceEndpoint to build IChannelListener i.e. built without Binding.
// We can add an extra field to ChannelDispatcher to indicate that it is from ServiceEndpoint (i.e. with Binding),
// but it makes little sense especially for checking duplicate listen URIs. Duplicate listen URIs should be rejected anyways.
public void EndpointDispatcherAddTest8 ()
{
var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
ServiceHost h = new ServiceHost (typeof (TestContract), uri);
var listener = new MyChannelListener<IReplyChannel> (uri);
MyChannelDispatcher d = new MyChannelDispatcher (listener);
var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
d.Endpoints.Add (ed);
ed.DispatchRuntime.Type = typeof (TestContract);
d.MessageVersion = MessageVersion.Default;
// add service endpoint to open the host (unlike all tests above).
h.AddServiceEndpoint (typeof (TestContract),
new BasicHttpBinding (), uri.ToString ());
h.ChannelDispatchers.Clear ();
h.ChannelDispatchers.Add (d);
Assert.AreEqual (h, d.Host, "#0");
try {
h.Open (TimeSpan.FromSeconds (10));
Assert.AreEqual (3, h.ChannelDispatchers.Count, "#0"); // TestContract, d, mex
Assert.IsTrue (listener.BeginAcceptChannelTried, "#1"); // while it throws NIE ...
Assert.IsFalse (listener.WaitForChannelTried, "#2");
Assert.IsNotNull (ed.DispatchRuntime, "#3");
Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#4");
Assert.IsNotNull (ed.DispatchRuntime.InstanceContextProvider, "#5"); // it was set after ServiceHost.Open().
Assert.IsNull (ed.DispatchRuntime.SingletonInstanceContext, "#6");
/*
var l = new HttpListener ();
l.Prefixes.Add (uri.ToString ());
l.Start ();
l.Stop ();
*/
} finally {
h.Close (TimeSpan.FromSeconds (10));
h.Abort ();
}
}
// FIXME: this test itself indeed passes, but some weird conflict that blocks correspoding port happens between this and somewhere (probably above)
// [Test]
public void EndpointDispatcherAddTest9 () // test singleton service
{
var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
ServiceHost h = new ServiceHost (new TestContract (), uri);
h.Description.Behaviors.Find<ServiceBehaviorAttribute> ().InstanceContextMode = InstanceContextMode.Single;
var listener = new MyChannelListener<IReplyChannel> (uri);
MyChannelDispatcher d = new MyChannelDispatcher (listener);
var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
d.Endpoints.Add (ed);
ed.DispatchRuntime.Type = typeof (TestContract);
d.MessageVersion = MessageVersion.Default;
h.AddServiceEndpoint (typeof (TestContract), new BasicHttpBinding (), uri.ToString ());
h.ChannelDispatchers.Clear ();
Assert.IsNull (ed.DispatchRuntime.SingletonInstanceContext, "#1");
h.ChannelDispatchers.Add (d);
Assert.IsNull (ed.DispatchRuntime.SingletonInstanceContext, "#2");
try {
h.Open (TimeSpan.FromSeconds (10));
Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#4");
Assert.IsNotNull (ed.DispatchRuntime.InstanceContextProvider, "#5"); // it was set after ServiceHost.Open().
Assert.IsNotNull (ed.DispatchRuntime.SingletonInstanceContext, "#6");
} finally {
h.Close (TimeSpan.FromSeconds (10));
h.Abort ();
}
}
[ServiceContract]
public class TestContract
{
[OperationContract]
public void Process (string input) {
}
}
class MyChannelDispatcher : ChannelDispatcher
{
public bool Attached = false;
public MyChannelDispatcher (IChannelListener l) : base (l) { }
protected override void Attach (ServiceHostBase host) {
base.Attach (host);
Attached = true;
}
protected override void Detach (ServiceHostBase host) {
base.Detach (host);
Attached = false;
}
}
class MyChannelListener<TChannel> : MyChannelListener, IChannelListener<TChannel> where TChannel : class, IChannel
{
public MyChannelListener (Uri uri)
: base (uri)
{
}
public bool AcceptChannelTried { get; set; }
public bool BeginAcceptChannelTried { get; set; }
public TChannel AcceptChannel ()
{
AcceptChannelTried = true;
throw new NotImplementedException ();
}
public TChannel AcceptChannel (TimeSpan timeout)
{
AcceptChannelTried = true;
throw new NotImplementedException ();
}
public IAsyncResult BeginAcceptChannel (AsyncCallback callback, object state)
{
BeginAcceptChannelTried = true;
throw new NotImplementedException ();
}
public IAsyncResult BeginAcceptChannel (TimeSpan timeout, AsyncCallback callback, object state)
{
BeginAcceptChannelTried = true;
throw new NotImplementedException ();
}
public TChannel EndAcceptChannel (IAsyncResult result)
{
throw new NotImplementedException ();
}
}
class MyChannelListener : IChannelListener
{
public MyChannelListener (Uri uri)
{
Uri = uri;
}
public bool WaitForChannelTried { get; set; }
public CommunicationState State { get; set; }
#region IChannelListener Members
public IAsyncResult BeginWaitForChannel (TimeSpan timeout, AsyncCallback callback, object state)
{
WaitForChannelTried = true;
throw new NotImplementedException ();
}
public bool EndWaitForChannel (IAsyncResult result)
{
throw new NotImplementedException ();
}
public T GetProperty<T> () where T : class
{
throw new NotImplementedException ();
}
public Uri Uri { get; set; }
public bool WaitForChannel (TimeSpan timeout)
{
WaitForChannelTried = true;
throw new NotImplementedException ();
}
#endregion
#region ICommunicationObject Members
public void Abort ()
{
State = CommunicationState.Closed;
}
public IAsyncResult BeginClose (TimeSpan timeout, AsyncCallback callback, object state) {
throw new NotImplementedException ();
}
public IAsyncResult BeginClose (AsyncCallback callback, object state) {
throw new NotImplementedException ();
}
public IAsyncResult BeginOpen (TimeSpan timeout, AsyncCallback callback, object state) {
throw new NotImplementedException ();
}
public IAsyncResult BeginOpen (AsyncCallback callback, object state) {
throw new NotImplementedException ();
}
public void Close (TimeSpan timeout)
{
State = CommunicationState.Closed;
}
public void Close ()
{
State = CommunicationState.Closed;
}
public event EventHandler Closed;
public event EventHandler Closing;
public void EndClose (IAsyncResult result) {
throw new NotImplementedException ();
}
public void EndOpen (IAsyncResult result) {
throw new NotImplementedException ();
}
public event EventHandler Faulted;
public void Open (TimeSpan timeout)
{
State = CommunicationState.Opened;
}
public void Open ()
{
State = CommunicationState.Opened;
}
public event EventHandler Opened;
public event EventHandler Opening;
#endregion
}
}
}
#endif