Merge pull request #1886 from BrzVlad/fix-arm-thread-state
[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 = "http://" + NetworkHelpers.LocalEphemeralEndPoint().ToString();
165                         ServiceHost h = new ServiceHost (typeof (AllActions), new Uri (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 (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 = "http://" + NetworkHelpers.LocalEphemeralEndPoint().ToString();
190                         ServiceHost h = new ServiceHost (typeof (AllActions), new Uri (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 (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:" + NetworkHelpers.FindFreePort ()));
277                         Assert.AreEqual (1, host.BaseAddresses.Count, "#1");
278                         host.DoAddBaseAddress (new Uri ("net.tcp://localhost:" + NetworkHelpers.FindFreePort ()));
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:" + NetworkHelpers.FindFreePort ()));
289                         // http base address is already added.
290                         host.DoAddBaseAddress (new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ()));
291                 }
292
293                 [Test]
294                 public void AddServiceEndpointUri ()
295                 {
296                         int port = NetworkHelpers.FindFreePort ();
297                         var host = new ServiceHost (typeof (AllActions),
298                                 new Uri ("http://localhost:" + port));
299                         var se = host.AddServiceEndpoint (typeof (AllActions),
300                                 new BasicHttpBinding (), "foobar");
301                         Assert.AreEqual ("http://localhost:" + port + "/foobar", se.Address.Uri.AbsoluteUri, "#1");
302                         Assert.AreEqual ("http://localhost:" + port + "/foobar", se.ListenUri.AbsoluteUri, "#2");
303                 }
304
305                 [Test]
306                 public void AddServiceEndpointUri2 ()
307                 {
308                         int port = NetworkHelpers.FindFreePort ();
309                         var host = new ServiceHost (typeof (AllActions),
310                                 new Uri ("http://localhost:" + port));
311                         var se = host.AddServiceEndpoint (typeof (AllActions),
312                                 new BasicHttpBinding (), String.Empty);
313                         Assert.AreEqual ("http://localhost:" + port + "/", se.Address.Uri.AbsoluteUri, "#1");
314                         Assert.AreEqual ("http://localhost:" + port + "/", se.ListenUri.AbsoluteUri, "#2");
315                 }
316
317                 [Test]
318                 [ExpectedException (typeof (InvalidOperationException))]
319                 public void AddServiceEndpointOnlyMex ()
320                 {
321             var ep = NetworkHelpers.LocalEphemeralEndPoint().ToString();
322                         var host = new ServiceHost (typeof (AllActions),
323                                 new Uri ("http://" + ep));
324                         host.Description.Behaviors.Add (new ServiceMetadataBehavior ());
325                         host.AddServiceEndpoint ("IMetadataExchange",
326                                 new BasicHttpBinding (), "/wsdl");
327                         host.Open ();
328                         try {
329                                 // to make sure that throwing IOE from here does not count.
330                                 host.Close ();
331                         } catch {
332                         }
333                         Assert.Fail ("should not open");
334                 }
335
336                 [Test]
337                 [Category ("NotWorking")] // Timeouts randomly #5813
338                 public void RunDestinationUnreachableTest ()
339                 {
340                         RunDestinationUnreachableTest ("BasicHttp", new BasicHttpBinding ());
341                 }
342
343                 [Test]
344                 [Category ("NotWorking")] // Timeouts randomly #5813
345                 public void RunDestinationUnreachableTest2 ()
346                 {
347                         RunDestinationUnreachableTest ("CustomSoap12", new CustomBinding (new HttpTransportBindingElement ()));
348                 }
349
350                 void RunDestinationUnreachableTest (string label, Binding binding)
351                 {
352                         string address = "http://" + NetworkHelpers.LocalEphemeralEndPoint().ToString();
353                         var host = OpenHost (address, binding);
354                         
355                         try {
356                                 var client = new DestinationUnreachableClient (binding, address);
357                                 client.NotImplementedOperation ();
358                                 Assert.Fail (label + " ActionNotSupportedException is expected");
359                         } catch (ActionNotSupportedException) {
360                                 // catching it instead of ExpectedException to distinguish errors at service side.
361                         } finally {
362                                 host.Close ();
363                         }
364                 }
365                 
366                 ServiceHost OpenHost (string address, Binding binding)
367                 {
368                         var baseAddresses = new Uri[] { new Uri(address) };
369
370                         var host = new ServiceHost (typeof (DummyService), baseAddresses);
371                         host.AddServiceEndpoint (typeof (IDummyService), binding, new Uri ("", UriKind.Relative));
372                         host.Open ();
373                         return host;
374                 }
375
376 #if NET_4_0
377                 [Test]
378                 public void AddServiceEndpoint_Directly ()
379                 {
380                         var host = new ServiceHost (typeof (DummyService));
381                         var address = new EndpointAddress ("http://localhost:30158");
382                         var binding = new BasicHttpBinding ();
383                         var contract = ContractDescription.GetContract (typeof (IDummyService));
384                         host.AddServiceEndpoint (new ServiceEndpoint (contract, binding, address));
385                 }
386
387                 [Test]
388                 [ExpectedException (typeof (ArgumentException))]
389                 public void AddServiceEndpoint_Directly_NullAddress ()
390                 {
391                         var host = new ServiceHost (typeof (DummyService));
392                         var binding = new BasicHttpBinding ();
393                         var contract = ContractDescription.GetContract (typeof (IDummyService));
394                         host.AddServiceEndpoint (new ServiceEndpoint (contract, binding, null));
395                 }
396
397                 [Test]
398                 [ExpectedException (typeof (ArgumentException))]
399                 public void AddServiceEndpoint_Directly_NullBinding ()
400                 {
401                         var host = new ServiceHost (typeof (DummyService));
402                         var address = new EndpointAddress ("http://localhost:30158");
403                         var contract = ContractDescription.GetContract (typeof (IDummyService));
404                         host.AddServiceEndpoint (new ServiceEndpoint (contract, null, address));
405                 }
406
407                 [Test]
408                 [ExpectedException (typeof (ArgumentException))]
409                 public void AddServiceMetadataEndpoint ()
410                 {
411                         var host = new ServiceHost (typeof (DummyService));
412                         host.AddServiceEndpoint (new ServiceMetadataEndpoint ());
413                 }
414
415                 [Test]
416                 [ExpectedException (typeof (InvalidOperationException))]
417                 public void AddServiceEndpoint_Directly_ContractMismatch ()
418                 {
419                         var host = new ServiceHost (typeof (DummyService));
420                         var address = new EndpointAddress ("http://localhost:30158");
421                         var binding = new BasicHttpBinding ();
422                         var contract = ContractDescription.GetContract (typeof (INotImplementedService));
423                         host.AddServiceEndpoint (new ServiceEndpoint (contract, binding, address));
424                 }
425 #endif
426
427                 #region helpers
428
429                 public enum Stage
430                 {
431                 }
432
433                 public class HostState
434                 {
435                         public string CurrentStage = "Start";
436                 }
437
438                 public class MyServiceBehavior : IServiceBehavior
439                 {
440                         #region IServiceBehavior Members
441
442                         HostState _state;
443                         ServiceHost _host;
444                         public MyServiceBehavior (HostState state, ServiceHost h) {
445                                 _state = state;
446                                 _host = h;
447                         }
448
449                         public void AddBindingParameters (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, global::System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) {                         
450                                 _state.CurrentStage += ", IServiceBehavior.AddBindingParameters";                               
451                                 bindingParameters.Add (this);
452                         }
453
454                         public void ApplyDispatchBehavior (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {                            
455                                 _state.CurrentStage += ", IServiceBehavior.ApplyDispatchBehavior";                              
456                         }
457
458                         public void Validate (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
459                                 _state.CurrentStage += ", IServiceBehavior.Validate";
460                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);
461                         }
462
463                         #endregion
464                 }
465
466                 public class MyEndpointBehavior : IEndpointBehavior
467                 {
468                         #region IEndpointBehavior Members
469                         HostState _state;
470                         ServiceHost _host;
471                         public MyEndpointBehavior (HostState state, ServiceHost h) {
472                                 _state = state;
473                                 _host = h;
474                         }
475
476                         public void AddBindingParameters (ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) {
477                                 Console.WriteLine ("IEndpointBehavior - AddBindingParameters " + _host.ChannelDispatchers.Count);
478                                 _state.CurrentStage += ", IEndpointBehavior.AddBindingParameters";                              
479                                 bindingParameters.Add (this);
480                         }
481
482                         public void ApplyClientBehavior (ServiceEndpoint endpoint, ClientRuntime clientRuntime) {
483                                 Console.WriteLine ("IEndpointBehavior - ApplyClientBehavior " + _host.ChannelDispatchers.Count);
484                         }
485
486                         public void ApplyDispatchBehavior (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) {
487                                 Console.WriteLine ("IEndpointBehavior - ApplyDispatchBehavior " + _host.ChannelDispatchers.Count);
488                                 _state.CurrentStage += ", IEndpointBehavior.ApplyDispatchBehavior";                             
489                         }
490
491                         public void Validate (ServiceEndpoint endpoint) {
492                                 Console.WriteLine ("IEndpointBehavior - Validate " + _host.ChannelDispatchers.Count);
493                                 _state.CurrentStage += ", IEndpointBehavior.Validate";
494                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);                            
495                         }
496
497                         #endregion
498                 }
499
500                 public class MyContractBehavior : IContractBehavior
501                 {
502                         #region IContractBehavior Members
503                         HostState _state;
504                         ServiceHost _host;
505                         public MyContractBehavior (HostState state, ServiceHost h) {
506                                 _state = state;
507                                 _host = h;
508                         }
509
510                         public void AddBindingParameters (ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) {
511                                 Console.WriteLine ("Contract - AddBindingParameters " + _host.ChannelDispatchers.Count);
512                                 _state.CurrentStage += ", IContractBehavior.AddBindingParameters";                              
513                                 bindingParameters.Add (this);
514                         }
515
516                         public void ApplyClientBehavior (ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) {
517                                 Console.WriteLine ("Contract - ApplyClientBehavior " + _host.ChannelDispatchers.Count);
518                         }
519
520                         public void ApplyDispatchBehavior (ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) {
521                                 Console.WriteLine ("Contract - ApplyDispatchBehavior " + _host.ChannelDispatchers.Count);
522                                 _state.CurrentStage += ", IContractBehavior.ApplyDispatchBehavior";                             
523                         }
524
525                         public void Validate (ContractDescription contractDescription, ServiceEndpoint endpoint) {
526                                 Console.WriteLine ("Contract - Validate " + _host.ChannelDispatchers.Count);
527                                 _state.CurrentStage += ", IContractBehavior.Validate";          
528                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);                            
529                         }
530
531                         #endregion
532                 }
533
534                 public class MyOperationBehavior : IOperationBehavior
535                 {
536                         #region IOperationBehavior Members
537                         HostState _state;
538                         ServiceHost _host;
539                         public MyOperationBehavior (HostState state, ServiceHost h) {
540                                 _state = state;
541                                 _host = h;
542                         }
543
544                         public void AddBindingParameters (OperationDescription operationDescription, BindingParameterCollection bindingParameters) {
545                                 Console.WriteLine ("IOperationBehavior - AddBindingParameters " + _host.ChannelDispatchers.Count);
546                                 _state.CurrentStage += ", IOperationBehavior.AddBindingParameters";                                     
547                                 bindingParameters.Add (this);
548                         }
549
550                         public void ApplyClientBehavior (OperationDescription operationDescription, ClientOperation clientOperation) {
551                                 Console.WriteLine ("IOperationBehavior - ApplyClientBehavior " + _host.ChannelDispatchers.Count);
552                         }
553
554                         public void ApplyDispatchBehavior (OperationDescription operationDescription, DispatchOperation dispatchOperation) {
555                                 Console.WriteLine ("IOperationBehavior - ApplyDispatchBehavior " + _host.ChannelDispatchers.Count);
556                                 _state.CurrentStage += ", IOperationBehavior.ApplyDispatchBehavior";                            
557                         }
558
559                         public void Validate (OperationDescription operationDescription) {
560                                 Console.WriteLine ("IOperationBehavior - Validate " + _host.ChannelDispatchers.Count);
561                                 _state.CurrentStage += ", IOperationBehavior.ApplyDispatchBehavior";
562                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);
563                         }
564
565                         #endregion
566                 }
567
568                 [ServiceContract]
569                 class AllActions
570                 {
571                         [OperationContract (Action = "*", ReplyAction = "*")]
572                         public SMMessage Get (SMMessage req) {
573                                 return null;
574                         }
575                 }
576
577                 [ServiceContract]
578                 interface Action1Interface
579                 {
580                         [OperationContract (Action = "Specific1", ReplyAction = "*")]
581                         SMMessage GetMessage1 (SMMessage req);
582                 }
583
584                 [ServiceContract]
585                 interface Action2Interface
586                 {
587                         [OperationContract (Action = "Specific2", ReplyAction = "*")]
588                         SMMessage GetMessage2 (SMMessage req);
589                 }
590                 
591                 class SpecificAction : Action1Interface, Action2Interface
592                 {                       
593                         public SMMessage GetMessage1 (SMMessage req) {
594                                 return null;
595                         }
596
597                         public SMMessage GetMessage2 (SMMessage req) {
598                                 return null;
599                         }
600                 }
601
602                 [ServiceContract]
603                 class SpecificAction2
604                 {
605                         [OperationContract (Action = "Specific", ReplyAction = "*")]
606                         public SMMessage GetMessage1 (SMMessage req) {
607                                 return null;
608                         }
609                 }
610
611                 class MyChannelDispatcher : ChannelDispatcher
612                 {
613                         public bool Attached = false;
614
615                         public MyChannelDispatcher (IChannelListener l) : base (l) { }
616                         protected override void Attach (ServiceHostBase host) {
617                                 base.Attach (host);
618                                 Attached = true;
619                         }
620                 }
621
622                 class MyChannelListener : IChannelListener
623                 {
624                         #region IChannelListener Members
625
626                         public IAsyncResult BeginWaitForChannel (TimeSpan timeout, AsyncCallback callback, object state) {
627                                 throw new NotImplementedException ();
628                         }
629
630                         public bool EndWaitForChannel (IAsyncResult result) {
631                                 throw new NotImplementedException ();
632                         }
633
634                         public T GetProperty<T> () where T : class {
635                                 throw new NotImplementedException ();
636                         }
637
638                         public Uri Uri {
639                                 get { throw new NotImplementedException (); }
640                         }
641
642                         public bool WaitForChannel (TimeSpan timeout) {
643                                 throw new NotImplementedException ();
644                         }
645
646                         #endregion
647
648                         #region ICommunicationObject Members
649
650                         public void Abort () {
651                                 throw new NotImplementedException ();
652                         }
653
654                         public IAsyncResult BeginClose (TimeSpan timeout, AsyncCallback callback, object state) {
655                                 throw new NotImplementedException ();
656                         }
657
658                         public IAsyncResult BeginClose (AsyncCallback callback, object state) {
659                                 throw new NotImplementedException ();
660                         }
661
662                         public IAsyncResult BeginOpen (TimeSpan timeout, AsyncCallback callback, object state) {
663                                 throw new NotImplementedException ();
664                         }
665
666                         public IAsyncResult BeginOpen (AsyncCallback callback, object state) {
667                                 throw new NotImplementedException ();
668                         }
669
670                         public void Close (TimeSpan timeout) {
671                                 throw new NotImplementedException ();
672                         }
673
674                         public void Close () {
675                                 throw new NotImplementedException ();
676                         }
677
678                         public event EventHandler Closed;
679
680                         public event EventHandler Closing;
681
682                         public void EndClose (IAsyncResult result) {
683                                 throw new NotImplementedException ();
684                         }
685
686                         public void EndOpen (IAsyncResult result) {
687                                 throw new NotImplementedException ();
688                         }
689
690                         public event EventHandler Faulted;
691
692                         public void Open (TimeSpan timeout) {
693                                 throw new NotImplementedException ();
694                         }
695
696                         public void Open () {
697                                 throw new NotImplementedException ();
698                         }
699
700                         public event EventHandler Opened;
701
702                         public event EventHandler Opening;
703
704                         public CommunicationState State {
705                                 get { throw new NotImplementedException (); }
706                         }
707
708                         #endregion
709                 }
710
711                 [ServiceContract]
712                 public interface IDummyService
713                 {
714                         [OperationContract]
715                         void DummyOperation ();
716                 }
717                 public class DummyService : IDummyService
718                 {
719                         public void DummyOperation ()
720                         {
721                                 // Do nothing
722                         }
723                 }
724                 [ServiceContract]
725                 public interface INotImplementedService
726                 {
727                         [OperationContract]
728                         void NotImplementedOperation ();
729                 }
730                 public class DestinationUnreachableClient : ClientBase<INotImplementedService>, INotImplementedService
731                 {
732                         public void NotImplementedOperation ()
733                         {
734                                 Channel.NotImplementedOperation ();
735                         }
736                 
737                         public DestinationUnreachableClient (Binding binding, string address) 
738                                 : base (binding, new EndpointAddress (address))
739                         {
740                         }
741                 }
742
743                 #endregion
744         }
745 }