2 // IntegratedConnectionTest.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2006 Novell, Inc. http://www.novell.com
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 using System.Collections.ObjectModel;
32 using System.Net.Security;
33 using System.Runtime.Serialization;
34 using System.ServiceModel;
35 using System.ServiceModel.Channels;
36 using System.ServiceModel.Description;
37 using System.ServiceModel.Dispatcher;
38 using System.Threading;
40 using NUnit.Framework;
42 using MonoTests.Helpers;
44 namespace MonoTests.System.ServiceModel
46 // FIXME: uncomment when NUnit tests on HTTP connection got as
47 // stable as non-nunit samples.
50 public class IntegratedConnectionTest
53 [Ignore ("With Orcas it does not work fine")]
54 // It is almost identical to samples/basic-http-binding
55 public void SimpleHttpConnection ()
58 ServiceHost host = new ServiceHost (typeof (Foo));
59 int port = NetworkHelpers.FindFreePort ();
61 Binding binding = new BasicHttpBinding ();
62 binding.SendTimeout = binding.ReceiveTimeout = TimeSpan.FromSeconds (5);
63 ServiceEndpoint se = host.AddServiceEndpoint ("MonoTests.System.ServiceModel.IFoo",
64 binding, new Uri ("http://localhost:" + port));
68 ChannelFactory<IFoo> cf = new ChannelFactory<IFoo> (
69 new BasicHttpBinding (),
70 new EndpointAddress ("http://localhost:" + port + "/"));
71 IFoo foo = cf.CreateChannel ();
72 Assert.AreEqual ("Test for EchoTest for Echo", foo.Echo ("Test for Echo"));
74 if (host.State == CommunicationState.Opened)
80 [Ignore ("With Orcas it does not work fine")]
81 public void SimpleClientBase ()
84 ServiceHost host = new ServiceHost (typeof (Foo2));
85 int port = NetworkHelpers.FindFreePort ();
87 Binding binding = new BasicHttpBinding ();
88 binding.SendTimeout = binding.ReceiveTimeout = TimeSpan.FromSeconds (5);
89 host.AddServiceEndpoint ("MonoTests.System.ServiceModel.IFoo2",
90 binding, new Uri ("http://localhost:" + port));
94 Foo2Proxy proxy = new Foo2Proxy (
95 new BasicHttpBinding (),
96 new EndpointAddress ("http://localhost:" + port + "/"));
99 Assert.AreEqual ("TEST FOR ECHOTEST FOR ECHO",
100 proxy.Echo ("TEST FOR ECHO"));
106 if (host.State == CommunicationState.Opened)
112 [Ignore ("With Orcas it does not work fine")]
113 public void ExchangeMetadata ()
116 ServiceHost host = new ServiceHost (typeof (MetadataExchange));
117 int port = NetworkHelpers.FindFreePort ();
119 Binding binding = new BasicHttpBinding ();
120 binding.ReceiveTimeout = TimeSpan.FromSeconds (5);
121 host.AddServiceEndpoint ("IMetadataExchange",
122 binding, new Uri ("http://localhost:" + port));
126 MetadataExchangeProxy proxy = new MetadataExchangeProxy (
127 new BasicHttpBinding (),
128 new EndpointAddress ("http://localhost:" + port + "/"));
132 Message req = Message.CreateMessage (MessageVersion.Soap11, "http://schemas.xmlsoap.org/ws/2004/09/transfer/Get");
133 Message res = proxy.Get (req);
139 if (host.State == CommunicationState.Opened)
144 [ServiceContract(SessionMode = SessionMode.Required)]
148 int GetInstanceCounter ();
151 [ServiceBehavior (InstanceContextMode = InstanceContextMode.PerSession)]
152 class Foo3 : IFoo3, IDisposable
154 public static int CreatedInstances { get; set; }
155 public static int DisposedInstances { get; set; }
157 public static int InstanceCounter {
158 get { return CreatedInstances - DisposedInstances; }
166 public int GetInstanceCounter ()
168 return InstanceCounter;
171 public virtual void Dispose ()
178 private void TestSessionbehaviour (Binding binding, Uri address)
180 ServiceHost host = new ServiceHost (typeof (Foo3), address);
181 host.AddServiceEndpoint (typeof (IFoo3), binding, address);
182 host.Description.Behaviors.Add (new ServiceThrottlingBehavior () { MaxConcurrentSessions = 1 });
183 Foo3.CreatedInstances = Foo3.DisposedInstances = 0; // Reset
185 Assert.AreEqual (0, Foo3.InstanceCounter, "Initial state wrong"); // just to be sure
186 var cd = (ChannelDispatcher) host.ChannelDispatchers [0];
187 for (int i = 1; i <= 3; ++i) {
188 var factory = new ChannelFactory<IFoo3Client> (binding, address.ToString ());
189 var proxy = factory.CreateChannel ();
190 Assert.AreEqual (1, proxy.GetInstanceCounter (), "One server instance after first call in session #" + i);
191 Assert.AreEqual (1, proxy.GetInstanceCounter (), "One server instance after second call in session #" + i);
192 factory.Close (); // should close session even when no IsTerminating method has been invoked
193 Thread.Sleep (500); // give WCF time to dispose service object
194 Assert.AreEqual (0, Foo3.InstanceCounter, "Service instances must be disposed after channel is closed, in session #" + i);
195 Assert.AreEqual (i, Foo3.CreatedInstances, "One new instance per session, in session #" + i);
200 interface IFoo3Client : IFoo3, IClientChannel {}
202 [Test (Description = "Tests InstanceContextMode.PerSession behavior for NetTcp binding")]
203 public void TestSessionInstancesNetTcp ()
205 Binding binding = new NetTcpBinding (SecurityMode.None, false);
206 Uri address = new Uri (binding.Scheme + "://localhost:9999/test");
207 TestSessionbehaviour (binding, address);
210 [Test (Description = "Tests InstanceContextMode.PerSession behavior for WsHttp binding")]
211 [Category ("NotWorking")] // no working WSHttpBinding in mono.
212 public void TestSessionInstancesWsHttp ()
214 Binding binding = new WSHttpBinding (SecurityMode.None, true);
215 Uri address = new Uri (binding.Scheme + "://localhost:9999/test");
216 TestSessionbehaviour(binding, address);
220 #region SimpleConnection classes
223 public interface IFoo
226 string Echo (string msg);
231 public string Echo (string msg)
237 // This is manually created type for strongly typed request.
238 [DataContract (Name = "Echo", Namespace = "http://tempuri.org/")]
239 public class EchoType
241 public EchoType (string msg)
247 public string msg = "test";
252 #region SampleClientBase classes
255 public interface IFoo2
258 string Echo (string msg);
263 public string Echo (string msg)
269 public class Foo2Proxy : ClientBase<IFoo2>, IFoo2
271 public Foo2Proxy (Binding binding, EndpointAddress address)
272 : base (binding, address)
276 public string Echo (string msg)
278 return Channel.Echo (msg);
284 #region ExchangeMetadata classes
286 class MetadataExchange : IMetadataExchange
288 public Message Get (Message request)
290 XmlDocument doc = new XmlDocument ();
291 doc.AppendChild (doc.CreateElement ("Metadata", "http://schemas.xmlsoap.org/ws/2004/09/mex"));
292 return Message.CreateMessage (request.Version,
293 "http://schemas.xmlsoap.org/ws/2004/09/transfer/GetResponse",
294 new XmlNodeReader (doc));
297 public IAsyncResult BeginGet (Message request, AsyncCallback cb, object state)
299 throw new NotImplementedException ();
302 public Message EndGet (IAsyncResult result)
304 throw new NotImplementedException ();
308 public class MetadataExchangeProxy : ClientBase<IMetadataExchange>, IMetadataExchange
310 public MetadataExchangeProxy (Binding binding, EndpointAddress address)
311 : base (binding, address)
315 public Message Get (Message request)
317 return Channel.Get (request);
320 public IAsyncResult BeginGet (Message request, AsyncCallback callback, object state)
322 throw new NotImplementedException ();
325 public Message EndGet (IAsyncResult result)
327 throw new NotImplementedException ();