PageRenderTime 39ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/sdk/test/UnitTests/Custom/TestTools/RequestValidator.cs

https://gitlab.com/CORP-RESELLER/aws-sdk-net
C# | 312 lines | 273 code | 32 blank | 7 comment | 70 complexity | 122e81b88a00ebae0b9ac88fb6b1ef53 MD5 | raw file
  1. using Amazon.Runtime.Internal;
  2. using Microsoft.VisualStudio.TestTools.UnitTesting;
  3. using ServiceClientGenerator;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Reflection;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. namespace AWSSDK_DotNet35.UnitTests.TestTools
  13. {
  14. public abstract class RequestValidator
  15. {
  16. public static void Validate(string operation, object request, IRequest marshalledRequest, ServiceModel serviceModel)
  17. {
  18. switch (serviceModel.Type)
  19. {
  20. //case ServiceType.Json:
  21. // break;
  22. //case ServiceType.Query:
  23. // break;
  24. case ServiceType.Rest_Xml:
  25. new RestXmlValidator(operation, request, marshalledRequest, serviceModel).Validate();
  26. break;
  27. case ServiceType.Rest_Json:
  28. case ServiceType.Json:
  29. new RestJsonValidator(operation, request, marshalledRequest, serviceModel).Validate();
  30. break;
  31. default:
  32. throw new InvalidOperationException();
  33. }
  34. }
  35. }
  36. public abstract class RequestValidator<T> : RequestValidator
  37. {
  38. protected ServiceModel ServiceModel { get; set; }
  39. protected object Request { get; set; }
  40. protected IRequest MarshalledRequest { get; set; }
  41. protected Operation Operation { get; set; }
  42. public RequestValidator(string operation, object request, IRequest marshalledRequest, ServiceModel serviceModel)
  43. {
  44. this.ServiceModel = serviceModel;
  45. this.Request = request;
  46. this.MarshalledRequest = marshalledRequest;
  47. this.Operation = serviceModel.FindOperation(operation);
  48. }
  49. public virtual void Validate()
  50. {
  51. var type = this.Request.GetType();
  52. ValidateHeaders(type.GetProperties());
  53. ValidateQueryParameters(type.GetProperties());
  54. ValidateUriParameters(type.GetProperties());
  55. ValidateStreamingContent();
  56. ValidateBody();
  57. }
  58. protected abstract T GetMarshalledData(byte[] content);
  59. protected virtual void ValidateBody()
  60. {
  61. var payload = this.Operation.RequestPayloadMember;
  62. var payloadMarshalled = payload != null && payload.IsStructure;
  63. if (this.Operation.RequestHasBodyMembers || payloadMarshalled)
  64. {
  65. Assert.IsTrue(this.MarshalledRequest.Content.Count() > 0);
  66. T marshalledData = GetMarshalledData(this.MarshalledRequest.Content);
  67. var parentType = this.Operation.RequestPayloadMember == null ?
  68. this.Request.GetType() :
  69. this.Request.GetType().GetProperties().Single(p => p.Name == this.Operation.RequestPayloadMember.PropertyName).PropertyType;
  70. var parentObject = this.Operation.RequestPayloadMember == null ?
  71. this.Request :
  72. this.Request.GetType().GetProperties().Single(p => p.Name == this.Operation.RequestPayloadMember.PropertyName).GetValue(this.Request);
  73. var members = this.Operation.RequestPayloadMember == null ?
  74. this.Operation.RequestBodyMembers :
  75. this.Operation.RequestPayloadMember.Shape.Members;
  76. foreach (var property in parentType.GetProperties(BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance))
  77. {
  78. if (this.Operation.RequestHeaderMembers.Any(m=>m.PropertyName == property.Name) ||
  79. this.Operation.RequestQueryStringMembers.Any(m => m.PropertyName == property.Name) ||
  80. this.Operation.RequestUriMembers.Any(m => m.PropertyName == property.Name))
  81. {
  82. continue;
  83. }
  84. if (property.PropertyType.BaseType.FullName == "System.MulticastDelegate")
  85. {
  86. continue;
  87. }
  88. var childMember = members.Single(m => m.PropertyName == property.Name);
  89. var childValue = property.GetValue(parentObject);
  90. var childMarshalledData = GetMarshalledProperty(marshalledData, childMember.MarshallName);
  91. Visit(childValue, childMember, childMarshalledData);
  92. }
  93. }
  94. else
  95. {
  96. Assert.IsNull(this.MarshalledRequest.Content);
  97. }
  98. }
  99. protected abstract T GetMarshalledProperty(T marshalledData, string propertyName);
  100. void Visit(object value, Member member, T marshalledData)
  101. {
  102. var type = value.GetType();
  103. if (type.IsPrimitive || type == typeof(string))
  104. {
  105. ValidateProperty(value, member, marshalledData);
  106. }
  107. else if (type == typeof(DateTime))
  108. {
  109. ValidateProperty(value, member, marshalledData);
  110. }
  111. else if (type == typeof(MemoryStream))
  112. {
  113. ValidateProperty(value, member, marshalledData);
  114. }
  115. else if (type.BaseType.FullName == "Amazon.Runtime.ConstantClass")
  116. {
  117. ValidateProperty(value.ToString(), member, marshalledData);
  118. }
  119. else if (type.GetInterface("System.Collections.IList") != null)
  120. {
  121. var list = value as IList;
  122. Assert.IsTrue(member.IsList);
  123. ValidateList(list, member, marshalledData);
  124. var enumerator = GetMarshalledListItem(marshalledData).GetEnumerator();
  125. foreach (var item in list)
  126. {
  127. enumerator.MoveNext();
  128. var marshalledListData = enumerator.Current;
  129. ValidateListMember(item, member.Shape, marshalledListData);
  130. if (member.Shape.ListShape.IsStructure)
  131. {
  132. // It's a list of complex type
  133. foreach (var property in item.GetType().GetProperties(BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance))
  134. {
  135. var childMember = member.Shape.ListShape.Members.Single(m => m.PropertyName == property.Name);
  136. var childValue = property.GetValue(item);
  137. var childMarshalledData = GetMarshalledProperty(marshalledListData, childMember.MarshallName);
  138. Visit(childValue, childMember, childMarshalledData);
  139. }
  140. }
  141. }
  142. }
  143. else if (type.GetInterface("System.Collections.IDictionary") != null)
  144. {
  145. var map = value as IDictionary;
  146. Assert.IsTrue(member.IsMap);
  147. ValidateMap(map, member, marshalledData);
  148. var enumerator = GetMarshalledMapKey(marshalledData).GetEnumerator();
  149. foreach (var item in map.Keys)
  150. {
  151. enumerator.MoveNext();
  152. var marshalledKey = enumerator.Current;
  153. ValidateMapKey(item, member, marshalledKey);
  154. var marshalledValue = GetMarshalledMapValue(marshalledData, marshalledKey);
  155. var mapValue = map[item];
  156. if (member.Shape.ValueShape.IsStructure)
  157. {
  158. // Map's value is of complex type
  159. ValidateMapValue(mapValue, member, marshalledValue);
  160. foreach (var property in mapValue.GetType().GetProperties(BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance))
  161. {
  162. var childMember = member.Shape.ValueShape.Members.Single(m => m.PropertyName == property.Name);
  163. var childValue = property.GetValue(mapValue);
  164. var childMarshalledData = GetMarshalledProperty(marshalledValue, childMember.MarshallName);
  165. Visit(childValue, childMember, childMarshalledData);
  166. }
  167. }
  168. else
  169. {
  170. ValidateMapValue(mapValue, member, marshalledValue);
  171. }
  172. }
  173. }
  174. else
  175. {
  176. // It's a complex type
  177. foreach (var property in type.GetProperties(BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance))
  178. {
  179. var childMember = member.Shape.Members.Single(m => m.PropertyName == property.Name);
  180. var childValue = property.GetValue(value);
  181. var childMarshalledData = GetMarshalledProperty(marshalledData, childMember.MarshallName);
  182. Visit(childValue, childMember, childMarshalledData);
  183. }
  184. }
  185. }
  186. private void ValidateMap(IDictionary map, Member member, T marshalledData) { }
  187. protected virtual void ValidateList(IList list, Member member, T marshalledData) { }
  188. protected virtual void ValidateMapValue(object mapValue, Member member, T marshalledValue) { }
  189. protected virtual void ValidateMapKey(object item, Member member, object marshalledKey) { }
  190. protected virtual void ValidateListMember(object item, Shape shapeWrapper, T marshalledListData) { }
  191. protected virtual void ValidateProperty(object value, Member member, T marshalledData) { }
  192. protected abstract IEnumerable<T> GetMarshalledListItem(T marshalledData);
  193. protected abstract IEnumerable<object> GetMarshalledMapKey(T marshalledData);
  194. protected abstract T GetMarshalledMapValue(T marshalledData, object key);
  195. private void ValidateStreamingContent()
  196. {
  197. var payload = this.Operation.RequestPayloadMember;
  198. if (payload != null && !payload.IsStructure)
  199. {
  200. Assert.IsTrue(this.MarshalledRequest.Headers.ContainsKey("Content-Type"));
  201. if (!this.Operation.RequestHeaderMembers.Any(h => h.MarshallLocationName.ToLower() == "content-type"))
  202. {
  203. Assert.AreEqual("binary/octet-stream", this.MarshalledRequest.Headers["Content-Type"]);
  204. }
  205. Assert.IsNotNull(this.MarshalledRequest.ContentStream);
  206. }
  207. else
  208. {
  209. Assert.IsNull(this.MarshalledRequest.ContentStream);
  210. }
  211. }
  212. protected void ValidateHeaders(IEnumerable<PropertyInfo> properties)
  213. {
  214. foreach (var property in properties)
  215. {
  216. if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
  217. {
  218. var member = this.Operation.RequestHeaderMembers.SingleOrDefault(m =>
  219. m.PropertyName == property.Name);
  220. if (member != null)
  221. {
  222. Assert.IsTrue(this.MarshalledRequest.Headers.ContainsKey(member.MarshallLocationName));
  223. if (member.OverrideDataType == null)
  224. Assert.AreEqual(property.GetValue(this.Request), this.MarshalledRequest.Headers[member.MarshallLocationName]);
  225. }
  226. }
  227. }
  228. }
  229. protected void ValidateQueryParameters(IEnumerable<PropertyInfo> properties)
  230. {
  231. if (this.Operation.RequestQueryStringMembers.Count() > 0)
  232. {
  233. foreach (var property in properties)
  234. {
  235. if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
  236. {
  237. var member = this.Operation.RequestQueryStringMembers.SingleOrDefault(m =>
  238. m.PropertyName == property.Name);
  239. if (member == null)
  240. continue;
  241. Assert.IsTrue(this.MarshalledRequest.Parameters.ContainsKey(member.MarshallLocationName));
  242. var value = this.MarshalledRequest.Parameters[member.MarshallLocationName];
  243. var convertedValue = Convert.ChangeType(value, property.PropertyType);
  244. Assert.AreEqual(property.GetValue(this.Request), convertedValue);
  245. }
  246. }
  247. }
  248. }
  249. protected void ValidateUriParameters(IEnumerable<PropertyInfo> properties)
  250. {
  251. if (this.Operation.RequestUriMembers.Count() > 0)
  252. {
  253. var uri = this.MarshalledRequest.ResourcePath.Split('?')[0];
  254. var uriSegments = uri.Split('/');
  255. var operationUri = this.Operation.RequestUri.Split('?')[0];
  256. var operationUriSegments = operationUri.Split('/');
  257. foreach (var property in properties)
  258. {
  259. if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
  260. {
  261. var member = this.Operation.RequestUriMembers.SingleOrDefault(m =>
  262. m.PropertyName == property.Name);
  263. if (member != null)
  264. {
  265. var index = -1;
  266. for (int i = 0; i < operationUriSegments.Length; i++)
  267. {
  268. if (operationUriSegments[i] == string.Format("{{{0}}}", member.MarshallLocationName))
  269. {
  270. index = i; break;
  271. }
  272. }
  273. Assert.AreEqual(property.GetValue(this.Request), Convert.ChangeType(uriSegments[index], property.PropertyType));
  274. }
  275. }
  276. }
  277. }
  278. }
  279. }
  280. }