2 // CallbackBehaviorAttributeTest.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2009 Novell, Inc. http://www.novell.com
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 using System.Collections.ObjectModel;
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;
41 namespace MonoTests.System.ServiceModel
44 public class CallbackBehaviorAttributeTest
47 public void DefaultValues ()
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");
62 public void AddBindingParameters ()
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");
75 [ExpectedException (typeof (InvalidOperationException))]
76 public void ApplyDispatchBehavior ()
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);
87 [ExpectedException (typeof (InvalidOperationException))]
88 public void ApplyClientBehaviorNonDuplex ()
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);
99 /* There is no way that I can create ClientRuntime instance ...
101 public void ApplyClientBehavior ()
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");
116 public interface IFoo
119 string Join (string s1, string s2);
122 [ServiceContract (CallbackContract = typeof (IFoo))]
123 public interface IDuplexFoo
126 void Block (string s);
129 #region "bug #567672"
131 public void CallbackExample1 ()
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 ();
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);
148 proxy.SendMessage ();
150 //Wait for callback - sort of hack, but better than using wait handle to possibly block tests.
154 eventServiceHost.Close ();
156 Assert.IsTrue (CallbackSent, "#1");
157 Assert.IsTrue (CallbackReceived, "#2");
160 public static bool CallbackSent, CallbackReceived;
162 //Service implementation
163 [ServiceBehavior (ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
164 public class GreetingsService : IGreetings
166 public void SendMessage ()
169 IGreetingsCallback clientCallback = OperationContext.Current.GetCallbackChannel<IGreetingsCallback> ();
171 clientCallback.ShowMessage ("Mono and WCF are GREAT!");
172 CallbackBehaviorAttributeTest.CallbackSent = true;
176 // Client callback interface implementation
177 [CallbackBehavior (ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
178 public class ClientCallback : IGreetingsCallback
180 public void ShowMessage (string message)
182 CallbackBehaviorAttributeTest.CallbackReceived = true;
186 [ServiceContract (CallbackContract = typeof (IGreetingsCallback))]
187 public interface IGreetings
189 [OperationContract (IsOneWay = true)]
194 public interface IGreetingsCallback
196 [OperationContract (IsOneWay = true)]
197 void ShowMessage (string message);