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;
43 namespace MonoTests.System.ServiceModel
45 // FIXME: uncomment when NUnit tests on HTTP connection got as
46 // stable as non-nunit samples.
49 public class IntegratedConnectionTest
52 [Ignore ("With Orcas it does not work fine")]
53 // It is almost identical to samples/basic-http-binding
54 public void SimpleHttpConnection ()
57 ServiceHost host = new ServiceHost (typeof (Foo));
59 Binding binding = new BasicHttpBinding ();
60 binding.SendTimeout = binding.ReceiveTimeout = TimeSpan.FromSeconds (5);
61 ServiceEndpoint se = host.AddServiceEndpoint ("MonoTests.System.ServiceModel.IFoo",
62 binding, new Uri ("http://localhost:37564"));
66 ChannelFactory<IFoo> cf = new ChannelFactory<IFoo> (
67 new BasicHttpBinding (),
68 new EndpointAddress ("http://localhost:37564/"));
69 IFoo foo = cf.CreateChannel ();
70 Assert.AreEqual ("Test for EchoTest for Echo", foo.Echo ("Test for Echo"));
72 if (host.State == CommunicationState.Opened)
78 [Ignore ("With Orcas it does not work fine")]
79 public void SimpleClientBase ()
82 ServiceHost host = new ServiceHost (typeof (Foo2));
84 Binding binding = new BasicHttpBinding ();
85 binding.SendTimeout = binding.ReceiveTimeout = TimeSpan.FromSeconds (5);
86 host.AddServiceEndpoint ("MonoTests.System.ServiceModel.IFoo2",
87 binding, new Uri ("http://localhost:37564"));
91 Foo2Proxy proxy = new Foo2Proxy (
92 new BasicHttpBinding (),
93 new EndpointAddress ("http://localhost:37564/"));
96 Assert.AreEqual ("TEST FOR ECHOTEST FOR ECHO",
97 proxy.Echo ("TEST FOR ECHO"));
103 if (host.State == CommunicationState.Opened)
109 [Ignore ("With Orcas it does not work fine")]
110 public void ExchangeMetadata ()
113 ServiceHost host = new ServiceHost (typeof (MetadataExchange));
115 Binding binding = new BasicHttpBinding ();
116 binding.ReceiveTimeout = TimeSpan.FromSeconds (5);
117 host.AddServiceEndpoint ("IMetadataExchange",
118 binding, new Uri ("http://localhost:37564"));
122 MetadataExchangeProxy proxy = new MetadataExchangeProxy (
123 new BasicHttpBinding (),
124 new EndpointAddress ("http://localhost:37564/"));
128 Message req = Message.CreateMessage (MessageVersion.Soap11, "http://schemas.xmlsoap.org/ws/2004/09/transfer/Get");
129 Message res = proxy.Get (req);
135 if (host.State == CommunicationState.Opened)
140 [ServiceContract(SessionMode = SessionMode.Required)]
144 int GetInstanceCounter ();
147 [ServiceBehavior (InstanceContextMode = InstanceContextMode.PerSession)]
148 class Foo3 : IFoo3, IDisposable
150 public static int CreatedInstances { get; set; }
151 public static int DisposedInstances { get; set; }
153 public static int InstanceCounter {
154 get { return CreatedInstances - DisposedInstances; }
162 public int GetInstanceCounter ()
164 return InstanceCounter;
167 public virtual void Dispose ()
174 private void TestSessionbehaviour (Binding binding, Uri address)
176 ServiceHost host = new ServiceHost (typeof (Foo3), address);
177 host.AddServiceEndpoint (typeof (IFoo3), binding, address);
178 host.Description.Behaviors.Add (new ServiceThrottlingBehavior () { MaxConcurrentSessions = 1 });
179 Foo3.CreatedInstances = Foo3.DisposedInstances = 0; // Reset
181 Assert.AreEqual (0, Foo3.InstanceCounter, "Initial state wrong"); // just to be sure
182 var cd = (ChannelDispatcher) host.ChannelDispatchers [0];
183 for (int i = 1; i <= 3; ++i) {
184 var factory = new ChannelFactory<IFoo3Client> (binding, address.ToString ());
185 var proxy = factory.CreateChannel ();
186 Assert.AreEqual (1, proxy.GetInstanceCounter (), "One server instance after first call in session #" + i);
187 Assert.AreEqual (1, proxy.GetInstanceCounter (), "One server instance after second call in session #" + i);
188 factory.Close (); // should close session even when no IsTerminating method has been invoked
189 Thread.Sleep (500); // give WCF time to dispose service object
190 Assert.AreEqual (0, Foo3.InstanceCounter, "Service instances must be disposed after channel is closed, in session #" + i);
191 Assert.AreEqual (i, Foo3.CreatedInstances, "One new instance per session, in session #" + i);
196 interface IFoo3Client : IFoo3, IClientChannel {}
198 [Test (Description = "Tests InstanceContextMode.PerSession behavior for NetTcp binding")]
199 public void TestSessionInstancesNetTcp ()
201 Binding binding = new NetTcpBinding (SecurityMode.None, false);
202 Uri address = new Uri (binding.Scheme + "://localhost:9999/test");
203 TestSessionbehaviour (binding, address);
206 [Test (Description = "Tests InstanceContextMode.PerSession behavior for WsHttp binding")]
207 [Category ("NotWorking")] // no working WSHttpBinding in mono.
208 public void TestSessionInstancesWsHttp ()
210 Binding binding = new WSHttpBinding (SecurityMode.None, true);
211 Uri address = new Uri (binding.Scheme + "://localhost:9999/test");
212 TestSessionbehaviour(binding, address);
216 #region SimpleConnection classes
219 public interface IFoo
222 string Echo (string msg);
227 public string Echo (string msg)
233 // This is manually created type for strongly typed request.
234 [DataContract (Name = "Echo", Namespace = "http://tempuri.org/")]
235 public class EchoType
237 public EchoType (string msg)
243 public string msg = "test";
248 #region SampleClientBase classes
251 public interface IFoo2
254 string Echo (string msg);
259 public string Echo (string msg)
265 public class Foo2Proxy : ClientBase<IFoo2>, IFoo2
267 public Foo2Proxy (Binding binding, EndpointAddress address)
268 : base (binding, address)
272 public string Echo (string msg)
274 return Channel.Echo (msg);
280 #region ExchangeMetadata classes
282 class MetadataExchange : IMetadataExchange
284 public Message Get (Message request)
286 XmlDocument doc = new XmlDocument ();
287 doc.AppendChild (doc.CreateElement ("Metadata", "http://schemas.xmlsoap.org/ws/2004/09/mex"));
288 return Message.CreateMessage (request.Version,
289 "http://schemas.xmlsoap.org/ws/2004/09/transfer/GetResponse",
290 new XmlNodeReader (doc));
293 public IAsyncResult BeginGet (Message request, AsyncCallback cb, object state)
295 throw new NotImplementedException ();
298 public Message EndGet (IAsyncResult result)
300 throw new NotImplementedException ();
304 public class MetadataExchangeProxy : ClientBase<IMetadataExchange>, IMetadataExchange
306 public MetadataExchangeProxy (Binding binding, EndpointAddress address)
307 : base (binding, address)
311 public Message Get (Message request)
313 return Channel.Get (request);
316 public IAsyncResult BeginGet (Message request, AsyncCallback callback, object state)
318 throw new NotImplementedException ();
321 public Message EndGet (IAsyncResult result)
323 throw new NotImplementedException ();