Merge branch 'bugfix-main-thread-root'
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel.Description / ContractDescriptionTest.cs
1 //
2 // ContractDescriptionTest.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.Linq;
31 using System.Net.Security;
32 using System.Reflection;
33 using System.ServiceModel;
34 using System.ServiceModel.Channels;
35 using System.ServiceModel.Description;
36 using NUnit.Framework;
37
38 namespace MonoTests.System.ServiceModel.Description
39 {
40         [TestFixture]
41         public class ContractDescriptionTest
42         {
43                 [Test]
44                 [ExpectedException (typeof (InvalidOperationException))]
45                 public void GetNonContract ()
46                 {
47                         ContractDescription cd = ContractDescription.GetContract (
48                                 typeof (object));
49                 }
50
51                 [Test]
52                 public void GetContract ()
53                 {
54                         InternalTestGetContract (
55                                 ContractDescription.GetContract (typeof (IFoo)));
56                 }
57
58                 [Test]
59                 public void GetContractParamRenamed ()
60                 {
61                         ContractDescription cd = ContractDescription.GetContract (typeof (IFooMsgParams));
62
63                         Assert.AreEqual (1, cd.Operations.Count, "Operation count");
64
65                         // Operation #1
66                         OperationDescription od = cd.Operations [0];
67
68                         ServiceAssert.AssertOperationDescription (
69                                 "MyFoo", null, null, 
70                                 typeof (IFooMsgParams).GetMethod ("Foo"),
71                                 true, false, false,
72                                 od, "MyFoo");
73
74                         // Operation #1 -> Message #1
75                         MessageDescription md = od.Messages [0];
76
77                         ServiceAssert.AssertMessageAndBodyDescription (
78                                 "http://tempuri.org/IFooMsgParams/MyFoo",
79                                 MessageDirection.Input,
80                                 null, "MyFoo", "http://tempuri.org/", false,
81                                 md, "MyFoo");
82
83                         ServiceAssert.AssertMessagePartDescription (
84                                 "MyParam", "http://tempuri.org/", 0, false,
85                                 ProtectionLevel.None, typeof (string), md.Body.Parts [0], "MyFoo.msg");
86
87                         md = od.Messages [1];
88
89                         ServiceAssert.AssertMessageAndBodyDescription (
90                                 "http://tempuri.org/IFooMsgParams/MyFooResponse",
91                                 MessageDirection.Output,
92                                 null, "MyFooResponse",
93                                 "http://tempuri.org/", true,
94                                 md, "MyFoo");
95
96                         ServiceAssert.AssertMessagePartDescription (
97                                 "MyResult", "http://tempuri.org/", 0, false,
98                                 ProtectionLevel.None, typeof (string), md.Body.ReturnValue, "MyResult ReturnValue");
99                 }
100
101                 [Test]
102                 public void GetContractConfigName ()
103                 {
104                         ContractDescription cd = ContractDescription.GetContract (typeof (ICtorUseCase2));
105                         Assert.AreEqual("CtorUseCase2", cd.ConfigurationName);
106                         Assert.AreEqual("ICtorUseCase2", cd.Name);
107                         cd = ContractDescription.GetContract (typeof (ICtorUseCase1));
108                         Assert.AreEqual("MonoTests.System.ServiceModel.ICtorUseCase1", cd.ConfigurationName);
109                         Assert.AreEqual("ICtorUseCase1", cd.Name);
110                 }
111
112                 [Test]
113                 public void GetContract2 ()
114                 {
115                         InternalTestGetContract (
116                                 ContractDescription.GetContract (typeof (Foo)));
117                 }
118
119                 public void InternalTestGetContract (ContractDescription cd)
120                 {
121                         ServiceAssert.AssertContractDescription (
122                                 "IFoo", "http://tempuri.org/", SessionMode.Allowed, typeof (IFoo), null,
123                                 cd, "contract");
124
125                         Assert.AreEqual (2, cd.Operations.Count, "Operation count");
126
127                         // Operation #1
128                         OperationDescription od = cd.Operations [0];
129
130                         ServiceAssert.AssertOperationDescription (
131                                 "HeyDude", null, null, 
132                                 typeof (IFoo).GetMethod ("HeyDude"),
133                                 true, false, false,
134                                 od, "HeyDude");
135
136                         // Operation #1 -> Message #1
137                         MessageDescription md = od.Messages [0];
138
139                         ServiceAssert.AssertMessageAndBodyDescription (
140                                 "http://tempuri.org/IFoo/HeyDude",
141                                 MessageDirection.Input,
142                                 null, "HeyDude", "http://tempuri.org/", false,
143                                 md, "HeyDude");
144
145                         ServiceAssert.AssertMessagePartDescription (
146                                 "msg", "http://tempuri.org/", 0, false,
147                                 ProtectionLevel.None, typeof (string), md.Body.Parts [0], "HeyDude.msg");
148                         ServiceAssert.AssertMessagePartDescription (
149                                 "msg2", "http://tempuri.org/", 1, false,
150                                 ProtectionLevel.None, typeof (string), md.Body.Parts [1], "HeyDude.msg");
151
152                         // Operation #1 -> Message #2
153                         md = od.Messages [1];
154
155                         ServiceAssert.AssertMessageAndBodyDescription (
156                                 "http://tempuri.org/IFoo/HeyDudeResponse",
157                                 MessageDirection.Output,
158                                 null, "HeyDudeResponse",
159                                 "http://tempuri.org/", true,
160                                 md, "HeyDude");
161
162                         ServiceAssert.AssertMessagePartDescription (
163                                 "HeyDudeResult", "http://tempuri.org/", 0, false,
164                                 ProtectionLevel.None, typeof (string), md.Body.ReturnValue, "HeyDudeResponse ReturnValue");
165
166                         // Operation #2
167                         od = cd.Operations [1];
168
169                         ServiceAssert.AssertOperationDescription (
170                                 "HeyHey", null, null,
171                                 typeof (IFoo).GetMethod ("HeyHey"),
172                                 true, false, false,
173                                 od, "HeyHey");
174
175                         // Operation #2 -> Message #1
176                         md = od.Messages [0];
177
178                         ServiceAssert.AssertMessageAndBodyDescription (
179                                 "http://tempuri.org/IFoo/HeyHey",
180                                 MessageDirection.Input,
181                                 null, "HeyHey", "http://tempuri.org/", false,
182                                 md, "HeyHey");
183
184                         ServiceAssert.AssertMessagePartDescription (
185                                 "ref1", "http://tempuri.org/", 0, false,
186                                 ProtectionLevel.None, typeof (string), md.Body.Parts [0], "HeyHey.ref1");
187
188                         // Operation #2 -> Message #2
189                         md = od.Messages [1];
190
191                         ServiceAssert.AssertMessageAndBodyDescription (
192                                 "http://tempuri.org/IFoo/HeyHeyResponse",
193                                 MessageDirection.Output,
194                                 null, "HeyHeyResponse",
195                                 "http://tempuri.org/", true,
196                                 md, "HeyHey");
197
198                         ServiceAssert.AssertMessagePartDescription (
199                                 "HeyHeyResult", "http://tempuri.org/", 0, false,
200                                 ProtectionLevel.None, typeof (void), md.Body.ReturnValue, "HeyHeyResponse ReturnValue");
201
202                         ServiceAssert.AssertMessagePartDescription (
203                                 "out1", "http://tempuri.org/", 0, false,
204                                 ProtectionLevel.None, typeof (string), md.Body.Parts [0], "HeyHey.out1");
205                         ServiceAssert.AssertMessagePartDescription (
206                                 "ref1", "http://tempuri.org/", 1, false,
207                                 ProtectionLevel.None, typeof (string), md.Body.Parts [1], "HeyHey.ref1");
208                 }
209
210                 [Test]
211                 public void GetContractInherit ()
212                 {
213                         ContractDescription.GetContract (typeof (Foo));
214                 }
215
216                 [Test]
217                 [ExpectedException (typeof (InvalidOperationException))]
218                 public void GetMultipleServiceContract ()
219                 {
220                         ContractDescription.GetContract (typeof (FooBar));
221                 }
222
223                 [Test]
224                 // [ExpectedException (typeof (InvalidOperationException))]
225                 public void GetContractNoOperation ()
226                 {
227                         ContractDescription.GetContract (typeof (INoOperation));
228                 }
229
230                 [Test]
231                 [Category ("NotWorking")]
232                 public void GetContractMessageParameter ()
233                 {
234                         ContractDescription cd = ContractDescription.GetContract (typeof (IMessageParameter));
235
236                         ServiceAssert.AssertContractDescription (
237                                 "IMessageParameter", "http://tempuri.org/", 
238                                 SessionMode.Allowed, typeof (IMessageParameter), null,
239                                 cd, "contract");
240
241                         OperationDescription od = cd.Operations [0];
242
243                         ServiceAssert.AssertOperationDescription (
244                                 "ReturnMessage", null, null, 
245                                 typeof (IMessageParameter).GetMethod ("ReturnMessage"),
246                                 true, false, false,
247                                 od, "operation");
248
249                         MessageDescription md = od.Messages [0];
250
251                         ServiceAssert.AssertMessageAndBodyDescription (
252                                 "http://tempuri.org/IMessageParameter/ReturnMessage",
253                                 MessageDirection.Input,
254                                 // Body.WrapperName is null
255                                 null, null, null, false,
256                                 md, "ReturnMessage");
257
258                         ServiceAssert.AssertMessagePartDescription (
259                                 "arg", "http://tempuri.org/", 0, false,
260                                 ProtectionLevel.None, typeof (Message), md.Body.Parts [0], "ReturnMessage input");
261                 }
262
263                 [Test]
264                 [ExpectedException (typeof (InvalidOperationException))]
265                 public void GetContractInvalidAsync ()
266                 {
267                         ContractDescription.GetContract (typeof (IInvalidAsync));
268                 }
269
270                 [Test]
271                 // IMetadataExchange contains async patterns.
272                 public void GetContractIMetadataExchange ()
273                 {
274                         ContractDescription cd = ContractDescription.GetContract (typeof (IMetadataExchange));
275                         OperationDescription od = cd.Operations [0];
276                         Assert.AreEqual (2, od.Messages.Count, "premise: message count");
277                         foreach (MessageDescription md in od.Messages) {
278                                 if (md.Direction == MessageDirection.Input) {
279                                         Assert.AreEqual ("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get", md.Action, "#1-1");
280                                         Assert.AreEqual (1, md.Body.Parts.Count, "#1-2");
281                                         Assert.IsNull (md.Body.ReturnValue, "#1-3");
282                                         Assert.AreEqual (typeof (Message), md.Body.Parts [0].Type, "#1-4");
283                                 } else {
284                                         Assert.AreEqual ("http://schemas.xmlsoap.org/ws/2004/09/transfer/GetResponse", md.Action, "#2-1");
285                                         Assert.AreEqual (0, md.Body.Parts.Count, "#2-2");
286                                         Assert.IsNotNull (md.Body.ReturnValue, "#2-3");
287                                         Assert.AreEqual (typeof (Message), md.Body.ReturnValue.Type, "#2-4");
288                                 }
289                         }
290                 }
291
292                 [Test]
293                 // enable it if we want to become a compatibility kid. It has
294                 // no ServiceContract, thus it should not be accepted. But
295                 // there is an abuse of ChannelFactory<IRequestChannel> in
296                 // MSDN documentations and probably examples.
297                 [Category ("NotWorking")]
298                 public void GetContractIRequestChannel ()
299                 {
300                         ContractDescription cd = ContractDescription.GetContract (typeof (IRequestChannel));
301                         Assert.AreEqual (typeof (IRequestChannel), cd.ContractType, "#_1");
302                         Assert.AreEqual ("IRequestChannel", cd.Name, "#_2");
303                         Assert.AreEqual ("http://schemas.microsoft.com/2005/07/ServiceModel", cd.Namespace, "#_3");
304                         Assert.AreEqual (false, cd.HasProtectionLevel, "#_4");
305                         Assert.AreEqual (SessionMode.NotAllowed, cd.SessionMode, "#_5");
306                         Assert.AreEqual (0, cd.Behaviors.Count, "#_6");
307                         Assert.AreEqual (1, cd.Operations.Count, "#_7");
308                         OperationDescription od = cd.Operations [0];
309                         Assert.IsNull (od.SyncMethod, "#_8");
310                         Assert.IsNull (od.BeginMethod, "#_9");
311                         Assert.IsNull (od.EndMethod, "#_10");
312                         Assert.AreEqual (false, od.IsOneWay, "#_11");
313                         Assert.AreEqual (false, od.HasProtectionLevel, "#_12");
314                         Assert.AreEqual ("Request", od.Name, "#_13");
315                         Assert.AreEqual (true, od.IsInitiating, "#_14");
316                         Assert.AreEqual (0, od.Behaviors.Count, "#_15");
317                         Assert.AreEqual (2, od.Messages.Count, "#_16");
318                         foreach (MessageDescription md in od.Messages) {
319                                 if (md.Direction == MessageDirection.Output) {
320                                         Assert.AreEqual ("*", md.Action, "#_17");
321                                         Assert.AreEqual (false, md.HasProtectionLevel, "#_18");
322                                         Assert.AreEqual (0, md.Headers.Count, "#_19");
323                                         Assert.AreEqual (0, md.Properties.Count, "#_20");
324                                         Assert.IsNull (md.MessageType, "#_21");
325                                         MessageBodyDescription mb = md.Body;
326                                         Assert.AreEqual (null, mb.WrapperName, "#_22");
327                                         Assert.AreEqual (null, mb.WrapperNamespace, "#_23");
328                                         Assert.IsNull (mb.ReturnValue, "#_24");
329                                         Assert.AreEqual (0, mb.Parts.Count, "#_25");
330                                 } else {
331                                         Assert.AreEqual ("*", md.Action, "#_17_");
332                                         Assert.AreEqual (false, md.HasProtectionLevel, "#_18_");
333                                         Assert.AreEqual (0, md.Headers.Count, "#_19_");
334                                         Assert.AreEqual (0, md.Properties.Count, "#_20_");
335                                         Assert.IsNull (md.MessageType, "#_21_");
336                                         MessageBodyDescription mb = md.Body;
337                                         Assert.AreEqual (null, mb.WrapperName, "#_22_");
338                                         Assert.AreEqual (null, mb.WrapperNamespace, "#_23_");
339                                         Assert.IsNull (mb.ReturnValue, "#_24_");
340                                         Assert.AreEqual (0, mb.Parts.Count, "#_25_");
341                                 }
342                         }
343                 }
344
345                 [Test]
346                 [ExpectedException (typeof (InvalidOperationException))]
347                 public void WrongAsyncEndContract ()
348                 {
349                         ContractDescription.GetContract (typeof (IWrongAsyncEndContract));
350                 }
351
352                 [Test]
353                 public void AsyncContract1 ()
354                 {
355                         ContractDescription cd =
356                                 ContractDescription.GetContract (typeof (IAsyncContract1));
357                         Assert.AreEqual (1, cd.Operations.Count);
358                         OperationDescription od = cd.Operations [0];
359                         Assert.AreEqual ("Sum", od.Name, "#1");
360                         Assert.IsNotNull (od.BeginMethod, "#2");
361                         Assert.IsNotNull (od.EndMethod, "#3");
362                 }
363
364                 [Test]
365                 [ExpectedException (typeof (InvalidOperationException))]
366                 public void DuplicateOperationNames ()
367                 {
368                         ContractDescription.GetContract (typeof (IDuplicateOperationNames));
369                 }
370
371                 [Test]
372                 [ExpectedException (typeof (InvalidOperationException))]
373                 public void AsyncMethodNameDoesNotStartWithBegin ()
374                 {
375                         ContractDescription.GetContract (typeof (IAsyncMethodNameDoesNotStartWithBegin));
376                 }
377
378                 [Test]
379                 [ExpectedException (typeof (InvalidOperationException))]
380                 public void AsyncNameDoesNotStartWithBeginButExplicitName ()
381                 {
382                         // it is still invalid ...
383                         ContractDescription.GetContract (typeof (IAsyncNameDoesNotStartWithBeginButExplicitName));
384                 }
385
386                 [Test]
387                 public void MessageBodyMemberIsNotInferred ()
388                 {
389                         ContractDescription cd = ContractDescription.GetContract (typeof (MessageBodyMemberIsNotInferredService));
390                         OperationDescription od = cd.Operations [0];
391                         MessageDescription md = od.Messages [0];
392                         Assert.AreEqual (0, md.Body.Parts.Count);
393                 }
394
395                 [Test]
396                 public void TestContractFromObject () {
397                         ContractDescription cd = ContractDescription.GetContract (typeof (Foo));
398                         ServiceAssert.AssertContractDescription (typeof (IFoo).Name, "http://tempuri.org/", SessionMode.Allowed, typeof (IFoo), null, cd, "#1");
399                         Assert.AreEqual (cd.Operations.Count, 2);
400                         OperationBehaviorAttribute op = cd.Operations.Find ("HeyHey").Behaviors.Find<OperationBehaviorAttribute> ();
401                         Assert.IsNotNull (op);
402                         Assert.AreEqual (
403                                 op.ReleaseInstanceMode,
404                                 ReleaseInstanceMode.None, "#2");
405
406                         cd = ContractDescription.GetContract (typeof (IFoo), typeof (Foo));
407                         ServiceAssert.AssertContractDescription (typeof (IFoo).Name, "http://tempuri.org/", SessionMode.Allowed, typeof (IFoo), null, cd, "#3");
408                         Assert.AreEqual (cd.Operations.Count, 2, "#4");
409                         Assert.AreEqual (
410                                 cd.Operations.Find ("HeyHey").Behaviors.Find<OperationBehaviorAttribute> ().ReleaseInstanceMode,
411                                 ReleaseInstanceMode.AfterCall, "#5");
412                 }
413
414                 [Test]
415                 public void GetDerivedContract ()
416                 {
417                         var cd = ContractDescription.GetContract (typeof (IFoo3));
418                         Assert.AreEqual (typeof (IFoo3), cd.ContractType, "#1");
419                         Assert.AreEqual (3, cd.Operations.Count, "#2");
420                         cd = ContractDescription.GetContract (typeof (Foo3));
421                         Assert.AreEqual (typeof (IFoo3), cd.ContractType, "#3");
422                         Assert.AreEqual (3, cd.Operations.Count, "#4");
423                 }
424                 
425                 [Test]
426                 public void MultipleContractsInTypeHierarchy ()
427                 {
428                         ContractDescription.GetContract (typeof (DuplicateCheckClassWrapper.ServiceInterface));
429
430                         var host = new ServiceHost (typeof (DuplicateCheckClassWrapper.DummyService)); // fine in MS, fails in Mono with "A contract cannot have two operations that have the identical names and different set of parameters"
431                 }
432
433                 [Test]
434                 public void GetInheritedContracts ()
435                 {
436                         var cd = ContractDescription.GetContract (typeof (IService));
437                         var ccd = cd.GetInheritedContracts ();
438                         Assert.AreEqual (1, ccd.Count, "#1");
439                         Assert.AreEqual (typeof (IServiceBase), ccd [0].ContractType, "#2");
440                 }
441
442                 [Test]
443                 public void InheritedContractAndNamespaces ()
444                 {
445                         var cd = ContractDescription.GetContract (typeof (IService));
446                         Assert.IsTrue (cd.Operations.Any (od => od.Messages.Any (md => md.Action == "http://tempuri.org/IServiceBase/Say")), "#1"); // inherited
447                         Assert.IsTrue (cd.Operations.Any (od => od.SyncMethod == typeof (IService).GetMethod ("Join") && od.Messages.Any (md => md.Action == "http://tempuri.org/IService/Join")), "#2"); // self
448                         Assert.IsTrue (cd.Operations.Any (od => od.SyncMethod == typeof (IService2).GetMethod ("Join") && od.Messages.Any (md => md.Action == "http://tempuri.org/IService/Join")), "#3"); // callback
449                 }
450
451                 // It is for testing attribute search in interfaces.
452                 public class Foo : IFoo
453                 {
454                         public string HeyDude (string msg, string msg2)
455                         {
456                                 return null;
457                         }
458
459                         [OperationBehavior (ReleaseInstanceMode = ReleaseInstanceMode.AfterCall)]
460                         public void HeyHey (out string out1, ref string ref1)
461                         {
462                                 out1 = null;
463                         }
464                 }
465
466                 // It inherits both IFoo and IBar, thus cannot be a contract.
467                 public class FooBar : IFoo, IBar
468                 {
469                         public string HeyDude (string msg, string msg2)
470                         {
471                                 return null;
472                         }
473                         
474                         public void HeyHey (out string out1, ref string ref1)
475                         {
476                                 out1 = null;
477                         }
478
479                         public void OpenBar () {}
480                 }
481
482                 [ServiceContract]
483                 public interface IFoo
484                 {
485                         [OperationContract]
486                         string HeyDude (string msg, string msg2);
487
488                         [OperationContract]
489                         void HeyHey (out string out1, ref string ref1);
490                 }
491
492                 [ServiceContract]
493                 public interface IFoo2
494                 {
495                         // FIXME: it does not pass yet
496                         [OperationContract]
497                         OregoMessage Nanoda (OregoMessage msg);
498
499                         // FIXME: it does not pass yet
500                         [OperationContract]
501                         OregoMessage Nanoda2 (OregoMessage msg1, OregoMessage msg2);
502
503                         // FIXME: it does not pass yet
504                         [OperationContract]
505                         Mona NewMona (Mona source);
506                 }
507
508                 [ServiceContract]
509                 public interface IFoo3 : IFoo
510                 {
511                         [OperationContract]
512                         string HeyMan (string msg, string msg2);
513                 }
514
515                 public class Foo3 : Foo, IFoo3
516                 {
517                         public string HeyMan (string msg, string msg2)
518                         {
519                                 return msg + msg2;
520                         }
521                 }
522
523                 [ServiceContract]
524                 public interface IBar
525                 {
526                         [OperationContract]
527                         void OpenBar ();
528                 }
529
530                 [MessageContract]
531                 public class OregoMessage
532                 {
533                         [MessageBodyMember]
534                         public string Neutral;
535                         [MessageBodyMember]
536                         public Assembly Huh;
537                         [MessageBodyMember] // it should be ignored ...
538                         public string Setter { set { } }
539                         public string NonMember;
540                 }
541
542                 public class Mona
543                 {
544                         public string OmaeMona;
545                         public string OreMona;
546                 }
547
548                 [ServiceContract]
549                 public interface INoOperation
550                 {
551                 }
552
553                 [ServiceContract]
554                 public interface IMessageParameter
555                 {
556                         [OperationContract]
557                         Message ReturnMessage (Message arg);
558                 }
559
560                 [ServiceContract]
561                 public interface IInvalidAsync
562                 {
563                         [OperationContract]
564                         Message ReturnMessage (Message arg);
565
566                         [OperationContract (AsyncPattern = true)]
567                         IAsyncResult BeginReturnMessage (Message arg, AsyncCallback callback, object state);
568
569                         // and no EndReturnMessage().
570                 }
571
572                 [ServiceContract]
573                 public interface IWrongAsyncEndContract
574                 {
575                         [OperationContract]
576                         int Sum (int a, int b);
577
578                         [OperationContract (AsyncPattern = true)]
579                         IAsyncResult BeginSum (int a, int b, AsyncCallback cb, object state);
580
581                         // this OperationContractAttribute is not allowed.
582                         [OperationContract (AsyncPattern = true)]
583                         int EndSum (IAsyncResult result);
584                 }
585
586                 [ServiceContract]
587                 public interface IAsyncContract1
588                 {
589                         [OperationContract]
590                         int Sum (int a, int b);
591
592                         [OperationContract (AsyncPattern = true)]
593                         IAsyncResult BeginSum (int a, int b, AsyncCallback cb, object state);
594
595                         int EndSum (IAsyncResult result);
596                 }
597
598                 [ServiceContract]
599                 public interface IAsyncMethodNameDoesNotStartWithBegin
600                 {
601                         [OperationContract]
602                         int Sum (int a, int b);
603
604                         [OperationContract (AsyncPattern = true)]
605                         IAsyncResult StartSum (int a, int b, AsyncCallback cb, object state);
606
607                         int EndSum (IAsyncResult result);
608                 }
609
610                 [ServiceContract]
611                 public interface IAsyncNameDoesNotStartWithBeginButExplicitName
612                 {
613                         [OperationContract]
614                         int Sum (int a, int b);
615
616                         [OperationContract (Name = "Sum", AsyncPattern = true)]
617                         IAsyncResult StartSum (int a, int b, AsyncCallback cb, object state);
618
619                         int EndSum (IAsyncResult result);
620                 }
621
622                 [ServiceContract]
623                 public interface IDuplicateOperationNames
624                 {
625                         [OperationContract]
626                         string Echo (string s);
627
628                         [OperationContract]
629                         string Echo (string s1, string s2);
630                 }
631
632                 [ServiceContract]
633                 public interface IFooMsgParams
634                 {
635                         [OperationContract (Name = "MyFoo")]
636                         [return: MessageParameter (Name = "MyResult")]
637                         string Foo ([MessageParameter (Name = "MyParam")] string param);
638                 }
639
640                 [ServiceContract]
641                 public class MessageBodyMemberIsNotInferredService
642                 {
643                         [OperationContract]
644                         public void Echo (MessageBodyMemberIsNotInferredContract msg)
645                         {
646                         }
647                 }
648
649                 [MessageContract]
650                 public class MessageBodyMemberIsNotInferredContract
651                 {
652                         string foo = "foo";
653                         public string Foo {
654                                 get { return foo; }
655                                 set { foo = value; }
656                         }
657                 }
658
659                 public class DuplicateCheckClassWrapper
660                 {
661
662                         [ServiceContract]
663                         internal interface ServiceInterface : Foo
664                         {
665                         }
666
667                         [ServiceContract]
668                         internal interface Foo : Bar
669                         {
670                                 [OperationContract] void Foo();
671                         }
672
673                         [ServiceContract]
674                         internal interface Bar
675                         {
676                                 [OperationContract] void FooBar();
677                         }
678
679                         internal class DummyService : ServiceInterface
680                         {
681                                 public void FooBar() { }
682
683                                 public void Foo() { }
684                         }
685                 }
686
687                 [ServiceContract]
688                 public interface IServiceBase
689                 {
690                         [OperationContract (IsOneWay = true)]
691                         void Say (string word);
692                 }
693
694                 [ServiceContract (CallbackContract = typeof (IService2))]
695                 public interface IService : IServiceBase
696                 {
697                         [OperationContract]
698                         void Join ();
699                 }
700
701                 [ServiceContract]
702                 public interface IServiceBase2
703                 {
704                         [OperationContract (IsOneWay = true)]
705                         void Say (string word);
706                 }
707
708                 [ServiceContract]
709                 public interface IService2 : IServiceBase2
710                 {
711                         [OperationContract]
712                         void Join ();
713                 }
714         }
715 }