ChannelDispatcherTest.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Text;
  7. using NUnit.Framework;
  8. using System.ServiceModel;
  9. using System.ServiceModel.Channels;
  10. using System.ServiceModel.Description;
  11. using System.ServiceModel.Dispatcher;
  12. using MonoTests.Helpers;
  13. namespace MonoTests.System.ServiceModel.Dispatcher
  14. {
  15. [TestFixture]
  16. public class ChannelDispatcherTest
  17. {
  18. [Test]
  19. public void ConstructorNullBindingName ()
  20. {
  21. new ChannelDispatcher (new MyChannelListener (new Uri ("urn:foo")), null);
  22. new ChannelDispatcher (new MyChannelListener (new Uri ("urn:foo")), null, null);
  23. }
  24. [Test]
  25. public void ServiceThrottle ()
  26. {
  27. var cd = new ChannelDispatcher (new MyChannelListener<IReplyChannel> (new Uri ("urn:foo")));
  28. var st = cd.ServiceThrottle;
  29. Assert.IsNull (st, "#0");
  30. var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
  31. ServiceHost h = new ServiceHost (typeof (TestContract), uri);
  32. h.AddServiceEndpoint (typeof (TestContract).FullName, new BasicHttpBinding (), "address");
  33. h.ChannelDispatchers.Add (cd);
  34. Assert.IsNull (st, "#1");
  35. var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
  36. Assert.IsNull (ed.ChannelDispatcher, "#1-2");
  37. ed.DispatchRuntime.Type = typeof (TestContract);
  38. cd.Endpoints.Add (ed);
  39. Assert.AreEqual (cd, ed.ChannelDispatcher, "#1-3");
  40. cd.MessageVersion = MessageVersion.Default;
  41. {
  42. cd.Open (TimeSpan.FromSeconds (10));
  43. try {
  44. Assert.IsNull (st, "#2");
  45. // so, can't really test actual slot values as it is null.
  46. } finally {
  47. cd.Close (TimeSpan.FromSeconds (10));
  48. }
  49. return;
  50. }
  51. }
  52. [Test]
  53. public void Collection_Add_Remove () {
  54. Console.WriteLine ("STart test Collection_Add_Remove");
  55. var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
  56. ServiceHost h = new ServiceHost (typeof (TestContract), uri);
  57. h.AddServiceEndpoint (typeof (TestContract).FullName, new BasicHttpBinding (), "address");
  58. MyChannelDispatcher d = new MyChannelDispatcher (new MyChannelListener (uri));
  59. h.ChannelDispatchers.Add (d);
  60. Assert.IsTrue (d.Attached, "#1");
  61. h.ChannelDispatchers.Remove (d);
  62. Assert.IsFalse (d.Attached, "#2");
  63. h.ChannelDispatchers.Insert (0, d);
  64. Assert.IsTrue (d.Attached, "#3");
  65. h.ChannelDispatchers.Add (new MyChannelDispatcher (new MyChannelListener (uri)));
  66. h.ChannelDispatchers.Clear ();
  67. Assert.IsFalse (d.Attached, "#4");
  68. }
  69. [Test]
  70. public void EndpointDispatcherAddTest ()
  71. {
  72. var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
  73. MyChannelDispatcher d = new MyChannelDispatcher (new MyChannelListener (uri));
  74. d.Endpoints.Add (new EndpointDispatcher (new EndpointAddress (uri), "", ""));
  75. }
  76. [Test]
  77. [ExpectedException (typeof (InvalidOperationException))]
  78. public void EndpointDispatcherAddTest2 () {
  79. var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
  80. MyChannelDispatcher d = new MyChannelDispatcher (new MyChannelListener (uri));
  81. d.Endpoints.Add (new EndpointDispatcher (new EndpointAddress (uri), "", ""));
  82. d.Open (); // the dispatcher must be attached.
  83. }
  84. [Test]
  85. [ExpectedException (typeof (InvalidOperationException))]
  86. public void EndpointDispatcherAddTest3 ()
  87. {
  88. var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
  89. ServiceHost h = new ServiceHost (typeof (TestContract), uri);
  90. MyChannelDispatcher d = new MyChannelDispatcher (new MyChannelListener (uri));
  91. d.Endpoints.Add (new EndpointDispatcher (new EndpointAddress (uri), "", ""));
  92. h.ChannelDispatchers.Add (d);
  93. d.Open (); // missing MessageVersion
  94. }
  95. [Test]
  96. [ExpectedException (typeof (InvalidOperationException))] // i.e. it is thrown synchronously in current thread.
  97. public void EndpointDispatcherAddTest4 ()
  98. {
  99. var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
  100. ServiceHost h = new ServiceHost (typeof (TestContract), uri);
  101. var listener = new MyChannelListener (uri);
  102. MyChannelDispatcher d = new MyChannelDispatcher (listener);
  103. var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
  104. Assert.IsNotNull (ed.DispatchRuntime, "#1");
  105. Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#2");
  106. Assert.IsNull (ed.DispatchRuntime.InstanceContextProvider, "#3");
  107. Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#3.2");
  108. Assert.IsNull (ed.DispatchRuntime.SingletonInstanceContext, "#4");
  109. d.Endpoints.Add (ed);
  110. d.MessageVersion = MessageVersion.Default;
  111. h.ChannelDispatchers.Add (d);
  112. // it misses DispatchRuntime.Type, which seems set
  113. // automatically when the dispatcher is created in
  114. // ordinal process but need to be set manually in this case.
  115. try {
  116. d.Open ();
  117. try {
  118. // should not reach here, but in case it didn't, it must be closed.
  119. d.Close (TimeSpan.FromSeconds (10));
  120. } catch {
  121. }
  122. } finally {
  123. Assert.AreEqual (CommunicationState.Opened, listener.State, "#5");
  124. }
  125. }
  126. [Test]
  127. [ExpectedException (typeof (InvalidOperationException))] // i.e. it is thrown synchronously in current thread.
  128. public void EndpointDispatcherAddTest5 ()
  129. {
  130. var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
  131. ServiceHost h = new ServiceHost (typeof (TestContract), uri);
  132. var binding = new BasicHttpBinding ();
  133. var listener = new MyChannelListener (uri);
  134. MyChannelDispatcher d = new MyChannelDispatcher (listener);
  135. var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
  136. d.Endpoints.Add (ed);
  137. ed.DispatchRuntime.Type = typeof (TestContract); // different from Test4
  138. d.MessageVersion = MessageVersion.Default;
  139. h.ChannelDispatchers.Add (d);
  140. // It rejects "unrecognized type" of the channel listener.
  141. // Test6 uses IChannelListener<IReplyChannel> and works.
  142. d.Open ();
  143. // should not reach here, but in case it didn't, it must be closed.
  144. d.Close (TimeSpan.FromSeconds (10));
  145. }
  146. [Test]
  147. public void EndpointDispatcherAddTest6 ()
  148. {
  149. var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
  150. ServiceHost h = new ServiceHost (typeof (TestContract), uri);
  151. var binding = new BasicHttpBinding ();
  152. var listener = new MyChannelListener<IReplyChannel> (uri);
  153. MyChannelDispatcher d = new MyChannelDispatcher (listener);
  154. var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
  155. d.Endpoints.Add (ed);
  156. Assert.IsFalse (d.Attached, "#x1");
  157. ed.DispatchRuntime.Type = typeof (TestContract);
  158. d.MessageVersion = MessageVersion.Default;
  159. h.ChannelDispatchers.Add (d);
  160. Assert.IsTrue (d.Attached, "#x2");
  161. d.Open (); // At this state, it does *not* call AcceptChannel() yet.
  162. Assert.IsFalse (listener.AcceptChannelTried, "#1");
  163. Assert.IsFalse (listener.WaitForChannelTried, "#2");
  164. Assert.IsNotNull (ed.DispatchRuntime, "#3");
  165. Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#4");
  166. Assert.IsNull (ed.DispatchRuntime.InstanceContextProvider, "#5"); // it is not still set after ChannelDispatcher.Open().
  167. Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#5.2");
  168. Assert.IsNull (ed.DispatchRuntime.SingletonInstanceContext, "#6");
  169. d.Close (); // we don't have to even close it.
  170. }
  171. [Test]
  172. [ExpectedException (typeof (InvalidOperationException))]
  173. public void EndpointDispatcherAddTest7 ()
  174. {
  175. var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
  176. ServiceHost h = new ServiceHost (typeof (TestContract), uri);
  177. var binding = new BasicHttpBinding ();
  178. var listener = new MyChannelListener<IReplyChannel> (uri);
  179. MyChannelDispatcher d = new MyChannelDispatcher (listener);
  180. var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
  181. d.Endpoints.Add (ed);
  182. ed.DispatchRuntime.Type = typeof (TestContract);
  183. d.MessageVersion = MessageVersion.Default;
  184. // add service endpoint to open the host (unlike all tests above).
  185. h.AddServiceEndpoint (typeof (TestContract),
  186. new BasicHttpBinding (), uri.ToString ());
  187. h.ChannelDispatchers.Clear ();
  188. h.ChannelDispatchers.Add (d);
  189. d.Open (); // At this state, it does *not* call AcceptChannel() yet.
  190. // This rejects already-opened ChannelDispatcher.
  191. h.Open (TimeSpan.FromSeconds (10));
  192. // should not reach here, but in case it didn't, it must be closed.
  193. h.Close (TimeSpan.FromSeconds (10));
  194. }
  195. [Test]
  196. [Category ("NotWorking")]
  197. // Validating duplicate listen URI causes this regression.
  198. // Since it is niche, I rather fixed ServiceHostBase to introduce validation.
  199. // It is probably because this code doesn't use ServiceEndpoint to build IChannelListener i.e. built without Binding.
  200. // We can add an extra field to ChannelDispatcher to indicate that it is from ServiceEndpoint (i.e. with Binding),
  201. // but it makes little sense especially for checking duplicate listen URIs. Duplicate listen URIs should be rejected anyways.
  202. public void EndpointDispatcherAddTest8 ()
  203. {
  204. var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
  205. ServiceHost h = new ServiceHost (typeof (TestContract), uri);
  206. var listener = new MyChannelListener<IReplyChannel> (uri);
  207. MyChannelDispatcher d = new MyChannelDispatcher (listener);
  208. var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
  209. d.Endpoints.Add (ed);
  210. ed.DispatchRuntime.Type = typeof (TestContract);
  211. d.MessageVersion = MessageVersion.Default;
  212. // add service endpoint to open the host (unlike all tests above).
  213. h.AddServiceEndpoint (typeof (TestContract),
  214. new BasicHttpBinding (), uri.ToString ());
  215. h.ChannelDispatchers.Clear ();
  216. h.ChannelDispatchers.Add (d);
  217. Assert.AreEqual (h, d.Host, "#0");
  218. try {
  219. h.Open (TimeSpan.FromSeconds (10));
  220. Assert.AreEqual (3, h.ChannelDispatchers.Count, "#0"); // TestContract, d, mex
  221. Assert.IsTrue (listener.BeginAcceptChannelTried, "#1"); // while it throws NIE ...
  222. Assert.IsFalse (listener.WaitForChannelTried, "#2");
  223. Assert.IsNotNull (ed.DispatchRuntime, "#3");
  224. Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#4");
  225. Assert.IsNotNull (ed.DispatchRuntime.InstanceContextProvider, "#5"); // it was set after ServiceHost.Open().
  226. Assert.IsNull (ed.DispatchRuntime.SingletonInstanceContext, "#6");
  227. /*
  228. var l = new HttpListener ();
  229. l.Prefixes.Add (uri.ToString ());
  230. l.Start ();
  231. l.Stop ();
  232. */
  233. } finally {
  234. h.Close (TimeSpan.FromSeconds (10));
  235. h.Abort ();
  236. }
  237. }
  238. // FIXME: this test itself indeed passes, but some weird conflict that blocks correspoding port happens between this and somewhere (probably above)
  239. // [Test]
  240. public void EndpointDispatcherAddTest9 () // test singleton service
  241. {
  242. var uri = new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ());
  243. ServiceHost h = new ServiceHost (new TestContract (), uri);
  244. h.Description.Behaviors.Find<ServiceBehaviorAttribute> ().InstanceContextMode = InstanceContextMode.Single;
  245. var listener = new MyChannelListener<IReplyChannel> (uri);
  246. MyChannelDispatcher d = new MyChannelDispatcher (listener);
  247. var ed = new EndpointDispatcher (new EndpointAddress (uri), "", "");
  248. d.Endpoints.Add (ed);
  249. ed.DispatchRuntime.Type = typeof (TestContract);
  250. d.MessageVersion = MessageVersion.Default;
  251. h.AddServiceEndpoint (typeof (TestContract), new BasicHttpBinding (), uri.ToString ());
  252. h.ChannelDispatchers.Clear ();
  253. Assert.IsNull (ed.DispatchRuntime.SingletonInstanceContext, "#1");
  254. h.ChannelDispatchers.Add (d);
  255. Assert.IsNull (ed.DispatchRuntime.SingletonInstanceContext, "#2");
  256. try {
  257. h.Open (TimeSpan.FromSeconds (10));
  258. Assert.IsNull (ed.DispatchRuntime.InstanceProvider, "#4");
  259. Assert.IsNotNull (ed.DispatchRuntime.InstanceContextProvider, "#5"); // it was set after ServiceHost.Open().
  260. Assert.IsNotNull (ed.DispatchRuntime.SingletonInstanceContext, "#6");
  261. } finally {
  262. h.Close (TimeSpan.FromSeconds (10));
  263. h.Abort ();
  264. }
  265. }
  266. [ServiceContract]
  267. public class TestContract
  268. {
  269. [OperationContract]
  270. public void Process (string input) {
  271. }
  272. }
  273. class MyChannelDispatcher : ChannelDispatcher
  274. {
  275. public bool Attached = false;
  276. public MyChannelDispatcher (IChannelListener l) : base (l) { }
  277. protected override void Attach (ServiceHostBase host) {
  278. base.Attach (host);
  279. Attached = true;
  280. }
  281. protected override void Detach (ServiceHostBase host) {
  282. base.Detach (host);
  283. Attached = false;
  284. }
  285. }
  286. class MyChannelListener<TChannel> : MyChannelListener, IChannelListener<TChannel> where TChannel : class, IChannel
  287. {
  288. public MyChannelListener (Uri uri)
  289. : base (uri)
  290. {
  291. }
  292. public bool AcceptChannelTried { get; set; }
  293. public bool BeginAcceptChannelTried { get; set; }
  294. public TChannel AcceptChannel ()
  295. {
  296. AcceptChannelTried = true;
  297. throw new NotImplementedException ();
  298. }
  299. public TChannel AcceptChannel (TimeSpan timeout)
  300. {
  301. AcceptChannelTried = true;
  302. throw new NotImplementedException ();
  303. }
  304. public IAsyncResult BeginAcceptChannel (AsyncCallback callback, object state)
  305. {
  306. BeginAcceptChannelTried = true;
  307. throw new NotImplementedException ();
  308. }
  309. public IAsyncResult BeginAcceptChannel (TimeSpan timeout, AsyncCallback callback, object state)
  310. {
  311. BeginAcceptChannelTried = true;
  312. throw new NotImplementedException ();
  313. }
  314. public TChannel EndAcceptChannel (IAsyncResult result)
  315. {
  316. throw new NotImplementedException ();
  317. }
  318. }
  319. class MyChannelListener : IChannelListener
  320. {
  321. public MyChannelListener (Uri uri)
  322. {
  323. Uri = uri;
  324. }
  325. public bool WaitForChannelTried { get; set; }
  326. public CommunicationState State { get; set; }
  327. #region IChannelListener Members
  328. public IAsyncResult BeginWaitForChannel (TimeSpan timeout, AsyncCallback callback, object state)
  329. {
  330. WaitForChannelTried = true;
  331. throw new NotImplementedException ();
  332. }
  333. public bool EndWaitForChannel (IAsyncResult result)
  334. {
  335. throw new NotImplementedException ();
  336. }
  337. public T GetProperty<T> () where T : class
  338. {
  339. throw new NotImplementedException ();
  340. }
  341. public Uri Uri { get; set; }
  342. public bool WaitForChannel (TimeSpan timeout)
  343. {
  344. WaitForChannelTried = true;
  345. throw new NotImplementedException ();
  346. }
  347. #endregion
  348. #region ICommunicationObject Members
  349. public void Abort ()
  350. {
  351. State = CommunicationState.Closed;
  352. }
  353. public IAsyncResult BeginClose (TimeSpan timeout, AsyncCallback callback, object state) {
  354. throw new NotImplementedException ();
  355. }
  356. public IAsyncResult BeginClose (AsyncCallback callback, object state) {
  357. throw new NotImplementedException ();
  358. }
  359. public IAsyncResult BeginOpen (TimeSpan timeout, AsyncCallback callback, object state) {
  360. throw new NotImplementedException ();
  361. }
  362. public IAsyncResult BeginOpen (AsyncCallback callback, object state) {
  363. throw new NotImplementedException ();
  364. }
  365. public void Close (TimeSpan timeout)
  366. {
  367. State = CommunicationState.Closed;
  368. }
  369. public void Close ()
  370. {
  371. State = CommunicationState.Closed;
  372. }
  373. public event EventHandler Closed;
  374. public event EventHandler Closing;
  375. public void EndClose (IAsyncResult result) {
  376. throw new NotImplementedException ();
  377. }
  378. public void EndOpen (IAsyncResult result) {
  379. throw new NotImplementedException ();
  380. }
  381. public event EventHandler Faulted;
  382. public void Open (TimeSpan timeout)
  383. {
  384. State = CommunicationState.Opened;
  385. }
  386. public void Open ()
  387. {
  388. State = CommunicationState.Opened;
  389. }
  390. public event EventHandler Opened;
  391. public event EventHandler Opening;
  392. #endregion
  393. }
  394. }
  395. }