[tests] Avoid "Address already in use"
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel / ServiceHostBaseTest.cs
index 49b59cf4ab10e39f27dbbb9f4bd5a765fa9714fe..e77173068f00a6f7495415687997a62ddb4807b6 100644 (file)
@@ -36,6 +36,8 @@ using System.ServiceModel.Dispatcher;
 using SMMessage = System.ServiceModel.Channels.Message;
 using System.ServiceModel.Channels;
 
+using MonoTests.Helpers;
+
 namespace MonoTests.System.ServiceModel
 {
        [TestFixture]
@@ -159,32 +161,37 @@ namespace MonoTests.System.ServiceModel
 
                [Test]
                public void ChannelDispatchers_NoDebug () {
-                       ServiceHost h = new ServiceHost (typeof (AllActions), new Uri ("http://localhost:8080"));
+                       var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
+                       ServiceHost h = new ServiceHost (typeof (AllActions), new Uri ("http://" + ep));
                        h.AddServiceEndpoint (typeof (AllActions).FullName, new BasicHttpBinding (), "address");
 
                        ServiceDebugBehavior b = h.Description.Behaviors.Find<ServiceDebugBehavior> ();
                        b.HttpHelpPageEnabled = false;                                          
 
                        h.Open ();
+                       try {
                        Assert.AreEqual (h.ChannelDispatchers.Count, 1);
                        ChannelDispatcher channelDispatcher =  h.ChannelDispatchers[0] as ChannelDispatcher;
                        Assert.IsNotNull (channelDispatcher, "#1");
                        Assert.IsTrue (channelDispatcher.Endpoints.Count == 1, "#2");
                        EndpointAddressMessageFilter filter = channelDispatcher.Endpoints [0].AddressFilter as EndpointAddressMessageFilter;
                        Assert.IsNotNull (filter, "#3");
-                       Assert.IsTrue (filter.Address.Equals (new EndpointAddress ("http://localhost:8080/address")), "#4");
+                       Assert.IsTrue (filter.Address.Equals (new EndpointAddress ("http://" + ep + "/address")), "#4");
                        Assert.IsFalse (filter.IncludeHostNameInComparison, "#5");
                        Assert.IsTrue (channelDispatcher.Endpoints [0].ContractFilter is MatchAllMessageFilter, "#6");
+                       } finally {
                        h.Close ();
+                       }
                }
 
                [Test]
                public void ChannelDispatchers_WithDebug () {
-                       ServiceHost h = new ServiceHost (typeof (AllActions), new Uri ("http://localhost:8080"));
+                       var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
+                       ServiceHost h = new ServiceHost (typeof (AllActions), new Uri ("http://" + ep));
                        h.AddServiceEndpoint (typeof (AllActions).FullName, new BasicHttpBinding (), "address");
                        ServiceMetadataBehavior b = new ServiceMetadataBehavior ();
                        b.HttpGetEnabled = true;
-                       b.HttpGetUrl = new Uri( "http://localhost:8080" );
+                       b.HttpGetUrl = new Uri( ep );
                        h.Description.Behaviors.Add (b);
                        h.Open ();
 
@@ -194,7 +201,7 @@ namespace MonoTests.System.ServiceModel
                        Assert.IsTrue (channelDispatcher.Endpoints.Count == 1, "#3");
                        EndpointAddressMessageFilter filter = channelDispatcher.Endpoints [0].AddressFilter as EndpointAddressMessageFilter;
                        Assert.IsNotNull (filter, "#4");
-                       Assert.IsTrue (filter.Address.Equals (new EndpointAddress ("http://localhost:8080")), "#5");
+                       Assert.IsTrue (filter.Address.Equals (new EndpointAddress ("http://" + ep)), "#5");
                        Assert.IsFalse (filter.IncludeHostNameInComparison, "#6");
                        Assert.IsTrue (channelDispatcher.Endpoints [0].ContractFilter is MatchAllMessageFilter, "#7");
                        h.Close ();
@@ -204,7 +211,8 @@ namespace MonoTests.System.ServiceModel
                public void SpecificActionTest ()
                {
                        //EndpointDispatcher d = new EndpointDispatcher(
-                       ServiceHost h = new ServiceHost (typeof (SpecificAction), new Uri ("http://localhost:8080"));
+                       var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
+                       ServiceHost h = new ServiceHost (typeof (SpecificAction), new Uri ("http://" + ep));
                        h.AddServiceEndpoint (typeof (Action1Interface), new BasicHttpBinding (), "address");
                                                
                        h.Open ();
@@ -219,7 +227,8 @@ namespace MonoTests.System.ServiceModel
                [Test]
                public void InitializeRuntimeBehaviors1 () {
                        HostState st = new HostState ();
-                       ServiceHost h = new ServiceHost (typeof (SpecificAction2), new Uri ("http://localhost:8080"));
+                       var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
+                       ServiceHost h = new ServiceHost (typeof (SpecificAction2), new Uri ("http://" + ep));
                        h.AddServiceEndpoint (typeof (SpecificAction2), new BasicHttpBinding (), "temp");                       
 
                        h.Description.Behaviors.Add (new MyServiceBehavior (st, h));
@@ -238,7 +247,8 @@ namespace MonoTests.System.ServiceModel
                [Test]
                public void InitializeRuntimeBehaviors2 () {
                        HostState st = new HostState ();
-                       ServiceHost h = new ServiceHost (typeof (SpecificAction), new Uri ("http://localhost:8080"));
+                       var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
+                       ServiceHost h = new ServiceHost (typeof (SpecificAction), new Uri ("http://" + ep));
                        h.AddServiceEndpoint (typeof (Action1Interface), new BasicHttpBinding (), "temp");
                        h.AddServiceEndpoint (typeof (Action2Interface), new BasicHttpBinding (), "temp2");
 
@@ -286,7 +296,7 @@ namespace MonoTests.System.ServiceModel
                        var host = new ServiceHost (typeof (AllActions),
                                new Uri ("http://localhost:37564"));
                        var se = host.AddServiceEndpoint (typeof (AllActions),
-                               new BasicHttpBinding (), "/foobar");
+                               new BasicHttpBinding (), "foobar");
                        Assert.AreEqual ("http://localhost:37564/foobar", se.Address.Uri.AbsoluteUri, "#1");
                        Assert.AreEqual ("http://localhost:37564/foobar", se.ListenUri.AbsoluteUri, "#2");
                }
@@ -302,6 +312,116 @@ namespace MonoTests.System.ServiceModel
                        Assert.AreEqual ("http://localhost:37564/", se.ListenUri.AbsoluteUri, "#2");
                }
 
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void AddServiceEndpointOnlyMex ()
+               {
+            var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
+                       var host = new ServiceHost (typeof (AllActions),
+                               new Uri ("http://" + ep));
+                       host.Description.Behaviors.Add (new ServiceMetadataBehavior ());
+                       host.AddServiceEndpoint ("IMetadataExchange",
+                               new BasicHttpBinding (), "/wsdl");
+                       host.Open ();
+                       try {
+                               // to make sure that throwing IOE from here does not count.
+                               host.Close ();
+                       } catch {
+                       }
+                       Assert.Fail ("should not open");
+               }
+
+               [Test]
+               [Category ("NotWorking")] // Timeouts randomly #5813
+               public void RunDestinationUnreachableTest ()
+               {
+                       RunDestinationUnreachableTest ("BasicHttp", new BasicHttpBinding ());
+               }
+
+               [Test]
+               [Category ("NotWorking")] // Timeouts randomly #5813
+               public void RunDestinationUnreachableTest2 ()
+               {
+                       RunDestinationUnreachableTest ("CustomSoap12", new CustomBinding (new HttpTransportBindingElement ()));
+               }
+
+               void RunDestinationUnreachableTest (string label, Binding binding)
+               {
+                       string address = "http://" + NetworkHelpers.LocalEphemeralEndPoint().ToString();
+                       var host = OpenHost (address, binding);
+                       
+                       try {
+                               var client = new DestinationUnreachableClient (binding, address);
+                               client.NotImplementedOperation ();
+                               Assert.Fail (label + " ActionNotSupportedException is expected");
+                       } catch (ActionNotSupportedException) {
+                               // catching it instead of ExpectedException to distinguish errors at service side.
+                       } finally {
+                               host.Close ();
+                       }
+               }
+               
+               ServiceHost OpenHost (string address, Binding binding)
+               {
+                       var baseAddresses = new Uri[] { new Uri(address) };
+
+                       var host = new ServiceHost (typeof (DummyService), baseAddresses);
+                       host.AddServiceEndpoint (typeof (IDummyService), binding, new Uri ("", UriKind.Relative));
+                       host.Open ();
+                       return host;
+               }
+
+#if NET_4_0
+               [Test]
+               public void AddServiceEndpoint_Directly ()
+               {
+                       var host = new ServiceHost (typeof (DummyService));
+                       var address = new EndpointAddress ("http://localhost:30158");
+                       var binding = new BasicHttpBinding ();
+                       var contract = ContractDescription.GetContract (typeof (IDummyService));
+                       host.AddServiceEndpoint (new ServiceEndpoint (contract, binding, address));
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void AddServiceEndpoint_Directly_NullAddress ()
+               {
+                       var host = new ServiceHost (typeof (DummyService));
+                       var binding = new BasicHttpBinding ();
+                       var contract = ContractDescription.GetContract (typeof (IDummyService));
+                       host.AddServiceEndpoint (new ServiceEndpoint (contract, binding, null));
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void AddServiceEndpoint_Directly_NullBinding ()
+               {
+                       var host = new ServiceHost (typeof (DummyService));
+                       var address = new EndpointAddress ("http://localhost:30158");
+                       var contract = ContractDescription.GetContract (typeof (IDummyService));
+                       host.AddServiceEndpoint (new ServiceEndpoint (contract, null, address));
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void AddServiceMetadataEndpoint ()
+               {
+                       var host = new ServiceHost (typeof (DummyService));
+                       host.AddServiceEndpoint (new ServiceMetadataEndpoint ());
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void AddServiceEndpoint_Directly_ContractMismatch ()
+               {
+                       var host = new ServiceHost (typeof (DummyService));
+                       var address = new EndpointAddress ("http://localhost:30158");
+                       var binding = new BasicHttpBinding ();
+                       var contract = ContractDescription.GetContract (typeof (INotImplementedService));
+                       host.AddServiceEndpoint (new ServiceEndpoint (contract, binding, address));
+               }
+#endif
+
                #region helpers
 
                public enum Stage
@@ -585,7 +705,39 @@ namespace MonoTests.System.ServiceModel
 
                        #endregion
                }
-               #endregion
 
+               [ServiceContract]
+               public interface IDummyService
+               {
+                       [OperationContract]
+                       void DummyOperation ();
+               }
+               public class DummyService : IDummyService
+               {
+                       public void DummyOperation ()
+                       {
+                               // Do nothing
+                       }
+               }
+               [ServiceContract]
+               public interface INotImplementedService
+               {
+                       [OperationContract]
+                       void NotImplementedOperation ();
+               }
+               public class DestinationUnreachableClient : ClientBase<INotImplementedService>, INotImplementedService
+               {
+                       public void NotImplementedOperation ()
+                       {
+                               Channel.NotImplementedOperation ();
+                       }
+               
+                       public DestinationUnreachableClient (Binding binding, string address) 
+                               : base (binding, new EndpointAddress (address))
+                       {
+                       }
+               }
+
+               #endregion
        }
 }