New tests.
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel / CallbackBehaviorAttributeTest.cs
1 //
2 // CallbackBehaviorAttributeTest.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2009 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.IO;
31 using System.Net.Sockets;
32 using System.Reflection;
33 using System.ServiceModel;
34 using System.ServiceModel.Channels;
35 using System.ServiceModel.Description;
36 using System.ServiceModel.Dispatcher;
37 using System.Transactions;
38 using System.Threading;
39 using NUnit.Framework;
40
41 namespace MonoTests.System.ServiceModel
42 {
43         [TestFixture]
44         public class CallbackBehaviorAttributeTest
45         {
46                 [Test]
47                 public void DefaultValues ()
48                 {
49                         var c = new CallbackBehaviorAttribute ();
50                         Assert.IsTrue (c.AutomaticSessionShutdown, "#1");
51                         Assert.AreEqual (ConcurrencyMode.Single, c.ConcurrencyMode, "#2");
52                         Assert.IsFalse (c.IgnoreExtensionDataObject, "#3");
53                         Assert.IsFalse (c.IncludeExceptionDetailInFaults, "#4");
54                         Assert.AreEqual (0x10000, c.MaxItemsInObjectGraph, "#5");
55                         Assert.AreEqual (IsolationLevel.Unspecified, c.TransactionIsolationLevel, "#6");
56                         Assert.IsNull (c.TransactionTimeout, "#7");
57                         Assert.IsTrue (c.UseSynchronizationContext, "#8");
58                         Assert.IsTrue (c.ValidateMustUnderstand, "#9");
59                 }
60
61                 [Test]
62                 public void AddBindingParameters ()
63                 {
64                         IEndpointBehavior eb = new CallbackBehaviorAttribute ();
65                         var cd = ContractDescription.GetContract (typeof (IFoo));
66                         var se = new ServiceEndpoint (cd);
67                         Assert.AreEqual (0, se.Behaviors.Count, "#1");
68                         var pc = new BindingParameterCollection ();
69                         eb.AddBindingParameters (se, pc);
70                         Assert.AreEqual (0, pc.Count, "#2");
71                         Assert.AreEqual (0, se.Behaviors.Count, "#3");
72                 }
73
74                 [Test]
75                 [ExpectedException (typeof (InvalidOperationException))]
76                 public void ApplyDispatchBehavior ()
77                 {
78                         // It cannot be applied to service endpoint dispatcher.
79                         IEndpointBehavior eb = new CallbackBehaviorAttribute () { ConcurrencyMode = ConcurrencyMode.Multiple, ValidateMustUnderstand = false };
80                         var cd = ContractDescription.GetContract (typeof (IFoo));
81                         var se = new ServiceEndpoint (cd);
82                         var ed = new EndpointDispatcher (new EndpointAddress ("http://localhost:37564"), "IFoo", "urn:foo");
83                         eb.ApplyDispatchBehavior (se, ed);
84                 }
85
86                 [Test]
87                 [ExpectedException (typeof (InvalidOperationException))]
88                 public void ApplyClientBehaviorNonDuplex ()
89                 {
90                         // It must be applied to duplex callback runtime
91                         IEndpointBehavior eb = new CallbackBehaviorAttribute () { ConcurrencyMode = ConcurrencyMode.Multiple, ValidateMustUnderstand = false };
92                         var cd = ContractDescription.GetContract (typeof (IFoo));
93                         var se = new ServiceEndpoint (cd);
94                         var ed = new EndpointDispatcher (new EndpointAddress ("http://localhost:37564"), "IFoo", "urn:foo");
95                         var cr = ed.DispatchRuntime.CallbackClientRuntime;
96                         eb.ApplyClientBehavior (se, cr);
97                 }
98
99                 /* There is no way that I can create ClientRuntime instance ...
100                 [Test]
101                 public void ApplyClientBehavior ()
102                 {
103                         IEndpointBehavior eb = new CallbackBehaviorAttribute () { ConcurrencyMode = ConcurrencyMode.Multiple, ValidateMustUnderstand = false };
104                         var cd = ContractDescription.GetContract (typeof (IDuplexFoo));
105                         var se = new ServiceEndpoint (cd);
106                         var ed = new EndpointDispatcher (new EndpointAddress ("http://localhost:37564"), "IDuplexFoo", "urn:foo");
107                         var cr = ed.DispatchRuntime.CallbackClientRuntime;
108                         eb.ApplyClientBehavior (se, cr);
109                         Assert.IsFalse (cr.ValidateMustUnderstand, "#2.1");
110                         //Assert.IsFalse (cr.CallbackDispatchRuntime.ValidateMustUnderstand, "#2.2");
111                         Assert.AreEqual (1, se.Behaviors.Count, "#3");
112                 }
113                 */
114
115                 [ServiceContract]
116                 public interface IFoo
117                 {
118                         [OperationContract]
119                         string Join (string s1, string s2);
120                 }
121
122                 [ServiceContract (CallbackContract = typeof (IFoo))]
123                 public interface IDuplexFoo
124                 {
125                         [OperationContract]
126                         void Block (string s);
127                 }
128
129                 #region "bug #567672"
130                 [Test]
131                 public void CallbackExample1 ()
132                 {
133                         //Start service and use net.tcp binding
134                         ServiceHost eventServiceHost = new ServiceHost (typeof (GreetingsService));
135                         NetTcpBinding tcpBindingpublish = new NetTcpBinding ();
136                         tcpBindingpublish.Security.Mode = SecurityMode.None;
137                         eventServiceHost.AddServiceEndpoint (typeof (IGreetings), tcpBindingpublish, "net.tcp://localhost:8000/GreetingsService");
138                         eventServiceHost.Open ();
139
140                         //Create client proxy
141                         NetTcpBinding clientBinding = new NetTcpBinding ();
142                         clientBinding.Security.Mode = SecurityMode.None;
143                         EndpointAddress ep = new EndpointAddress ("net.tcp://localhost:8000/GreetingsService");
144                         ClientCallback cb = new ClientCallback ();
145                         IGreetings proxy = DuplexChannelFactory<IGreetings>.CreateChannel (new InstanceContext (cb), clientBinding, ep);
146
147                         //Call service
148                         proxy.SendMessage ();
149
150                         //Wait for callback - sort of hack, but better than using wait handle to possibly block tests.
151                         Thread.Sleep (1000);
152
153                         //Cleanup
154                         eventServiceHost.Close ();
155
156                         Assert.IsTrue (CallbackSent, "#1");
157                         Assert.IsTrue (CallbackReceived, "#2");
158                 }
159
160                 public static bool CallbackSent, CallbackReceived;
161
162                 //Service implementation
163                 [ServiceBehavior (ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
164                 public class GreetingsService : IGreetings
165                 {
166                         public void SendMessage ()
167                         {
168                                 //Make a callback
169                                 IGreetingsCallback clientCallback = OperationContext.Current.GetCallbackChannel<IGreetingsCallback> ();
170
171                                 clientCallback.ShowMessage ("Mono and WCF are GREAT!");
172                                 CallbackBehaviorAttributeTest.CallbackSent = true;
173                         }
174                 }
175
176                 // Client callback interface implementation
177                 [CallbackBehavior (ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
178                 public class ClientCallback : IGreetingsCallback
179                 {
180                         public void ShowMessage (string message)
181                         {
182                                 CallbackBehaviorAttributeTest.CallbackReceived = true;
183                         }
184                 }
185
186                 [ServiceContract (CallbackContract = typeof (IGreetingsCallback))]
187                 public interface IGreetings
188                 {
189                         [OperationContract (IsOneWay = true)]
190                         void SendMessage ();
191                 }
192
193                 [ServiceContract]
194                 public interface IGreetingsCallback
195                 {
196                         [OperationContract (IsOneWay = true)]
197                         void ShowMessage (string message);
198                 }
199                 #endregion
200         }
201 }