using System.ServiceModel.Dispatcher;
using NUnit.Framework;
+using MonoTests.Helpers;
+
namespace MonoTests.System.ServiceModel
{
[TestFixture]
}
[Test]
- [Ignore ("AddServiceEndpoint part does not work")]
public void AddServiceEndpoint ()
{
ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
- host.AddServiceEndpoint ("IBar", new BasicHttpBinding (), "rel");
- host.AddServiceEndpoint ("IBar", new BasicHttpBinding (), "svc");
+ host.AddServiceEndpoint (typeof (Foo), new BasicHttpBinding (), "rel");
+ host.AddServiceEndpoint (typeof (Foo), new BasicHttpBinding (), "svc");
Assert.IsNotNull (host.Description, "#6");
Assert.IsNotNull (host.Description.Endpoints, "#7");
{
ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("ftp://localhost/echo"));
// ftp does not match BasicHttpBinding
- host.AddServiceEndpoint ("IBar", new BasicHttpBinding (), "rel");
+ host.AddServiceEndpoint (typeof (Foo), new BasicHttpBinding (), "rel");
}
[Test]
[ExpectedException (typeof (InvalidOperationException))]
public void AddServiceEndpoint2 ()
{
- // IBar is not part of the contract
ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
- host.AddServiceEndpoint ("IBar", new BasicHttpBinding (), "rel");
- //host.AddServiceEndpoint ("IBar", new BasicHttpBinding (), "rel");
+ host.AddServiceEndpoint (typeof (Foo), new BasicHttpBinding (), "rel");
+ host.AddServiceEndpoint (typeof (Foo), new BasicHttpBinding (), "rel"); // duplicate URI
+
+ host.Open ();
+ host.Close (); // should not reach here. It is to make sure to close unexpectedly opened host.
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void AddServiceEndpoint2_2 ()
+ {
+ ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
+ // same as above, but through Endpoints.Add()
+ host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (Foo)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo/rel")));
+ host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (Foo)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo/rel")));
+
+ host.Open ();
+ host.Close (); // should not reach here. It is to make sure to close unexpectedly opened host.
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void AddServiceEndpoint2_3 ()
+ {
+ ServiceHost host = new ServiceHost (typeof (HogeFuga), new Uri ("http://localhost/echo"));
+ host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (IHoge)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo")));
+ host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (IFuga)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo")));
+
+ // Different contracts unlike previous two cases.
+ // If two or more endpoints are bound to the same listen
+ // URI, then they must share the same instance.
+
+ host.Open ();
+ host.Close (); // should not reach here. It is to make sure to close unexpectedly opened host.
+ }
+
+ [Test]
+ public void AddServiceEndpoint2_4 ()
+ {
+ var ep = "http://" + NetworkHelpers.LocalEphemeralEndPoint().ToString();
+ ServiceHost host = new ServiceHost (typeof (HogeFuga), new Uri (ep));
+ var binding = new BasicHttpBinding ();
+ host.AddServiceEndpoint (typeof (IHoge), binding, new Uri (ep));
+ host.AddServiceEndpoint (typeof (IFuga), binding, new Uri (ep));
+
+ // Use the same binding, results in one ChannelDispatcher (actually two, for metadata/debug behavior).
+ host.Open ();
+ try {
+ Assert.AreEqual (2, host.ChannelDispatchers.Count, "#1");
+ foreach (ChannelDispatcher cd in host.ChannelDispatchers) {
+ if (cd.BindingName != binding.Name)
+ continue; // mex
+ Assert.AreEqual (2, cd.Endpoints.Count, "#2");
+ }
+ } finally {
+ host.Close ();
+ }
}
[Test]
[ExpectedException (typeof (InvalidOperationException))]
public void AddServiceEndpoint3 ()
{
- // IBar is not part of the contract
ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
- host.AddServiceEndpoint ("IBar", new BasicHttpBinding (), "rel");
- // host.AddServiceEndpoint ("IBar", new BasicHttpBinding (), "http://localhost/echo/rel");
+ host.AddServiceEndpoint (typeof (Foo), new BasicHttpBinding (), "rel");
+ host.AddServiceEndpoint (typeof (Foo), new BasicHttpBinding (), "http://localhost/echo/rel"); // duplicate URI when resolved
+
+ host.Open ();
+ host.Close (); // should not reach here. It is to make sure to close unexpectedly opened host.
+ }
+
+ [Test]
+ public void Open ()
+ {
+ ServiceHost host = new ServiceHost (typeof (ZeroOperationsImpl));
+ host.AddServiceEndpoint (typeof (IHaveZeroOperarationsContract), new BasicHttpBinding (), "http://localhost/echo");
+
+ try {
+ host.Open ();
+ Assert.Fail ("InvalidOperationException expected");
+ }
+ catch (InvalidOperationException e) {
+ //"ContractDescription 'IHaveZeroOperarationsContract' has zero operations; a contract must have at least one operation."
+ StringAssert.Contains ("IHaveZeroOperarationsContract", e.Message);
+ }
+ finally {
+ if (host.State == CommunicationState.Opened)
+ host.Close (); // It is to make sure to close unexpectedly opened host if the test fail.
+ }
}
[Test]
host.AddServiceEndpoint ("ISuchTypeDoesNotExist", new BasicHttpBinding (), "rel");
}
+ [Test]
+ public void AddServiceEndpoint7 ()
+ {
+ ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
+ var a = host.AddServiceEndpoint (typeof (Foo), new BasicHttpBinding (), "a");
+ Console.WriteLine (a.Address);
+ Assert.AreEqual ("http", a.Address.Uri.Scheme, "#1");
+ Assert.AreEqual ("http://localhost/echo/a", a.Address.Uri.AbsoluteUri, "#2");
+
+ var b = host.AddServiceEndpoint (typeof (Foo), new BasicHttpBinding (), "/b");
+ Console.WriteLine (b.Address);
+ Assert.AreEqual ("http", b.Address.Uri.Scheme, "#3");
+ Assert.AreEqual ("http://localhost/echo/b", b.Address.Uri.AbsoluteUri, "#4");
+ }
+
[Test]
[ExpectedException (typeof (InvalidOperationException))]
- public void AddServiceEndpointMex ()
+ public void AddServiceEndpointMexWithNoImpl ()
{
- using (ServiceHost h = new ServiceHost (typeof (Foo), new Uri ("http://localhost:8080"))) {
+ var port = NetworkHelpers.FindFreePort ();
+ using (ServiceHost h = new ServiceHost (typeof (Foo), new Uri ("http://localhost:" + port))) {
// it expects ServiceMetadataBehavior
h.AddServiceEndpoint (ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexHttpBinding (), "mex");
}
[Test]
public void AddServiceEndpointMetadataExchange ()
{
+ var port = NetworkHelpers.FindFreePort ();
+ // MyMetadataExchange implements IMetadataExchange
ServiceHost host = new ServiceHost (typeof (MyMetadataExchange));
- // strange, but unlike above, it is accepted. The only difference I can see is the binding name.
host.AddServiceEndpoint ("IMetadataExchange",
new BasicHttpBinding (),
- "http://localhost:8080");
+ "http://localhost:" + port + "/");
}
[Test]
[ExpectedException (typeof (InvalidOperationException))]
public void AddServiceEndpointMetadataExchangeFullNameFails ()
{
+ var port = NetworkHelpers.FindFreePort ();
ServiceHost host = new ServiceHost (typeof (MyMetadataExchange));
host.AddServiceEndpoint ("System.ServiceModel.Description.IMetadataExchange",
new BasicHttpBinding (),
- "http://localhost:8080");
+ "http://localhost:" + port);
}
[Test]
public void InstanceWithNonSingletonMode ()
{
+ var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
ServiceHost host = new ServiceHost (
new NonSingletonService ());
Assert.IsNotNull (host.Description.Behaviors.Find<ServiceBehaviorAttribute> ().GetWellKnownSingleton (), "premise1");
host.AddServiceEndpoint (
typeof (NonSingletonService),
new BasicHttpBinding (),
- new Uri ("http://localhost:37564/s1"));
+ new Uri ("http://" + ep + "/s1"));
// in case Open() didn't fail, we need to close the host.
// And even if Close() caused the expected exception,
[Test]
public void InstanceWithSingletonMode ()
{
+ var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
SingletonService instance = new SingletonService ();
ServiceHost host = new ServiceHost (instance);
Assert.IsNotNull (host.Description.Behaviors.Find<ServiceBehaviorAttribute> ().GetWellKnownSingleton (), "#1");
host.AddServiceEndpoint (
typeof (SingletonService),
new BasicHttpBinding (),
- new Uri ("http://localhost:37564/s2"));
+ new Uri ("http://" + ep + "/s2"));
// in case Open() didn't fail, we need to close the host.
// And even if Close() caused the expected exception,
}
}
+ [Test]
+ public void InstanceWithSingletonMode_InheritServiceBehavior ()
+ {
+ // # 37035
+
+ var ep = NetworkHelpers.LocalEphemeralEndPoint ().ToString ();
+
+ ChildSingletonService instance = new ChildSingletonService ();
+ ServiceHost host = new ServiceHost (instance);
+
+ host.AddServiceEndpoint (typeof (SingletonService),
+ new BasicHttpBinding (),
+ new Uri ("http://" + ep + "/s3"));
+
+ try {
+ host.Open ();
+ } catch (InvalidOperationException ex) {
+ Assert.Fail ("InstanceContextMode was not inherited from parent, exception was: {0}", ex);
+ } finally {
+ host.Close ();
+ }
+ }
+
[ServiceContract]
interface IBar
{
[OperationContract]
string Echo (string source);
}
+
+ [ServiceContract]
+ interface IHoge
+ {
+ [OperationContract]
+ void DoX ();
+ }
+
+ [ServiceContract]
+ interface IFuga
+ {
+ [OperationContract]
+ void DoY ();
+ }
+
+ [ServiceContract]
+ interface IHaveZeroOperarationsContract
+ {
+ string Echo (string source);
+ }
+
+ class ZeroOperationsImpl : IHaveZeroOperarationsContract
+ {
+ public string Echo(string source)
+ {
+ return null;
+ }
+ }
+
+ class HogeFuga : IHoge, IFuga
+ {
+ public void DoX () {}
+ public void DoY () {}
+ }
class Baz : IBaz
{
public class SingletonService
{
[OperationContract]
- public void Process (string input)
+ public virtual void Process (string input)
+ {
+ }
+ }
+
+ public class ChildSingletonService : SingletonService
+ {
+ public override void Process (string input)
{
}
}