do not check order sequence if option /order was not used
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel.Channels / CustomBindingTest.cs
1 //
2 // CustomBindingTest.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc.  http://www.novell.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 using System;
29 using System.Collections.ObjectModel;
30 using System.Net.Security;
31 using System.IdentityModel.Tokens;
32 using System.Runtime.Serialization;
33 using System.Security.Cryptography.X509Certificates;
34 using System.ServiceModel;
35 using System.ServiceModel.Channels;
36 using System.ServiceModel.Description;
37 using System.ServiceModel.Security;
38 using System.ServiceModel.Security.Tokens;
39 using System.Text;
40 using System.Xml;
41 using NUnit.Framework;
42
43 namespace MonoTests.System.ServiceModel.Channels
44 {
45         [TestFixture]
46         public class CustomBindingTest
47         {
48                 [Test]
49                 public void DefaultCtor ()
50                 {
51                         CustomBinding cb = new CustomBinding ();
52                         
53                         Assert.AreEqual (0, cb.Elements.Count, "#1");
54                         Assert.AreEqual ("CustomBinding", cb.Name, "#3");
55                         Assert.AreEqual ("http://tempuri.org/", cb.Namespace, "#4");
56                         Assert.AreEqual (TimeSpan.FromMinutes (1), cb.OpenTimeout, "#5");
57                         Assert.AreEqual (TimeSpan.FromMinutes (1), cb.CloseTimeout, "#6");
58                         Assert.AreEqual (TimeSpan.FromMinutes (1), cb.SendTimeout, "#7");
59                         Assert.AreEqual (TimeSpan.FromMinutes (10), cb.ReceiveTimeout, "#8");
60                         Assert.AreEqual (0, cb.CreateBindingElements ().Count, "#9");
61                 }
62
63                 class MyBinding : Binding
64                 {
65                         public override string Scheme { get { return "hoge"; } }
66
67                         public override BindingElementCollection CreateBindingElements ()
68                         {
69                                 throw new ApplicationException ("HEHE");
70                         }
71                 }
72
73                 [Test]
74                 public void CtorFromAnotherBinding ()
75                 {
76                         CustomBinding cb =
77                                 new CustomBinding (new WSHttpBinding ());
78                         // Its properties become mostly copy of the original one
79                         Assert.AreEqual (4, cb.Elements.Count, "#1");
80                         Assert.AreEqual ("http", cb.Scheme, "#2");
81                         Assert.AreEqual ("WSHttpBinding", cb.Name, "#3");
82                         Assert.AreEqual ("http://tempuri.org/", cb.Namespace, "#4");
83
84                         Assert.AreEqual (4, cb.CreateBindingElements ().Count, "#9");
85                 }
86
87                 [Test]
88                 public void MessageVersionProperty ()
89                 {
90                         Assert.IsNull (new CustomBinding ().MessageVersion, "#1");
91                         Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new CustomBinding (new HttpTransportBindingElement ()).MessageVersion, "#2");
92                         Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new CustomBinding (new TextMessageEncodingBindingElement ()).MessageVersion, "#3");
93                 }
94
95                 [Test]
96                 [ExpectedException (typeof (ApplicationException))]
97                 public void CtorFromAnotherBindingCallsCreateBindingElement ()
98                 {
99                         new CustomBinding (new MyBinding ());
100                 }
101
102                 Message reqmsg, resmsg;
103
104                 [Test]
105                 public void CustomTransportDoesNotRequireMessageEncoding ()
106                 {
107                         ReplyHandler replier = delegate (Message msg) {
108                                 resmsg = msg;
109                         };
110
111                         RequestReceiver receiver = delegate () {
112                                 return reqmsg;
113                         };
114
115                         RequestSender sender = delegate (Message msg) {
116                                 reqmsg = msg;
117
118                                 CustomBinding br = new CustomBinding (
119                                         new HandlerTransportBindingElement (replier, receiver));
120                                 IChannelListener<IReplyChannel> l =
121                                         br.BuildChannelListener<IReplyChannel> (
122                                                 new BindingParameterCollection ());
123                                 l.Open ();
124                                 IReplyChannel rch = l.AcceptChannel ();
125                                 rch.Open ();
126                                 Message res = Message.CreateMessage (MessageVersion.Default, "urn:succeeded");
127                                 rch.ReceiveRequest ().Reply (res);
128                                 rch.Close ();
129                                 l.Close ();
130
131                                 return resmsg;
132                         };
133
134                         CustomBinding bs = new CustomBinding (
135                                 new HandlerTransportBindingElement (sender));
136
137                         IChannelFactory<IRequestChannel> f =
138                                 bs.BuildChannelFactory<IRequestChannel> (
139                                         new BindingParameterCollection ());
140                         f.Open ();
141                         IRequestChannel ch = f.CreateChannel (new EndpointAddress ("urn:dummy"));
142                         ch.Open ();
143                         Message result = ch.Request (Message.CreateMessage (MessageVersion.Default, "urn:request"));
144                 }
145
146                 [Test]
147                 public void TransportBindingElementDefaultMessageVersion ()
148                 {
149                         Assert.AreEqual (MessageVersion.Soap12WSAddressing10, new HandlerTransportBindingElement (null).GetProperty<MessageVersion> (new BindingContext (new CustomBinding (), new BindingParameterCollection ())), "version");
150                 }
151
152                 [Test]
153                 [ExpectedException (typeof (InvalidOperationException))]
154                 //  Envelope Version 'EnvelopeNone (http://schemas.microsoft.com/ws/2005/05/envelope/none)'
155                 // does not support adding Message Headers.
156                 public void MessageSecurityPOX ()
157                 {
158                         SymmetricSecurityBindingElement sbe =
159                                 new SymmetricSecurityBindingElement ();
160                         sbe.ProtectionTokenParameters =
161                                 new X509SecurityTokenParameters ();
162                         RequestSender sender = delegate (Message input) {
163                                 MessageBuffer buf = input.CreateBufferedCopy (0x10000);
164                                 using (XmlWriter w = XmlWriter.Create (Console.Error)) {
165                                         buf.CreateMessage ().WriteMessage (w);
166                                 }
167                                 return buf.CreateMessage ();
168                         };
169
170                         CustomBinding binding = new CustomBinding (
171                                 sbe,
172                                 new TextMessageEncodingBindingElement (
173                                         MessageVersion.None, Encoding.UTF8),
174                                 new HandlerTransportBindingElement (sender));
175
176                         EndpointAddress address = new EndpointAddress (
177                                 new Uri ("http://localhost:37564"),
178                                 new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
179
180                         ChannelFactory<IRequestChannel> cf =
181                                 new ChannelFactory<IRequestChannel> (binding, address);
182                         IRequestChannel ch = cf.CreateChannel ();
183 /*
184                         // neither of Endpoint, Contract nor its Operation seems
185                         // to have applicable behaviors (except for
186                         // ClientCredentials)
187                         Assert.AreEqual (1, cf.Endpoint.Behaviors.Count, "EndpointBehavior");
188                         Assert.AreEqual (0, cf.Endpoint.Contract.Behaviors.Count, "ContractBehavior");
189                         Assert.AreEqual (1, cf.Endpoint.Contract.Operations.Count, "Operations");
190                         OperationDescription od = cf.Endpoint.Contract.Operations [0];
191                         Assert.AreEqual (0, od.Behaviors.Count, "OperationBehavior");
192 */
193
194                         ch.Open ();
195                         try {
196                                 ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction"));
197                         } finally {
198                                 ch.Close ();
199                         }
200                 }
201
202                 [Test]
203                 [Ignore ("it's underway")]
204                 [Category ("NotWorking")]
205                 public void MessageSecurityManualProtection ()
206                 {
207                         SymmetricSecurityBindingElement sbe =
208                                 new SymmetricSecurityBindingElement ();
209                         sbe.ProtectionTokenParameters =
210                                 new X509SecurityTokenParameters ();
211                         RequestSender sender = delegate (Message input) {
212                                 MessageBuffer buf = input.CreateBufferedCopy (0x10000);
213                                 using (XmlWriter w = XmlWriter.Create (Console.Error)) {
214                                         buf.CreateMessage ().WriteMessage (w);
215                                 }
216                                 return buf.CreateMessage ();
217                         };
218
219                         CustomBinding binding = new CustomBinding (
220                                 sbe,
221                                 new TextMessageEncodingBindingElement (),
222                                 new HandlerTransportBindingElement (sender));
223
224                         EndpointAddress address = new EndpointAddress (
225                                 new Uri ("http://localhost:37564"),
226                                 new X509CertificateEndpointIdentity (new X509Certificate2 ("Test/Resources/test.pfx", "mono")));
227
228                         ChannelProtectionRequirements reqs =
229                                 new ChannelProtectionRequirements ();
230                         reqs.OutgoingSignatureParts.AddParts (
231                                 new MessagePartSpecification (new XmlQualifiedName ("SampleValue", "urn:foo")), "urn:myaction");
232                         BindingParameterCollection parameters =
233                                 new BindingParameterCollection ();
234                         parameters.Add (reqs);
235 /*
236                         SymmetricSecurityBindingElement innersbe =
237                                 new SymmetricSecurityBindingElement ();
238                         innersbe.ProtectionTokenParameters =
239                                 new X509SecurityTokenParameters ();
240                         sbe.ProtectionTokenParameters =
241                                 new SecureConversationSecurityTokenParameters (
242                                         innersbe, false, reqs);
243 */
244
245                         IChannelFactory<IRequestChannel> cf =
246                                 binding.BuildChannelFactory<IRequestChannel> (parameters);
247                         cf.Open ();
248                         IRequestChannel ch = cf.CreateChannel (address);
249
250                         ch.Open ();
251                         try {
252                                 ch.Request (Message.CreateMessage (MessageVersion.None, "urn:myaction", new SampleValue ()));
253                         } finally {
254                                 ch.Close ();
255                         }
256                 }
257
258                 [Test]
259                 [ExpectedException (typeof (InvalidOperationException))]
260                 public void CanBuildChannelListenerNoTransport ()
261                 {
262                         CustomBinding cb = new CustomBinding ();
263                         BindingContext ctx = new BindingContext (
264                                 cb, new BindingParameterCollection ());
265                         Assert.IsFalse (new TextMessageEncodingBindingElement ().CanBuildChannelListener<IReplyChannel> (ctx), "#1");
266                 }
267
268                 [Test]
269                 [ExpectedException (typeof (InvalidOperationException))]
270                 public void BuildChannelListenerNoTransport ()
271                 {
272                         CustomBinding cb = new CustomBinding ();
273                         BindingContext ctx = new BindingContext (
274                                 cb, new BindingParameterCollection ());
275                         new TextMessageEncodingBindingElement ().BuildChannelListener<IReplyChannel> (ctx);
276                 }
277
278                 [Test]
279                 [ExpectedException (typeof (ArgumentException))]
280                 [Category ("NotWorking")]
281                 public void BuildChannelListenerWithDuplicateElement ()
282                 {
283                         CustomBinding cb = new CustomBinding (
284                                 new TextMessageEncodingBindingElement (),
285                                 new HttpTransportBindingElement ());
286                         BindingContext ctx = new BindingContext (
287                                 cb, new BindingParameterCollection (),
288                                 new Uri ("http://localhost:37564"), String.Empty, ListenUriMode.Unique);
289                         new TextMessageEncodingBindingElement ().BuildChannelListener<IReplyChannel> (ctx);
290                 }
291
292                 [Test]
293                 [ExpectedException (typeof (InvalidOperationException))]
294                 public void BuildChannelListenerWithNoMessageVersion ()
295                 {
296                         // MyBindingElement overrides GetProperty<T>() without calling GetInnerProperty<T>() and returns null in this case.
297                         // ServiceHost.Open() tries to get MessageVersion and raises an error if it cannot get any.
298                         // HttpTransportBindingElement can actually provide one.
299                         ServiceHost host = new ServiceHost (typeof (FooService));
300                         host.AddServiceEndpoint (typeof (IFooService),
301                                 new CustomBinding (new MyBindingElement (false), new HttpTransportBindingElement ()),
302                                 "http://localhost:37564");
303                         host.Open ();
304                 }
305
306                 [Test]
307                 [ExpectedException (typeof (MyException))]
308                 public void BuildChannelListenerWithMessageVersion ()
309                 {
310                         // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
311                         // HttpTransportBindingElement should return Soap11.
312                         ServiceHost host = new ServiceHost (typeof (FooService));
313                         host.AddServiceEndpoint (typeof (IFooService),
314                                 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
315                                 "http://localhost:37564");
316                         host.Open ();
317                         host.Close ();
318                 }
319
320                 [Test]
321                 [ExpectedException (typeof (InvalidOperationException))]
322                 public void RelativeListenUriNoBaseAddress ()
323                 {
324                         // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
325                         // HttpTransportBindingElement should return Soap11.
326                         ServiceHost host = new ServiceHost (typeof (FooService));
327                         host.AddServiceEndpoint (typeof (IFooService),
328                                 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
329                                 "http://localhost:37564", new Uri ("foobar", UriKind.Relative));
330                 }
331
332                 [Test]
333                 [ExpectedException (typeof (MyException))]
334                 public void RelativeListenUriWithBaseAddress ()
335                 {
336                         // MyBindingElement overrides GetProperty<T>() to call GetInnerProperty<T>() (default implementation).
337                         // HttpTransportBindingElement should return Soap11.
338                         ServiceHost host = new ServiceHost (typeof (FooService), new Uri ("http://localhost:37564"));
339                         host.AddServiceEndpoint (typeof (IFooService),
340                                 new CustomBinding (new MyBindingElement (true), new HttpTransportBindingElement ()),
341                                 "http://localhost:37564", new Uri ("foobar", UriKind.Relative));
342                         host.Open ();
343                         host.Close ();
344                 }
345                 
346                 [ServiceContract]
347                 public interface IFooService
348                 {
349                         [OperationContract]
350                         string Hello (string msg);
351                 }
352                 public class FooService : IFooService
353                 {
354                         public string Hello (string msg)
355                         {
356                                 return "hello";
357                         }
358                 }
359
360                 class MyBindingElement : BindingElement
361                 {
362                         public MyBindingElement (bool returnProperty)
363                         {
364                                 return_property = returnProperty;
365                         }
366                         
367                         bool return_property;
368
369                         public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (
370                                 BindingContext ctx)
371                         {
372                                 throw new NotImplementedException ();
373                         }
374
375                         public override IChannelListener<TChannel> BuildChannelListener<TChannel> (
376                                 BindingContext ctx)
377                         {
378                                 throw new MyException ();
379                         }
380
381                         public override bool CanBuildChannelListener<TChannel> (BindingContext ctx)
382                         {
383                                 return true;
384                         }
385
386                         public override BindingElement Clone ()
387                         {
388                                 return new MyBindingElement (return_property);
389                         }
390
391                         public override T GetProperty<T> (BindingContext context)
392                         {
393                                 return return_property ? context.GetInnerProperty<T> () : null;
394                         }
395                 }
396                 
397                 public class MyException : Exception
398                 {
399                 }
400         }
401
402         [DataContract (Namespace = "urn:foo")]
403         class SampleValue
404         {
405         }
406 }