[tests] Avoid "Address already in use"
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel / ServiceHostBaseTest.cs
1 //
2 // ServiceHostBaseTest.cs
3 //
4 // Author:
5 //      Igor Zelmanovich <igorz@mainsoft.com>
6 //
7 // Copyright (C) 2008 Mainsoft, Inc.  http://www.mainsoft.com
8 //
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:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
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.
27 //
28
29 using System;
30 using System.Collections.Generic;
31 using System.Text;
32 using NUnit.Framework;
33 using System.ServiceModel;
34 using System.ServiceModel.Description;
35 using System.ServiceModel.Dispatcher;
36 using SMMessage = System.ServiceModel.Channels.Message;
37 using System.ServiceModel.Channels;
38
39 using MonoTests.Helpers;
40
41 namespace MonoTests.System.ServiceModel
42 {
43         [TestFixture]
44         public class ServiceHostBaseTest
45         {
46                 class Poker : ServiceHostBase
47                 {
48                         public event EventHandler OnApplyConfiguration;
49
50                         protected override ServiceDescription CreateDescription (out IDictionary<string, ContractDescription> implementedContracts) {
51                                 implementedContracts = new Dictionary<string, ContractDescription> ();
52                                 ServiceDescription description = new ServiceDescription ();
53                                 description.ServiceType = typeof (MyService);
54                                 description.Behaviors.Add (new ServiceBehaviorAttribute ());
55                                 return description;
56                         }
57
58                         protected override void ApplyConfiguration () {
59                                 if (OnApplyConfiguration != null)
60                                         OnApplyConfiguration (this, EventArgs.Empty);
61                                 base.ApplyConfiguration ();
62                         }
63
64                         public void CallInitializeDescription () {
65                                 InitializeDescription (new UriSchemeKeyedCollection ());
66                         }
67
68                         protected override void InitializeRuntime () {
69                                 base.InitializeRuntime ();
70                         }
71
72                         public void CallInitializeRuntime () {
73                                 InitializeRuntime ();
74                         }
75
76                         public void DoAddBaseAddress (Uri uri)
77                         {
78                                 AddBaseAddress (uri);
79                         }
80                 }
81
82                 [Test]
83                 public void Ctor () {
84                         Poker host = new Poker ();
85
86                         Assert.AreEqual (null, host.Description, "Description");
87                         Assert.AreEqual (null, host.Authorization, "Authorization");
88                 }
89
90                 [Test]
91                 public void DefaultConfiguration () {
92                         Poker host = new Poker ();
93                         host.OnApplyConfiguration += delegate (object sender, EventArgs e) {
94                                 Assert.AreEqual (1, host.Description.Behaviors.Count, "Description.Behaviors.Count #1");
95                         };
96                         host.CallInitializeDescription ();
97
98                         Assert.AreEqual (true, host.Description.Behaviors.Count > 1, "Description.Behaviors.Count #2");
99
100                         Assert.IsNotNull (host.Description.Behaviors.Find<ServiceDebugBehavior> (), "ServiceDebugBehavior");
101                         Assert.IsNotNull (host.Description.Behaviors.Find<ServiceAuthorizationBehavior> (), "ServiceDebugBehavior");
102                         Assert.IsNotNull (host.Authorization, "Authorization #1");
103
104                         Assert.AreEqual (host.Description.Behaviors.Find<ServiceAuthorizationBehavior> (), host.Authorization, "Authorization #2");
105                 }
106
107                 [Test]
108                 [ExpectedException (typeof (InvalidOperationException))]
109                 public void ApplyConfigurationNoDescription () {
110                         CustomServiceHost customHost = new CustomServiceHost ();
111                         customHost.ApplyConfiguration ();
112                 }
113
114                 class CustomServiceHost : ServiceHostBase
115                 {
116
117                         public CustomServiceHost () {
118
119                         }
120
121                         public new void ApplyConfiguration () {
122                                 base.ApplyConfiguration ();
123                         }
124
125                         protected override ServiceDescription CreateDescription (out IDictionary<string, ContractDescription> implementedContracts) {
126                                 throw new NotImplementedException ();
127                         }
128                 }
129
130                 [Test]
131                 public void InitializeRuntime () {
132                         Poker host = new Poker ();
133                         host.CallInitializeDescription ();
134                         EndpointAddress address = new EndpointAddress ("http://localhost:8090/");
135                         ContractDescription contract = ContractDescription.GetContract (typeof (IMyContract));
136                         ServiceEndpoint endpoint = new ServiceEndpoint (contract, new BasicHttpBinding (), address);
137                         endpoint.ListenUri = address.Uri;
138                         host.Description.Endpoints.Add (endpoint);
139
140                         Assert.AreEqual (0, host.ChannelDispatchers.Count, "ChannelDispatchers.Count #1");
141
142                         host.CallInitializeRuntime ();
143
144                         Assert.AreEqual (1, host.ChannelDispatchers.Count, "ChannelDispatchers.Count #1");
145                         Assert.AreEqual (CommunicationState.Created, host.ChannelDispatchers [0].State, "ChannelDispatchers.Count #1");
146                 }
147
148                 [ServiceContract]
149                 interface IMyContract
150                 {
151                         [OperationContract]
152                         string GetData ();
153                 }
154
155                 class MyService : IMyContract
156                 {
157                         public string GetData () {
158                                 return "Hello World";
159                         }
160                 }
161
162                 [Test]
163                 public void ChannelDispatchers_NoDebug () {
164                         var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
165                         ServiceHost h = new ServiceHost (typeof (AllActions), new Uri ("http://" + ep));
166                         h.AddServiceEndpoint (typeof (AllActions).FullName, new BasicHttpBinding (), "address");
167
168                         ServiceDebugBehavior b = h.Description.Behaviors.Find<ServiceDebugBehavior> ();
169                         b.HttpHelpPageEnabled = false;                                          
170
171                         h.Open ();
172                         try {
173                         Assert.AreEqual (h.ChannelDispatchers.Count, 1);
174                         ChannelDispatcher channelDispatcher =  h.ChannelDispatchers[0] as ChannelDispatcher;
175                         Assert.IsNotNull (channelDispatcher, "#1");
176                         Assert.IsTrue (channelDispatcher.Endpoints.Count == 1, "#2");
177                         EndpointAddressMessageFilter filter = channelDispatcher.Endpoints [0].AddressFilter as EndpointAddressMessageFilter;
178                         Assert.IsNotNull (filter, "#3");
179                         Assert.IsTrue (filter.Address.Equals (new EndpointAddress ("http://" + ep + "/address")), "#4");
180                         Assert.IsFalse (filter.IncludeHostNameInComparison, "#5");
181                         Assert.IsTrue (channelDispatcher.Endpoints [0].ContractFilter is MatchAllMessageFilter, "#6");
182                         } finally {
183                         h.Close ();
184                         }
185                 }
186
187                 [Test]
188                 public void ChannelDispatchers_WithDebug () {
189                         var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
190                         ServiceHost h = new ServiceHost (typeof (AllActions), new Uri ("http://" + ep));
191                         h.AddServiceEndpoint (typeof (AllActions).FullName, new BasicHttpBinding (), "address");
192                         ServiceMetadataBehavior b = new ServiceMetadataBehavior ();
193                         b.HttpGetEnabled = true;
194                         b.HttpGetUrl = new Uri( ep );
195                         h.Description.Behaviors.Add (b);
196                         h.Open ();
197
198                         Assert.AreEqual (h.ChannelDispatchers.Count, 2, "#1");
199                         ChannelDispatcher channelDispatcher = h.ChannelDispatchers[1] as ChannelDispatcher;
200                         Assert.IsNotNull (channelDispatcher, "#2");
201                         Assert.IsTrue (channelDispatcher.Endpoints.Count == 1, "#3");
202                         EndpointAddressMessageFilter filter = channelDispatcher.Endpoints [0].AddressFilter as EndpointAddressMessageFilter;
203                         Assert.IsNotNull (filter, "#4");
204                         Assert.IsTrue (filter.Address.Equals (new EndpointAddress ("http://" + ep)), "#5");
205                         Assert.IsFalse (filter.IncludeHostNameInComparison, "#6");
206                         Assert.IsTrue (channelDispatcher.Endpoints [0].ContractFilter is MatchAllMessageFilter, "#7");
207                         h.Close ();
208                 }
209
210                 [Test]
211                 public void SpecificActionTest ()
212                 {
213                         //EndpointDispatcher d = new EndpointDispatcher(
214                         var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
215                         ServiceHost h = new ServiceHost (typeof (SpecificAction), new Uri ("http://" + ep));
216                         h.AddServiceEndpoint (typeof (Action1Interface), new BasicHttpBinding (), "address");
217                                                 
218                         h.Open ();
219                         ChannelDispatcher d = h.ChannelDispatchers [0] as ChannelDispatcher;
220                         EndpointDispatcher ed = d.Endpoints [0] as EndpointDispatcher;
221                         ActionMessageFilter actionFilter = ed.ContractFilter as ActionMessageFilter;
222                         Assert.IsNotNull (actionFilter, "#1");
223                         Assert.IsTrue (actionFilter.Actions.Count == 1, "#2");
224                         h.Close();
225                 }
226
227                 [Test]
228                 public void InitializeRuntimeBehaviors1 () {
229                         HostState st = new HostState ();
230                         var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
231                         ServiceHost h = new ServiceHost (typeof (SpecificAction2), new Uri ("http://" + ep));
232                         h.AddServiceEndpoint (typeof (SpecificAction2), new BasicHttpBinding (), "temp");                       
233
234                         h.Description.Behaviors.Add (new MyServiceBehavior (st, h));
235
236                         h.Description.Endpoints [0].Behaviors.Add (new MyEndpointBehavior (st, h));
237                         h.Description.Endpoints [0].Contract.Behaviors.Add (new MyContractBehavior (st, h));
238                         h.Description.Endpoints [0].Contract.Operations [0].Behaviors.Add (new MyOperationBehavior (st, h));
239                         
240                         h.Open ();
241                         h.Close ();
242                         
243                         string expected = "Start, IServiceBehavior.Validate, IContractBehavior.Validate, IEndpointBehavior.Validate, IOperationBehavior.ApplyDispatchBehavior, IServiceBehavior.AddBindingParameters, IContractBehavior.AddBindingParameters, IEndpointBehavior.AddBindingParameters, IOperationBehavior.AddBindingParameters, IServiceBehavior.ApplyDispatchBehavior, IContractBehavior.ApplyDispatchBehavior, IEndpointBehavior.ApplyDispatchBehavior, IOperationBehavior.ApplyDispatchBehavior";
244                         Assert.AreEqual (expected, st.CurrentStage);
245                 }
246
247                 [Test]
248                 public void InitializeRuntimeBehaviors2 () {
249                         HostState st = new HostState ();
250                         var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
251                         ServiceHost h = new ServiceHost (typeof (SpecificAction), new Uri ("http://" + ep));
252                         h.AddServiceEndpoint (typeof (Action1Interface), new BasicHttpBinding (), "temp");
253                         h.AddServiceEndpoint (typeof (Action2Interface), new BasicHttpBinding (), "temp2");
254
255                         h.Description.Behaviors.Add (new MyServiceBehavior (st, h));                    
256                         
257                         h.Description.Endpoints [0].Behaviors.Add (new MyEndpointBehavior (st, h));
258                         h.Description.Endpoints [0].Contract.Behaviors.Add (new MyContractBehavior (st, h));
259                         h.Description.Endpoints [0].Contract.Operations [0].Behaviors.Add (new MyOperationBehavior (st, h));
260
261                         h.Description.Endpoints [1].Behaviors.Add (new MyEndpointBehavior (st, h));
262                         h.Description.Endpoints [1].Contract.Behaviors.Add (new MyContractBehavior (st, h));
263                         h.Description.Endpoints [1].Contract.Operations [0].Behaviors.Add (new MyOperationBehavior (st, h));
264                         h.Open ();
265                         h.Close ();
266
267                         string expected = "Start, IServiceBehavior.Validate, IContractBehavior.Validate, IEndpointBehavior.Validate, IOperationBehavior.ApplyDispatchBehavior, IContractBehavior.Validate, IEndpointBehavior.Validate, IOperationBehavior.ApplyDispatchBehavior, IServiceBehavior.AddBindingParameters, IContractBehavior.AddBindingParameters, IEndpointBehavior.AddBindingParameters, IOperationBehavior.AddBindingParameters, IServiceBehavior.AddBindingParameters, IContractBehavior.AddBindingParameters, IEndpointBehavior.AddBindingParameters, IOperationBehavior.AddBindingParameters, IServiceBehavior.ApplyDispatchBehavior, IContractBehavior.ApplyDispatchBehavior, IEndpointBehavior.ApplyDispatchBehavior, IOperationBehavior.ApplyDispatchBehavior, IContractBehavior.ApplyDispatchBehavior, IEndpointBehavior.ApplyDispatchBehavior, IOperationBehavior.ApplyDispatchBehavior";
268                         Assert.AreEqual (expected, st.CurrentStage);
269                 }
270
271                 [Test]
272                 public void AddBaseAddress ()
273                 {
274                         var host = new Poker ();
275                         Assert.AreEqual (0, host.BaseAddresses.Count, "#1");
276                         host.DoAddBaseAddress (new Uri ("http://localhost:37564"));
277                         Assert.AreEqual (1, host.BaseAddresses.Count, "#1");
278                         host.DoAddBaseAddress (new Uri ("net.tcp://localhost:893"));
279                         Assert.AreEqual (2, host.BaseAddresses.Count, "#1");
280                 }
281
282                 [Test]
283                 [ExpectedException (typeof (ArgumentException))]
284                 public void AddBaseAddress2 ()
285                 {
286                         var host = new Poker ();
287                         Assert.AreEqual (0, host.BaseAddresses.Count, "#1");
288                         host.DoAddBaseAddress (new Uri ("http://localhost:37564"));
289                         // http base address is already added.
290                         host.DoAddBaseAddress (new Uri ("http://localhost:893"));
291                 }
292
293                 [Test]
294                 public void AddServiceEndpointUri ()
295                 {
296                         var host = new ServiceHost (typeof (AllActions),
297                                 new Uri ("http://localhost:37564"));
298                         var se = host.AddServiceEndpoint (typeof (AllActions),
299                                 new BasicHttpBinding (), "foobar");
300                         Assert.AreEqual ("http://localhost:37564/foobar", se.Address.Uri.AbsoluteUri, "#1");
301                         Assert.AreEqual ("http://localhost:37564/foobar", se.ListenUri.AbsoluteUri, "#2");
302                 }
303
304                 [Test]
305                 public void AddServiceEndpointUri2 ()
306                 {
307                         var host = new ServiceHost (typeof (AllActions),
308                                 new Uri ("http://localhost:37564"));
309                         var se = host.AddServiceEndpoint (typeof (AllActions),
310                                 new BasicHttpBinding (), String.Empty);
311                         Assert.AreEqual ("http://localhost:37564/", se.Address.Uri.AbsoluteUri, "#1");
312                         Assert.AreEqual ("http://localhost:37564/", se.ListenUri.AbsoluteUri, "#2");
313                 }
314
315                 [Test]
316                 [ExpectedException (typeof (InvalidOperationException))]
317                 public void AddServiceEndpointOnlyMex ()
318                 {
319             var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
320                         var host = new ServiceHost (typeof (AllActions),
321                                 new Uri ("http://" + ep));
322                         host.Description.Behaviors.Add (new ServiceMetadataBehavior ());
323                         host.AddServiceEndpoint ("IMetadataExchange",
324                                 new BasicHttpBinding (), "/wsdl");
325                         host.Open ();
326                         try {
327                                 // to make sure that throwing IOE from here does not count.
328                                 host.Close ();
329                         } catch {
330                         }
331                         Assert.Fail ("should not open");
332                 }
333
334                 [Test]
335                 [Category ("NotWorking")] // Timeouts randomly #5813
336                 public void RunDestinationUnreachableTest ()
337                 {
338                         RunDestinationUnreachableTest ("BasicHttp", new BasicHttpBinding ());
339                 }
340
341                 [Test]
342                 [Category ("NotWorking")] // Timeouts randomly #5813
343                 public void RunDestinationUnreachableTest2 ()
344                 {
345                         RunDestinationUnreachableTest ("CustomSoap12", new CustomBinding (new HttpTransportBindingElement ()));
346                 }
347
348                 void RunDestinationUnreachableTest (string label, Binding binding)
349                 {
350                         string address = "http://" + NetworkHelpers.LocalEphemeralEndPoint().ToString();
351                         var host = OpenHost (address, binding);
352                         
353                         try {
354                                 var client = new DestinationUnreachableClient (binding, address);
355                                 client.NotImplementedOperation ();
356                                 Assert.Fail (label + " ActionNotSupportedException is expected");
357                         } catch (ActionNotSupportedException) {
358                                 // catching it instead of ExpectedException to distinguish errors at service side.
359                         } finally {
360                                 host.Close ();
361                         }
362                 }
363                 
364                 ServiceHost OpenHost (string address, Binding binding)
365                 {
366                         var baseAddresses = new Uri[] { new Uri(address) };
367
368                         var host = new ServiceHost (typeof (DummyService), baseAddresses);
369                         host.AddServiceEndpoint (typeof (IDummyService), binding, new Uri ("", UriKind.Relative));
370                         host.Open ();
371                         return host;
372                 }
373
374 #if NET_4_0
375                 [Test]
376                 public void AddServiceEndpoint_Directly ()
377                 {
378                         var host = new ServiceHost (typeof (DummyService));
379                         var address = new EndpointAddress ("http://localhost:30158");
380                         var binding = new BasicHttpBinding ();
381                         var contract = ContractDescription.GetContract (typeof (IDummyService));
382                         host.AddServiceEndpoint (new ServiceEndpoint (contract, binding, address));
383                 }
384
385                 [Test]
386                 [ExpectedException (typeof (ArgumentException))]
387                 public void AddServiceEndpoint_Directly_NullAddress ()
388                 {
389                         var host = new ServiceHost (typeof (DummyService));
390                         var binding = new BasicHttpBinding ();
391                         var contract = ContractDescription.GetContract (typeof (IDummyService));
392                         host.AddServiceEndpoint (new ServiceEndpoint (contract, binding, null));
393                 }
394
395                 [Test]
396                 [ExpectedException (typeof (ArgumentException))]
397                 public void AddServiceEndpoint_Directly_NullBinding ()
398                 {
399                         var host = new ServiceHost (typeof (DummyService));
400                         var address = new EndpointAddress ("http://localhost:30158");
401                         var contract = ContractDescription.GetContract (typeof (IDummyService));
402                         host.AddServiceEndpoint (new ServiceEndpoint (contract, null, address));
403                 }
404
405                 [Test]
406                 [ExpectedException (typeof (ArgumentException))]
407                 public void AddServiceMetadataEndpoint ()
408                 {
409                         var host = new ServiceHost (typeof (DummyService));
410                         host.AddServiceEndpoint (new ServiceMetadataEndpoint ());
411                 }
412
413                 [Test]
414                 [ExpectedException (typeof (InvalidOperationException))]
415                 public void AddServiceEndpoint_Directly_ContractMismatch ()
416                 {
417                         var host = new ServiceHost (typeof (DummyService));
418                         var address = new EndpointAddress ("http://localhost:30158");
419                         var binding = new BasicHttpBinding ();
420                         var contract = ContractDescription.GetContract (typeof (INotImplementedService));
421                         host.AddServiceEndpoint (new ServiceEndpoint (contract, binding, address));
422                 }
423 #endif
424
425                 #region helpers
426
427                 public enum Stage
428                 {
429                 }
430
431                 public class HostState
432                 {
433                         public string CurrentStage = "Start";
434                 }
435
436                 public class MyServiceBehavior : IServiceBehavior
437                 {
438                         #region IServiceBehavior Members
439
440                         HostState _state;
441                         ServiceHost _host;
442                         public MyServiceBehavior (HostState state, ServiceHost h) {
443                                 _state = state;
444                                 _host = h;
445                         }
446
447                         public void AddBindingParameters (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, global::System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) {                         
448                                 _state.CurrentStage += ", IServiceBehavior.AddBindingParameters";                               
449                                 bindingParameters.Add (this);
450                         }
451
452                         public void ApplyDispatchBehavior (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {                            
453                                 _state.CurrentStage += ", IServiceBehavior.ApplyDispatchBehavior";                              
454                         }
455
456                         public void Validate (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
457                                 _state.CurrentStage += ", IServiceBehavior.Validate";
458                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);
459                         }
460
461                         #endregion
462                 }
463
464                 public class MyEndpointBehavior : IEndpointBehavior
465                 {
466                         #region IEndpointBehavior Members
467                         HostState _state;
468                         ServiceHost _host;
469                         public MyEndpointBehavior (HostState state, ServiceHost h) {
470                                 _state = state;
471                                 _host = h;
472                         }
473
474                         public void AddBindingParameters (ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) {
475                                 Console.WriteLine ("IEndpointBehavior - AddBindingParameters " + _host.ChannelDispatchers.Count);
476                                 _state.CurrentStage += ", IEndpointBehavior.AddBindingParameters";                              
477                                 bindingParameters.Add (this);
478                         }
479
480                         public void ApplyClientBehavior (ServiceEndpoint endpoint, ClientRuntime clientRuntime) {
481                                 Console.WriteLine ("IEndpointBehavior - ApplyClientBehavior " + _host.ChannelDispatchers.Count);
482                         }
483
484                         public void ApplyDispatchBehavior (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) {
485                                 Console.WriteLine ("IEndpointBehavior - ApplyDispatchBehavior " + _host.ChannelDispatchers.Count);
486                                 _state.CurrentStage += ", IEndpointBehavior.ApplyDispatchBehavior";                             
487                         }
488
489                         public void Validate (ServiceEndpoint endpoint) {
490                                 Console.WriteLine ("IEndpointBehavior - Validate " + _host.ChannelDispatchers.Count);
491                                 _state.CurrentStage += ", IEndpointBehavior.Validate";
492                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);                            
493                         }
494
495                         #endregion
496                 }
497
498                 public class MyContractBehavior : IContractBehavior
499                 {
500                         #region IContractBehavior Members
501                         HostState _state;
502                         ServiceHost _host;
503                         public MyContractBehavior (HostState state, ServiceHost h) {
504                                 _state = state;
505                                 _host = h;
506                         }
507
508                         public void AddBindingParameters (ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) {
509                                 Console.WriteLine ("Contract - AddBindingParameters " + _host.ChannelDispatchers.Count);
510                                 _state.CurrentStage += ", IContractBehavior.AddBindingParameters";                              
511                                 bindingParameters.Add (this);
512                         }
513
514                         public void ApplyClientBehavior (ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) {
515                                 Console.WriteLine ("Contract - ApplyClientBehavior " + _host.ChannelDispatchers.Count);
516                         }
517
518                         public void ApplyDispatchBehavior (ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) {
519                                 Console.WriteLine ("Contract - ApplyDispatchBehavior " + _host.ChannelDispatchers.Count);
520                                 _state.CurrentStage += ", IContractBehavior.ApplyDispatchBehavior";                             
521                         }
522
523                         public void Validate (ContractDescription contractDescription, ServiceEndpoint endpoint) {
524                                 Console.WriteLine ("Contract - Validate " + _host.ChannelDispatchers.Count);
525                                 _state.CurrentStage += ", IContractBehavior.Validate";          
526                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);                            
527                         }
528
529                         #endregion
530                 }
531
532                 public class MyOperationBehavior : IOperationBehavior
533                 {
534                         #region IOperationBehavior Members
535                         HostState _state;
536                         ServiceHost _host;
537                         public MyOperationBehavior (HostState state, ServiceHost h) {
538                                 _state = state;
539                                 _host = h;
540                         }
541
542                         public void AddBindingParameters (OperationDescription operationDescription, BindingParameterCollection bindingParameters) {
543                                 Console.WriteLine ("IOperationBehavior - AddBindingParameters " + _host.ChannelDispatchers.Count);
544                                 _state.CurrentStage += ", IOperationBehavior.AddBindingParameters";                                     
545                                 bindingParameters.Add (this);
546                         }
547
548                         public void ApplyClientBehavior (OperationDescription operationDescription, ClientOperation clientOperation) {
549                                 Console.WriteLine ("IOperationBehavior - ApplyClientBehavior " + _host.ChannelDispatchers.Count);
550                         }
551
552                         public void ApplyDispatchBehavior (OperationDescription operationDescription, DispatchOperation dispatchOperation) {
553                                 Console.WriteLine ("IOperationBehavior - ApplyDispatchBehavior " + _host.ChannelDispatchers.Count);
554                                 _state.CurrentStage += ", IOperationBehavior.ApplyDispatchBehavior";                            
555                         }
556
557                         public void Validate (OperationDescription operationDescription) {
558                                 Console.WriteLine ("IOperationBehavior - Validate " + _host.ChannelDispatchers.Count);
559                                 _state.CurrentStage += ", IOperationBehavior.ApplyDispatchBehavior";
560                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);
561                         }
562
563                         #endregion
564                 }
565
566                 [ServiceContract]
567                 class AllActions
568                 {
569                         [OperationContract (Action = "*", ReplyAction = "*")]
570                         public SMMessage Get (SMMessage req) {
571                                 return null;
572                         }
573                 }
574
575                 [ServiceContract]
576                 interface Action1Interface
577                 {
578                         [OperationContract (Action = "Specific1", ReplyAction = "*")]
579                         SMMessage GetMessage1 (SMMessage req);
580                 }
581
582                 [ServiceContract]
583                 interface Action2Interface
584                 {
585                         [OperationContract (Action = "Specific2", ReplyAction = "*")]
586                         SMMessage GetMessage2 (SMMessage req);
587                 }
588                 
589                 class SpecificAction : Action1Interface, Action2Interface
590                 {                       
591                         public SMMessage GetMessage1 (SMMessage req) {
592                                 return null;
593                         }
594
595                         public SMMessage GetMessage2 (SMMessage req) {
596                                 return null;
597                         }
598                 }
599
600                 [ServiceContract]
601                 class SpecificAction2
602                 {
603                         [OperationContract (Action = "Specific", ReplyAction = "*")]
604                         public SMMessage GetMessage1 (SMMessage req) {
605                                 return null;
606                         }
607                 }
608
609                 class MyChannelDispatcher : ChannelDispatcher
610                 {
611                         public bool Attached = false;
612
613                         public MyChannelDispatcher (IChannelListener l) : base (l) { }
614                         protected override void Attach (ServiceHostBase host) {
615                                 base.Attach (host);
616                                 Attached = true;
617                         }
618                 }
619
620                 class MyChannelListener : IChannelListener
621                 {
622                         #region IChannelListener Members
623
624                         public IAsyncResult BeginWaitForChannel (TimeSpan timeout, AsyncCallback callback, object state) {
625                                 throw new NotImplementedException ();
626                         }
627
628                         public bool EndWaitForChannel (IAsyncResult result) {
629                                 throw new NotImplementedException ();
630                         }
631
632                         public T GetProperty<T> () where T : class {
633                                 throw new NotImplementedException ();
634                         }
635
636                         public Uri Uri {
637                                 get { throw new NotImplementedException (); }
638                         }
639
640                         public bool WaitForChannel (TimeSpan timeout) {
641                                 throw new NotImplementedException ();
642                         }
643
644                         #endregion
645
646                         #region ICommunicationObject Members
647
648                         public void Abort () {
649                                 throw new NotImplementedException ();
650                         }
651
652                         public IAsyncResult BeginClose (TimeSpan timeout, AsyncCallback callback, object state) {
653                                 throw new NotImplementedException ();
654                         }
655
656                         public IAsyncResult BeginClose (AsyncCallback callback, object state) {
657                                 throw new NotImplementedException ();
658                         }
659
660                         public IAsyncResult BeginOpen (TimeSpan timeout, AsyncCallback callback, object state) {
661                                 throw new NotImplementedException ();
662                         }
663
664                         public IAsyncResult BeginOpen (AsyncCallback callback, object state) {
665                                 throw new NotImplementedException ();
666                         }
667
668                         public void Close (TimeSpan timeout) {
669                                 throw new NotImplementedException ();
670                         }
671
672                         public void Close () {
673                                 throw new NotImplementedException ();
674                         }
675
676                         public event EventHandler Closed;
677
678                         public event EventHandler Closing;
679
680                         public void EndClose (IAsyncResult result) {
681                                 throw new NotImplementedException ();
682                         }
683
684                         public void EndOpen (IAsyncResult result) {
685                                 throw new NotImplementedException ();
686                         }
687
688                         public event EventHandler Faulted;
689
690                         public void Open (TimeSpan timeout) {
691                                 throw new NotImplementedException ();
692                         }
693
694                         public void Open () {
695                                 throw new NotImplementedException ();
696                         }
697
698                         public event EventHandler Opened;
699
700                         public event EventHandler Opening;
701
702                         public CommunicationState State {
703                                 get { throw new NotImplementedException (); }
704                         }
705
706                         #endregion
707                 }
708
709                 [ServiceContract]
710                 public interface IDummyService
711                 {
712                         [OperationContract]
713                         void DummyOperation ();
714                 }
715                 public class DummyService : IDummyService
716                 {
717                         public void DummyOperation ()
718                         {
719                                 // Do nothing
720                         }
721                 }
722                 [ServiceContract]
723                 public interface INotImplementedService
724                 {
725                         [OperationContract]
726                         void NotImplementedOperation ();
727                 }
728                 public class DestinationUnreachableClient : ClientBase<INotImplementedService>, INotImplementedService
729                 {
730                         public void NotImplementedOperation ()
731                         {
732                                 Channel.NotImplementedOperation ();
733                         }
734                 
735                         public DestinationUnreachableClient (Binding binding, string address) 
736                                 : base (binding, new EndpointAddress (address))
737                         {
738                         }
739                 }
740
741                 #endregion
742         }
743 }