BindingTestAssertions.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. //
  2. // BindingTestAssertions.cs
  3. //
  4. // Author:
  5. // Martin Baulig <[email protected]>
  6. //
  7. // Copyright (c) 2012 Xamarin Inc. (http://www.xamarin.com)
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining a copy
  10. // of this software and associated documentation files (the "Software"), to deal
  11. // in the Software without restriction, including without limitation the rights
  12. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. // copies of the Software, and to permit persons to whom the Software is
  14. // furnished to do so, subject to the following conditions:
  15. //
  16. // The above copyright notice and this permission notice shall be included in
  17. // all copies or substantial portions of the Software.
  18. //
  19. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. // THE SOFTWARE.
  26. using System;
  27. using System.Net;
  28. using System.Net.Security;
  29. using System.Xml;
  30. using System.Xml.XPath;
  31. using System.Text;
  32. using System.Collections.Generic;
  33. using System.ServiceModel;
  34. using System.ServiceModel.Security;
  35. using System.ServiceModel.Channels;
  36. using System.ServiceModel.Description;
  37. using NUnit.Framework;
  38. using NUnit.Framework.Constraints;
  39. using NUnit.Framework.SyntaxHelpers;
  40. using QName = System.Xml.XmlQualifiedName;
  41. using WS = System.Web.Services.Description;
  42. namespace MonoTests.System.ServiceModel.MetadataTests {
  43. public static class BindingTestAssertions {
  44. const string WspNamespace = "http://schemas.xmlsoap.org/ws/2004/09/policy";
  45. const string WsuNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
  46. const string MsbNamespace = "http://schemas.microsoft.com/ws/06/2004/mspolicy/netbinary1";
  47. const string WsawNamespace = "http://www.w3.org/2006/05/addressing/wsdl";
  48. const string MsfNamespace = "http://schemas.microsoft.com/ws/2006/05/framing/policy";
  49. const string SpNamespace = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy";
  50. const string WsrmNamespace = "http://schemas.xmlsoap.org/ws/2005/02/rm/policy";
  51. const string HttpNamespace = "http://schemas.microsoft.com/ws/06/2004/policy/http";
  52. const string WsomaNamespace = "http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization";
  53. const string Wsa10Namespace = "http://www.w3.org/2005/08/addressing";
  54. static readonly QName BinaryEncodingQName = new QName ("BinaryEncoding", MsbNamespace);
  55. static readonly QName UsingAddressingQName = new QName ("UsingAddressing", WsawNamespace);
  56. static readonly QName StreamedTransferQName = new QName ("Streamed", MsfNamespace);
  57. static readonly QName ReliableSessionQName = new QName ("RMAssertion", WsrmNamespace);
  58. static readonly QName TransportBindingQName = new QName ("TransportBinding", SpNamespace);
  59. static readonly QName AsymmetricBindingQName = new QName ("AsymmetricBinding", SpNamespace);
  60. static readonly QName SymmetricBindingQName = new QName ("SymmetricBinding", SpNamespace);
  61. static readonly QName EndorsingSupportingQName = new QName ("EndorsingSupportingTokens", SpNamespace);
  62. static readonly QName SignedSupportingQName = new QName ("SignedSupportingTokens", SpNamespace);
  63. static readonly QName Wss10QName = new QName ("Wss10", SpNamespace);
  64. static readonly QName Wss11QName = new QName ("Wss11", SpNamespace);
  65. static readonly QName Trust10QName = new QName ("Trust10", SpNamespace);
  66. static readonly QName NtlmAuthenticationQName = new QName ("NtlmAuthentication", HttpNamespace);
  67. static readonly QName MtomEncodingQName = new QName ("OptimizedMimeSerialization", WsomaNamespace);
  68. public static void CheckImportErrors (WsdlImporter importer, TestLabel label)
  69. {
  70. bool foundErrors = false;
  71. foreach (var error in importer.Errors) {
  72. if (error.IsWarning)
  73. Console.WriteLine ("WARNING ({0}): {1}", label, error.Message);
  74. else {
  75. Console.WriteLine ("ERROR ({0}): {1}", label, error.Message);
  76. foundErrors = true;
  77. }
  78. }
  79. if (foundErrors)
  80. Assert.Fail ("Found import errors", label);
  81. }
  82. static void CheckSoapBinding (object extension, string transport, TestLabel label)
  83. {
  84. label.EnterScope ("soap");
  85. Assert.That (extension, Is.InstanceOfType (typeof (WS.SoapBinding)), label.Get ());
  86. var soap = (WS.SoapBinding)extension;
  87. Assert.That (soap.Style, Is.EqualTo (WS.SoapBindingStyle.Document), label.Get ());
  88. Assert.That (soap.Transport, Is.EqualTo (transport), label.Get ());
  89. Assert.That (soap.Required, Is.False, label.Get ());
  90. label.LeaveScope ();
  91. }
  92. public static void CheckBasicHttpBinding (
  93. Binding binding, string scheme, BasicHttpSecurityMode security,
  94. WSMessageEncoding encoding, HttpClientCredentialType clientCred,
  95. AuthenticationSchemes authScheme, TestLabel label)
  96. {
  97. label.EnterScope ("http");
  98. if (security == BasicHttpSecurityMode.Message) {
  99. Assert.That (binding, Is.InstanceOfType (typeof(CustomBinding)), label.Get ());
  100. } else {
  101. Assert.That (binding, Is.InstanceOfType (typeof(BasicHttpBinding)), label.Get ());
  102. var basicHttp = (BasicHttpBinding)binding;
  103. Assert.That (basicHttp.EnvelopeVersion, Is.EqualTo (EnvelopeVersion.Soap11), label.Get ());
  104. Assert.That (basicHttp.MessageVersion, Is.EqualTo (MessageVersion.Soap11), label.Get ());
  105. Assert.That (basicHttp.Scheme, Is.EqualTo (scheme), label.Get ());
  106. Assert.That (basicHttp.TransferMode, Is.EqualTo (TransferMode.Buffered), label.Get ());
  107. Assert.That (basicHttp.MessageEncoding, Is.EqualTo (encoding), label.Get ());
  108. Assert.That (basicHttp.Security, Is.Not.Null, label.Get ());
  109. Assert.That (basicHttp.Security.Mode, Is.EqualTo (security), label.Get ());
  110. Assert.That (basicHttp.Security.Transport.ClientCredentialType, Is.EqualTo (clientCred), label.Get ());
  111. Assert.That (basicHttp.Security.Message.AlgorithmSuite, Is.EqualTo (SecurityAlgorithmSuite.Basic256), label.Get ());
  112. }
  113. label.EnterScope ("elements");
  114. var elements = binding.CreateBindingElements ();
  115. Assert.That (elements, Is.Not.Null, label.Get ());
  116. if ((security == BasicHttpSecurityMode.Message) ||
  117. (security == BasicHttpSecurityMode.TransportWithMessageCredential))
  118. Assert.That (elements.Count, Is.EqualTo (3), label.Get ());
  119. else
  120. Assert.That (elements.Count, Is.EqualTo (2), label.Get ());
  121. TextMessageEncodingBindingElement textElement = null;
  122. TransportSecurityBindingElement securityElement = null;
  123. HttpTransportBindingElement transportElement = null;
  124. AsymmetricSecurityBindingElement asymmSecurityElement = null;
  125. MtomMessageEncodingBindingElement mtomElement = null;
  126. foreach (var element in elements) {
  127. if (element is TextMessageEncodingBindingElement)
  128. textElement = (TextMessageEncodingBindingElement)element;
  129. else if (element is HttpTransportBindingElement)
  130. transportElement = (HttpTransportBindingElement)element;
  131. else if (element is TransportSecurityBindingElement)
  132. securityElement = (TransportSecurityBindingElement)element;
  133. else if (element is AsymmetricSecurityBindingElement)
  134. asymmSecurityElement = (AsymmetricSecurityBindingElement)element;
  135. else if (element is MtomMessageEncodingBindingElement)
  136. mtomElement = (MtomMessageEncodingBindingElement)element;
  137. else
  138. Assert.Fail (string.Format (
  139. "Unknown element: {0}", element.GetType ()), label.Get ());
  140. }
  141. label.EnterScope ("text");
  142. if (encoding == WSMessageEncoding.Text) {
  143. Assert.That (textElement, Is.Not.Null, label.Get ());
  144. Assert.That (textElement.WriteEncoding, Is.InstanceOfType (typeof(UTF8Encoding)), label.Get ());
  145. } else {
  146. Assert.That (textElement, Is.Null, label.Get ());
  147. }
  148. label.LeaveScope ();
  149. label.EnterScope ("mtom");
  150. if (encoding == WSMessageEncoding.Mtom) {
  151. Assert.That (mtomElement, Is.Not.Null, label.Get ());
  152. } else {
  153. Assert.That (mtomElement, Is.Null, label.Get ());
  154. }
  155. label.LeaveScope ();
  156. label.EnterScope ("security");
  157. if (security == BasicHttpSecurityMode.TransportWithMessageCredential) {
  158. Assert.That (securityElement, Is.Not.Null, label.Get ());
  159. Assert.That (securityElement.SecurityHeaderLayout,
  160. Is.EqualTo (SecurityHeaderLayout.Lax), label.Get ());
  161. } else {
  162. Assert.That (securityElement, Is.Null, label.Get ());
  163. }
  164. label.LeaveScope ();
  165. label.EnterScope ("asymmetric");
  166. if (security == BasicHttpSecurityMode.Message) {
  167. Assert.That (asymmSecurityElement, Is.Not.Null, label.Get ());
  168. } else {
  169. Assert.That (asymmSecurityElement, Is.Null, label.Get ());
  170. }
  171. label.LeaveScope ();
  172. label.EnterScope ("transport");
  173. Assert.That (transportElement, Is.Not.Null, label.Get ());
  174. Assert.That (transportElement.Realm, Is.Empty, label.Get ());
  175. Assert.That (transportElement.Scheme, Is.EqualTo (scheme), label.Get ());
  176. Assert.That (transportElement.TransferMode, Is.EqualTo (TransferMode.Buffered), label.Get ());
  177. label.EnterScope ("auth");
  178. Assert.That (transportElement.AuthenticationScheme, Is.EqualTo (authScheme), label.Get ());
  179. label.LeaveScope (); // auth
  180. label.LeaveScope (); // transport
  181. label.LeaveScope (); // elements
  182. label.LeaveScope (); // http
  183. }
  184. static void CheckEndpoint (ServiceEndpoint endpoint, string uri, TestLabel label)
  185. {
  186. label.EnterScope ("endpoint");
  187. Assert.That (endpoint.ListenUri, Is.EqualTo (new Uri (uri)), label.Get ());
  188. Assert.That (endpoint.ListenUriMode, Is.EqualTo (ListenUriMode.Explicit), label.Get ());
  189. Assert.That (endpoint.Contract, Is.Not.Null, label.Get ());
  190. Assert.That (endpoint.Contract.Name, Is.EqualTo ("MyContract"), label.Get ());
  191. Assert.That (endpoint.Address, Is.Not.Null, label.Get ());
  192. Assert.That (endpoint.Address.Uri, Is.EqualTo (new Uri (uri)), label.Get ());
  193. Assert.That (endpoint.Address.Identity, Is.Null, label.Get ());
  194. Assert.That (endpoint.Address.Headers, Is.Not.Null, label.Get ());
  195. Assert.That (endpoint.Address.Headers.Count, Is.EqualTo (0), label.Get ());
  196. label.LeaveScope ();
  197. }
  198. public static void BasicHttpBinding (
  199. TestContext context, MetadataSet doc, WSMessageEncoding encoding, TestLabel label)
  200. {
  201. BasicHttpBinding (
  202. context, doc, BasicHttpSecurityMode.None, encoding,
  203. HttpClientCredentialType.None, AuthenticationSchemes.Anonymous,
  204. label);
  205. }
  206. public static void BasicHttpBinding (
  207. TestContext context, MetadataSet doc, BasicHttpSecurityMode security, TestLabel label)
  208. {
  209. BasicHttpBinding (
  210. context, doc, security, WSMessageEncoding.Text,
  211. HttpClientCredentialType.None, AuthenticationSchemes.Anonymous,
  212. label);
  213. }
  214. public static void BasicHttpBinding (
  215. TestContext context, MetadataSet doc, BasicHttpSecurityMode security,
  216. WSMessageEncoding encoding, HttpClientCredentialType clientCred,
  217. AuthenticationSchemes authScheme, TestLabel label)
  218. {
  219. label.EnterScope ("basicHttpBinding");
  220. BasicHttpBinding_inner (
  221. context, doc, security, encoding, clientCred,
  222. authScheme, false, label);
  223. label.LeaveScope ();
  224. }
  225. public static void BasicHttpsBinding (
  226. TestContext context, MetadataSet doc, BasicHttpSecurityMode security,
  227. WSMessageEncoding encoding, HttpClientCredentialType clientCred,
  228. AuthenticationSchemes authScheme, TestLabel label)
  229. {
  230. label.EnterScope ("basicHttpsBinding");
  231. BasicHttpBinding_inner (
  232. context, doc, security, encoding, clientCred,
  233. authScheme, true, label);
  234. label.LeaveScope ();
  235. }
  236. static void BasicHttpBinding_inner (
  237. TestContext context, MetadataSet doc, BasicHttpSecurityMode security,
  238. WSMessageEncoding encoding, HttpClientCredentialType clientCred,
  239. AuthenticationSchemes authScheme, bool isHttps, TestLabel label)
  240. {
  241. var sd = (WS.ServiceDescription)doc.MetadataSections [0].Metadata;
  242. label.EnterScope ("wsdl");
  243. label.EnterScope ("bindings");
  244. Assert.That (sd.Bindings.Count, Is.EqualTo (1), label.Get ());
  245. var binding = sd.Bindings [0];
  246. Assert.That (binding.ExtensibleAttributes, Is.Null, label.Get ());
  247. Assert.That (binding.Extensions, Is.Not.Null, label.Get ());
  248. bool hasPolicyXml;
  249. switch (security) {
  250. case BasicHttpSecurityMode.None:
  251. if (isHttps)
  252. throw new InvalidOperationException ();
  253. hasPolicyXml = encoding == WSMessageEncoding.Mtom;
  254. break;
  255. case BasicHttpSecurityMode.Message:
  256. case BasicHttpSecurityMode.Transport:
  257. case BasicHttpSecurityMode.TransportWithMessageCredential:
  258. if (encoding == WSMessageEncoding.Mtom)
  259. throw new InvalidOperationException ();
  260. hasPolicyXml = true;
  261. break;
  262. case BasicHttpSecurityMode.TransportCredentialOnly:
  263. if (isHttps)
  264. throw new InvalidOperationException ();
  265. hasPolicyXml = true;
  266. break;
  267. default:
  268. throw new InvalidOperationException ();
  269. }
  270. label.LeaveScope ();
  271. WS.SoapBinding soap = null;
  272. XmlElement xml = null;
  273. foreach (var ext in binding.Extensions) {
  274. if (ext is WS.SoapBinding)
  275. soap = (WS.SoapBinding)ext;
  276. else if (ext is XmlElement)
  277. xml = (XmlElement)ext;
  278. }
  279. CheckSoapBinding (soap, WS.SoapBinding.HttpTransport, label);
  280. label.LeaveScope ();
  281. label.EnterScope ("policy-xml");
  282. if (!hasPolicyXml)
  283. Assert.That (xml, Is.Null, label.Get ());
  284. else {
  285. Assert.That (xml, Is.Not.Null, label.Get ());
  286. var assertions = AssertPolicy (sd, xml, label);
  287. Assert.That (assertions, Is.Not.Null, label.Get ());
  288. if (clientCred == HttpClientCredentialType.Ntlm)
  289. AssertPolicy (assertions, NtlmAuthenticationQName, label);
  290. if (encoding == WSMessageEncoding.Mtom)
  291. AssertPolicy (assertions, MtomEncodingQName, label);
  292. switch (security) {
  293. case BasicHttpSecurityMode.Message:
  294. AssertPolicy (assertions, AsymmetricBindingQName, label);
  295. AssertPolicy (assertions, Wss10QName, label);
  296. break;
  297. case BasicHttpSecurityMode.Transport:
  298. AssertPolicy (assertions, TransportBindingQName, label);
  299. break;
  300. case BasicHttpSecurityMode.TransportWithMessageCredential:
  301. AssertPolicy (assertions, SignedSupportingQName, label);
  302. AssertPolicy (assertions, TransportBindingQName, label);
  303. AssertPolicy (assertions, Wss10QName, label);
  304. break;
  305. default:
  306. break;
  307. }
  308. Assert.That (assertions.Count, Is.EqualTo (0), label.Get ());
  309. }
  310. label.LeaveScope ();
  311. label.EnterScope ("services");
  312. Assert.That (sd.Services, Is.Not.Null, label.Get ());
  313. Assert.That (sd.Services.Count, Is.EqualTo (1), label.Get ());
  314. var service = sd.Services [0];
  315. Assert.That (service.Ports, Is.Not.Null, label.Get ());
  316. Assert.That (service.Ports.Count, Is.EqualTo (1), label.Get ());
  317. var port = service.Ports [0];
  318. label.EnterScope ("port");
  319. Assert.That (port.Extensions, Is.Not.Null, label.Get ());
  320. Assert.That (port.Extensions.Count, Is.EqualTo (1), label.Get ());
  321. WS.SoapAddressBinding soap_addr_binding = null;
  322. foreach (var extension in port.Extensions) {
  323. if (extension is WS.SoapAddressBinding)
  324. soap_addr_binding = (WS.SoapAddressBinding)extension;
  325. else
  326. Assert.Fail (label.Get ());
  327. }
  328. Assert.That (soap_addr_binding, Is.Not.Null, label.Get ());
  329. label.LeaveScope ();
  330. label.LeaveScope (); // wsdl
  331. var importer = new WsdlImporter (doc);
  332. label.EnterScope ("bindings");
  333. var bindings = importer.ImportAllBindings ();
  334. CheckImportErrors (importer, label);
  335. Assert.That (bindings, Is.Not.Null, label.Get ());
  336. Assert.That (bindings.Count, Is.EqualTo (1), label.Get ());
  337. string scheme;
  338. if ((security == BasicHttpSecurityMode.Transport) ||
  339. (security == BasicHttpSecurityMode.TransportWithMessageCredential))
  340. scheme = "https";
  341. else
  342. scheme = "http";
  343. CheckBasicHttpBinding (
  344. bindings [0], scheme, security, encoding, clientCred,
  345. authScheme, label);
  346. label.LeaveScope ();
  347. label.EnterScope ("endpoints");
  348. var endpoints = importer.ImportAllEndpoints ();
  349. CheckImportErrors (importer, label);
  350. Assert.That (endpoints, Is.Not.Null, label.Get ());
  351. Assert.That (endpoints.Count, Is.EqualTo (1), label.Get ());
  352. var uri = isHttps ? MetadataSamples.HttpsUri : MetadataSamples.HttpUri;
  353. CheckEndpoint (endpoints [0], uri, label);
  354. label.LeaveScope ();
  355. }
  356. public static void CheckNetTcpBinding (
  357. Binding binding, SecurityMode security, bool reliableSession,
  358. TransferMode transferMode, TestLabel label)
  359. {
  360. label.EnterScope ("net-tcp");
  361. if (security == SecurityMode.Message) {
  362. Assert.That (binding, Is.InstanceOfType (typeof(CustomBinding)), label.Get ());
  363. } else {
  364. Assert.That (binding, Is.InstanceOfType (typeof(NetTcpBinding)), label.Get ());
  365. var netTcp = (NetTcpBinding)binding;
  366. Assert.That (netTcp.EnvelopeVersion, Is.EqualTo (EnvelopeVersion.Soap12), label.Get ());
  367. Assert.That (netTcp.MessageVersion, Is.EqualTo (MessageVersion.Soap12WSAddressing10), label.Get ());
  368. Assert.That (netTcp.Scheme, Is.EqualTo ("net.tcp"), label.Get ());
  369. Assert.That (netTcp.TransferMode, Is.EqualTo (transferMode), label.Get ());
  370. label.EnterScope ("security");
  371. Assert.That (netTcp.Security, Is.Not.Null, label.Get ());
  372. Assert.That (netTcp.Security.Mode, Is.EqualTo (security), label.Get ());
  373. Assert.That (netTcp.Security.Transport, Is.Not.Null, label.Get ());
  374. Assert.That (netTcp.Security.Transport.ProtectionLevel, Is.EqualTo (ProtectionLevel.EncryptAndSign), label.Get ());
  375. Assert.That (netTcp.Security.Transport.ClientCredentialType, Is.EqualTo (TcpClientCredentialType.Windows), label.Get ());
  376. label.LeaveScope ();
  377. }
  378. label.EnterScope ("elements");
  379. var elements = binding.CreateBindingElements ();
  380. Assert.That (elements, Is.Not.Null, label.Get ());
  381. TcpTransportBindingElement transportElement = null;
  382. TransactionFlowBindingElement transactionFlowElement = null;
  383. BinaryMessageEncodingBindingElement encodingElement = null;
  384. WindowsStreamSecurityBindingElement windowsStreamElement = null;
  385. ReliableSessionBindingElement reliableSessionElement = null;
  386. TransportSecurityBindingElement transportSecurityElement = null;
  387. SslStreamSecurityBindingElement sslStreamElement = null;
  388. SymmetricSecurityBindingElement symmSecurityElement = null;
  389. foreach (var element in elements) {
  390. if (element is TcpTransportBindingElement)
  391. transportElement = (TcpTransportBindingElement)element;
  392. else if (element is TransactionFlowBindingElement)
  393. transactionFlowElement = (TransactionFlowBindingElement)element;
  394. else if (element is BinaryMessageEncodingBindingElement)
  395. encodingElement = (BinaryMessageEncodingBindingElement)element;
  396. else if (element is WindowsStreamSecurityBindingElement)
  397. windowsStreamElement = (WindowsStreamSecurityBindingElement)element;
  398. else if (element is ReliableSessionBindingElement)
  399. reliableSessionElement = (ReliableSessionBindingElement)element;
  400. else if (element is TransportSecurityBindingElement)
  401. transportSecurityElement = (TransportSecurityBindingElement)element;
  402. else if (element is SslStreamSecurityBindingElement)
  403. sslStreamElement = (SslStreamSecurityBindingElement)element;
  404. else if (element is SymmetricSecurityBindingElement)
  405. symmSecurityElement = (SymmetricSecurityBindingElement)element;
  406. else
  407. Assert.Fail (string.Format (
  408. "Unknown element `{0}'.", element.GetType ()), label.Get ());
  409. }
  410. label.EnterScope ("windows-stream");
  411. if (security == SecurityMode.Transport) {
  412. Assert.That (windowsStreamElement, Is.Not.Null, label.Get ());
  413. Assert.That (windowsStreamElement.ProtectionLevel, Is.EqualTo (ProtectionLevel.EncryptAndSign), label.Get ());
  414. } else {
  415. Assert.That (windowsStreamElement, Is.Null, label.Get ());
  416. }
  417. label.LeaveScope ();
  418. label.EnterScope ("reliable-session");
  419. if (reliableSession) {
  420. Assert.That (reliableSessionElement, Is.Not.Null, label.Get ());
  421. } else {
  422. Assert.That (reliableSessionElement, Is.Null, label.Get ());
  423. }
  424. label.LeaveScope ();
  425. label.EnterScope ("encoding");
  426. Assert.That (encodingElement, Is.Not.Null, label.Get ());
  427. label.LeaveScope ();
  428. label.EnterScope ("transaction");
  429. if (security == SecurityMode.Message) {
  430. Assert.That (transactionFlowElement, Is.Null, label.Get ());
  431. } else {
  432. Assert.That (transactionFlowElement, Is.Not.Null, label.Get ());
  433. }
  434. label.LeaveScope ();
  435. label.EnterScope ("transport");
  436. Assert.That (transportElement, Is.Not.Null, label.Get ());
  437. Assert.That (transportElement.Scheme, Is.EqualTo ("net.tcp"), label.Get ());
  438. Assert.That (transportElement.TransferMode, Is.EqualTo (transferMode), label.Get ());
  439. label.LeaveScope (); // transport
  440. label.EnterScope ("security");
  441. switch (security) {
  442. case SecurityMode.None:
  443. case SecurityMode.Transport:
  444. Assert.That (transportSecurityElement, Is.Null, label.Get ());
  445. Assert.That (sslStreamElement, Is.Null, label.Get ());
  446. Assert.That (symmSecurityElement, Is.Null, label.Get ());
  447. break;
  448. case SecurityMode.TransportWithMessageCredential:
  449. Assert.That (transportSecurityElement, Is.Not.Null, label.Get ());
  450. Assert.That (sslStreamElement, Is.Not.Null, label.Get ());
  451. Assert.That (symmSecurityElement, Is.Null, label.Get ());
  452. break;
  453. case SecurityMode.Message:
  454. Assert.That (transportSecurityElement, Is.Null, label.Get ());
  455. Assert.That (sslStreamElement, Is.Null, label.Get ());
  456. Assert.That (symmSecurityElement, Is.Not.Null, label.Get ());
  457. break;
  458. default:
  459. throw new InvalidOperationException ();
  460. }
  461. label.LeaveScope ();
  462. label.LeaveScope (); // elements
  463. label.LeaveScope (); // net-tcp
  464. }
  465. public static void NetTcpBinding (
  466. TestContext context, MetadataSet doc, SecurityMode security,
  467. bool reliableSession, TransferMode transferMode, TestLabel label)
  468. {
  469. label.EnterScope ("netTcpBinding");
  470. var sd = (WS.ServiceDescription)doc.MetadataSections [0].Metadata;
  471. label.EnterScope ("wsdl");
  472. label.EnterScope ("bindings");
  473. Assert.That (sd.Bindings.Count, Is.EqualTo (1), label.Get ());
  474. var binding = sd.Bindings [0];
  475. Assert.That (binding.ExtensibleAttributes, Is.Null, label.Get ());
  476. Assert.That (binding.Extensions, Is.Not.Null, label.Get ());
  477. WS.Soap12Binding soap = null;
  478. XmlElement xml = null;
  479. foreach (var ext in binding.Extensions) {
  480. if (ext is WS.Soap12Binding)
  481. soap = (WS.Soap12Binding)ext;
  482. else if (ext is XmlElement)
  483. xml = (XmlElement)ext;
  484. }
  485. CheckSoapBinding (soap, "http://schemas.microsoft.com/soap/tcp", label);
  486. label.EnterScope ("policy-xml");
  487. Assert.That (xml, Is.Not.Null, label.Get ());
  488. var assertions = AssertPolicy (sd, xml, label);
  489. Assert.That (assertions, Is.Not.Null, label.Get ());
  490. AssertPolicy (assertions, BinaryEncodingQName, label);
  491. AssertPolicy (assertions, UsingAddressingQName, label);
  492. if (transferMode == TransferMode.Streamed)
  493. AssertPolicy (assertions, StreamedTransferQName, label);
  494. switch (security) {
  495. case SecurityMode.Message:
  496. AssertPolicy (assertions, SymmetricBindingQName, label);
  497. AssertPolicy (assertions, Wss11QName, label);
  498. AssertPolicy (assertions, Trust10QName, label);
  499. break;
  500. case SecurityMode.Transport:
  501. AssertPolicy (assertions, TransportBindingQName, label);
  502. break;
  503. case SecurityMode.TransportWithMessageCredential:
  504. AssertPolicy (assertions, TransportBindingQName, label);
  505. AssertPolicy (assertions, EndorsingSupportingQName, label);
  506. AssertPolicy (assertions, Wss11QName, label);
  507. AssertPolicy (assertions, Trust10QName, label);
  508. break;
  509. default:
  510. break;
  511. }
  512. if (reliableSession)
  513. AssertPolicy (assertions, ReliableSessionQName, label);
  514. Assert.That (assertions.Count, Is.EqualTo (0), label.Get ());
  515. label.LeaveScope ();
  516. label.EnterScope ("services");
  517. Assert.That (sd.Services, Is.Not.Null, label.Get ());
  518. Assert.That (sd.Services.Count, Is.EqualTo (1), label.Get ());
  519. var service = sd.Services [0];
  520. Assert.That (service.Ports, Is.Not.Null, label.Get ());
  521. Assert.That (service.Ports.Count, Is.EqualTo (1), label.Get ());
  522. var port = service.Ports [0];
  523. label.EnterScope ("port");
  524. Assert.That (port.Extensions, Is.Not.Null, label.Get ());
  525. Assert.That (port.Extensions.Count, Is.EqualTo (2), label.Get ());
  526. WS.Soap12AddressBinding soap_addr_binding = null;
  527. XmlElement port_xml = null;
  528. foreach (var extension in port.Extensions) {
  529. if (extension is WS.Soap12AddressBinding)
  530. soap_addr_binding = (WS.Soap12AddressBinding)extension;
  531. else if (extension is XmlElement)
  532. port_xml = (XmlElement)extension;
  533. else
  534. Assert.Fail (label.Get ());
  535. }
  536. Assert.That (soap_addr_binding, Is.Not.Null, label.Get ());
  537. Assert.That (port_xml, Is.Not.Null, label.Get ());
  538. Assert.That (port_xml.NamespaceURI, Is.EqualTo (Wsa10Namespace), label.Get ());
  539. Assert.That (port_xml.LocalName, Is.EqualTo ("EndpointReference"), label.Get ());
  540. label.LeaveScope ();
  541. label.LeaveScope ();
  542. label.LeaveScope (); // wsdl
  543. var importer = new WsdlImporter (doc);
  544. label.EnterScope ("bindings");
  545. var bindings = importer.ImportAllBindings ();
  546. CheckImportErrors (importer, label);
  547. Assert.That (bindings, Is.Not.Null, label.Get ());
  548. Assert.That (bindings.Count, Is.EqualTo (1), label.Get ());
  549. CheckNetTcpBinding (
  550. bindings [0], security, reliableSession,
  551. transferMode, label);
  552. label.LeaveScope ();
  553. label.EnterScope ("endpoints");
  554. var endpoints = importer.ImportAllEndpoints ();
  555. CheckImportErrors (importer, label);
  556. Assert.That (endpoints, Is.Not.Null, label.Get ());
  557. Assert.That (endpoints.Count, Is.EqualTo (1), label.Get ());
  558. CheckEndpoint (endpoints [0], MetadataSamples.NetTcpUri, label);
  559. label.LeaveScope ();
  560. label.LeaveScope ();
  561. }
  562. public static void Dump (PolicyAssertionCollection assertions)
  563. {
  564. foreach (var assertion in assertions)
  565. Console.WriteLine ("ASSERTION: {0}", assertion.OuterXml);
  566. }
  567. public static void AssertPolicy (
  568. PolicyAssertionCollection assertions, QName qname, TestLabel label)
  569. {
  570. var assertion = assertions.Find (qname.Name, qname.Namespace);
  571. label.EnterScope (qname.Name);
  572. Assert.That (assertion, Is.Not.Null, label.ToString ());
  573. assertions.Remove (assertion);
  574. label.LeaveScope ();
  575. }
  576. static XmlElement ResolvePolicy (WS.ServiceDescription sd, XmlElement policy)
  577. {
  578. if (policy.LocalName.Equals ("Policy"))
  579. return policy;
  580. var uri = policy.GetAttribute ("URI");
  581. if (!uri.StartsWith ("#"))
  582. return null;
  583. foreach (var sext in sd.Extensions) {
  584. var sxml = sext as XmlElement;
  585. if (sxml == null)
  586. continue;
  587. if (!sxml.NamespaceURI.Equals (WspNamespace))
  588. continue;
  589. if (!sxml.LocalName.Equals ("Policy"))
  590. continue;
  591. var id = sxml.GetAttribute ("Id", WsuNamespace);
  592. if (uri.Substring (1).Equals (id))
  593. return sxml;
  594. }
  595. return null;
  596. }
  597. public static PolicyAssertionCollection AssertPolicy (
  598. WS.Binding binding, TestLabel label)
  599. {
  600. label.EnterScope ("FindPolicy");
  601. XmlElement policy = null;
  602. foreach (var extension in binding.Extensions) {
  603. var xml = extension as XmlElement;
  604. if (xml == null)
  605. continue;
  606. Assert.That (policy, Is.Null, label.Get ());
  607. policy = xml;
  608. }
  609. Assert.That (policy, Is.Not.Null, label.Get ());
  610. try {
  611. return AssertPolicy (binding.ServiceDescription, policy, label);
  612. } finally {
  613. label.LeaveScope ();
  614. }
  615. }
  616. static XmlElement AssertExactlyOneChildElement (XmlElement element)
  617. {
  618. XmlElement found = null;
  619. foreach (var node in element.ChildNodes) {
  620. if (node is XmlWhitespace)
  621. continue;
  622. var e = node as XmlElement;
  623. if (e == null)
  624. return null;
  625. if (found != null)
  626. return null;
  627. found = e;
  628. }
  629. return found;
  630. }
  631. public static PolicyAssertionCollection AssertPolicy (
  632. WS.ServiceDescription sd, XmlElement element, TestLabel label)
  633. {
  634. label.EnterScope ("wsp:Policy");
  635. Assert.That (element.NamespaceURI, Is.EqualTo (WspNamespace), label.Get ());
  636. Assert.That (element.LocalName, Is.EqualTo ("Policy") | Is.EqualTo ("PolicyReference"), label.Get ());
  637. var policy = ResolvePolicy (sd, element);
  638. Assert.That (policy, Is.Not.Null, label.Get ());
  639. label.EnterScope ("wsp:ExactlyOne");
  640. var exactlyOne = AssertExactlyOneChildElement (policy);
  641. Assert.That (exactlyOne, Is.Not.Null, label.Get ());
  642. Assert.That (exactlyOne.NamespaceURI, Is.EqualTo (WspNamespace), label.Get ());
  643. Assert.That (exactlyOne.LocalName, Is.EqualTo ("ExactlyOne"), label.Get ());
  644. label.LeaveScope ();
  645. label.EnterScope ("wsp:Any");
  646. var all = AssertExactlyOneChildElement (exactlyOne);
  647. Assert.That (all, Is.Not.Null, label.Get ());
  648. Assert.That (all.NamespaceURI, Is.EqualTo (WspNamespace), label.Get ());
  649. Assert.That (all.LocalName, Is.EqualTo ("All"), label.Get ());
  650. label.LeaveScope ();
  651. var collection = new PolicyAssertionCollection ();
  652. label.EnterScope ("assertions");
  653. foreach (var node in all.ChildNodes) {
  654. if (node is XmlWhitespace)
  655. continue;
  656. Assert.That (node, Is.InstanceOfType (typeof (XmlElement)), label.ToString ());
  657. collection.Add ((XmlElement)node);
  658. }
  659. label.LeaveScope ();
  660. label.LeaveScope ();
  661. return collection;
  662. }
  663. public static void TestOperation (MetadataSet metadata, bool soap12, TestLabel label)
  664. {
  665. label.EnterScope ("TestOperation");
  666. label.EnterScope ("metadata");
  667. WS.ServiceDescription sd = null;
  668. foreach (var ms in metadata.MetadataSections) {
  669. if (!ms.Dialect.Equals ("http://schemas.xmlsoap.org/wsdl/"))
  670. continue;
  671. sd = ms.Metadata as WS.ServiceDescription;
  672. }
  673. Assert.That (sd, Is.Not.Null, label.Get ());
  674. Assert.That (sd.Bindings, Is.Not.Null, label.Get ());
  675. Assert.That (sd.Bindings.Count, Is.EqualTo (1), label.Get ());
  676. var binding = sd.Bindings [0];
  677. label.LeaveScope ();
  678. label.EnterScope ("operation");
  679. Assert.That (binding.Operations, Is.Not.Null, label.Get ());
  680. Assert.That (binding.Operations.Count, Is.EqualTo (1), label.Get ());
  681. var op = binding.Operations [0];
  682. Assert.That (op.Name, Is.EqualTo ("Hello"), label.Get ());
  683. Assert.That (op.ExtensibleAttributes, Is.Null, label.Get ());
  684. label.EnterScope ("extensions");
  685. Assert.That (op.Extensions, Is.Not.Null, label.Get ());
  686. Assert.That (op.Extensions.Count, Is.EqualTo (1), label.Get ());
  687. Assert.That (op.Extensions [0], Is.InstanceOfType (typeof (WS.SoapOperationBinding)), label.Get ());
  688. var soap = (WS.SoapOperationBinding)op.Extensions [0];
  689. TestSoap (soap, soap12, label);
  690. label.LeaveScope ();
  691. TestSoapMessage (op.Input, soap12, label);
  692. TestSoapMessage (op.Output, soap12, label);
  693. label.LeaveScope (); // operation
  694. label.LeaveScope ();
  695. }
  696. static void TestSoap (WS.SoapOperationBinding soap, bool soap12, TestLabel label)
  697. {
  698. label.EnterScope ("soap");
  699. var type = soap12 ? typeof (WS.Soap12OperationBinding) : typeof (WS.SoapOperationBinding);
  700. Assert.That (soap.GetType (), Is.EqualTo (type), label.Get ());
  701. Assert.That (soap.Style, Is.EqualTo (WS.SoapBindingStyle.Document), label.Get ());
  702. Assert.That (soap.SoapAction, Is.EqualTo ("http://tempuri.org/IMyContract/Hello"), label.Get ());
  703. Assert.That (soap.Required, Is.False, label.Get ());
  704. label.LeaveScope ();
  705. }
  706. static void TestSoapMessage (WS.MessageBinding binding, bool soap12, TestLabel label)
  707. {
  708. label.EnterScope (binding is WS.InputBinding ? "input" : "output");
  709. Assert.That (binding, Is.Not.Null, label.Get ());
  710. Assert.That (binding.Name, Is.Null, label.Get ());
  711. Assert.That (binding.ExtensibleAttributes, Is.Null, label.Get ());
  712. Assert.That (binding.Extensions, Is.Not.Null, label.Get ());
  713. Assert.That (binding.Extensions.Count, Is.EqualTo (1), label.Get ());
  714. Assert.That (binding.Extensions [0], Is.InstanceOfType (typeof (WS.SoapBodyBinding)), label.Get ());
  715. var body = (WS.SoapBodyBinding)binding.Extensions [0];
  716. TestSoapBody (body, soap12, label);
  717. label.LeaveScope ();
  718. }
  719. static void TestSoapBody (WS.SoapBodyBinding soap, bool soap12, TestLabel label)
  720. {
  721. label.EnterScope ("soap-body");
  722. var type = soap12 ? typeof (WS.Soap12BodyBinding) : typeof (WS.SoapBodyBinding);
  723. Assert.That (soap.GetType (), Is.EqualTo (type), label.Get ());
  724. Assert.That (soap.Encoding, Is.Empty, label.Get ());
  725. Assert.That (soap.Namespace, Is.Empty, label.Get ());
  726. Assert.That (soap.Parts, Is.Null, label.Get ());
  727. Assert.That (soap.Use, Is.EqualTo (WS.SoapBindingUse.Literal), label.Get ());
  728. label.LeaveScope ();
  729. }
  730. public static void AssertConfig (MetadataSet metadata, XmlDocument xml, TestLabel label)
  731. {
  732. label.EnterScope ("import");
  733. var importer = new WsdlImporter (metadata);
  734. var endpoints = importer.ImportAllEndpoints ();
  735. CheckImportErrors (importer, label);
  736. Assert.That (endpoints.Count, Is.AtLeast (1), label.Get ());
  737. label.LeaveScope ();
  738. var nav = xml.CreateNavigator ();
  739. // FIXME: Check endpoints.
  740. label.EnterScope ("endpoints");
  741. var endpointIter = nav.Select ("/configuration/system.serviceModel/client/endpoint");
  742. Assert.That (endpointIter.Count, Is.EqualTo (endpoints.Count), label.Get ());
  743. label.LeaveScope ();
  744. }
  745. }
  746. }