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