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

/src/ResourceManager/Profile/Commands.Profile.Test/RPRegistrationDelegatingHandlerTests.cs

https://gitlab.com/jslee1/azure-powershell
C# | 308 lines | 249 code | 28 blank | 31 comment | 0 complexity | 09de4c25bda39474d82a1dd04aee241f MD5 | raw file
  1. // ----------------------------------------------------------------------------------
  2. //
  3. // Copyright Microsoft Corporation
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. // ----------------------------------------------------------------------------------
  14. using Hyak.Common;
  15. using Microsoft.Azure.Commands.Common.Authentication.Models;
  16. using Microsoft.Azure.Management.Internal.Resources;
  17. using Microsoft.Azure.Management.Internal.Resources.Models;
  18. using Microsoft.Azure.ServiceManagemenet.Common.Models;
  19. using Microsoft.WindowsAzure.Commands.ScenarioTest;
  20. using Microsoft.WindowsAzure.Commands.Test.Utilities.Common;
  21. using Moq;
  22. using System.Collections.Generic;
  23. using System.Linq;
  24. using System.Net;
  25. using System.Net.Http;
  26. using System.Threading;
  27. using System.Threading.Tasks;
  28. using Xunit;
  29. using Xunit.Abstractions;
  30. namespace Microsoft.Azure.Commands.Profile.Test
  31. {
  32. public class RPRegistrationDelegatingHandlerTests : RMTestBase
  33. {
  34. private const string compatibleUri = "https://management.azure.com/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/Microsoft.Compute/virtualMachines/{vm-name}?validating={true|false}&api-version={api-version}";
  35. private const string incompatibleUri = "https://management.core.windows.net/<subscription-id>";
  36. public RPRegistrationDelegatingHandlerTests(ITestOutputHelper output)
  37. {
  38. XunitTracingInterceptor.AddToContext(new XunitTracingInterceptor(output));
  39. }
  40. [Fact]
  41. [Trait(Category.AcceptanceType, Category.CheckIn)]
  42. public void InvokeRegistrationForUnregisteredResourceProviders()
  43. {
  44. // Setup
  45. Mock<ResourceManagementClient> mockClient = new Mock<ResourceManagementClient>();
  46. Mock<IProviderOperations> mockProvidersOperations = new Mock<IProviderOperations>();
  47. mockClient.Setup(f => f.Providers).Returns(mockProvidersOperations.Object);
  48. mockProvidersOperations.Setup(f => f.GetAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())).Returns(
  49. (string rp, CancellationToken token) =>
  50. {
  51. ProviderGetResult r = new ProviderGetResult
  52. {
  53. Provider = new Provider
  54. {
  55. RegistrationState = RegistrationState.Registered.ToString()
  56. }
  57. };
  58. return Task.FromResult(r);
  59. }
  60. );
  61. HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, compatibleUri);
  62. Dictionary<HttpRequestMessage, List<HttpResponseMessage>> mapping = new Dictionary<HttpRequestMessage, List<HttpResponseMessage>>
  63. {
  64. {
  65. request, new List<HttpResponseMessage>
  66. {
  67. new HttpResponseMessage(HttpStatusCode.Conflict) { Content = new StringContent("registered to use namespace") },
  68. new HttpResponseMessage(HttpStatusCode.Accepted) { Content = new StringContent("Azure works!") }
  69. }
  70. }
  71. };
  72. List<string> msgs = new List<string>();
  73. RPRegistrationDelegatingHandler rpHandler = new RPRegistrationDelegatingHandler(() => mockClient.Object, s => msgs.Add(s))
  74. {
  75. InnerHandler = new MockResponseDelegatingHandler(mapping)
  76. };
  77. HttpClient httpClient = new HttpClient(rpHandler);
  78. // Test
  79. HttpResponseMessage response = httpClient.SendAsync(request).Result;
  80. // Assert
  81. Assert.True(msgs.Any(s => s.Equals("Succeeded to register resource provider 'microsoft.compute'")));
  82. Assert.Equal(response.StatusCode, HttpStatusCode.Accepted);
  83. Assert.Equal(response.Content.ReadAsStringAsync().Result, "Azure works!");
  84. }
  85. [Fact]
  86. [Trait(Category.AcceptanceType, Category.CheckIn)]
  87. public void DoesNotInvokeRegistrationForRegisteredResourceProviders()
  88. {
  89. // Setup
  90. Mock<ResourceManagementClient> mockClient = new Mock<ResourceManagementClient>();
  91. Mock<IProviderOperations> mockProvidersOperations = new Mock<IProviderOperations>();
  92. mockClient.Setup(f => f.Providers).Returns(mockProvidersOperations.Object);
  93. HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, compatibleUri);
  94. Dictionary<HttpRequestMessage, List<HttpResponseMessage>> mapping = new Dictionary<HttpRequestMessage, List<HttpResponseMessage>>
  95. {
  96. {
  97. request, new List<HttpResponseMessage>
  98. {
  99. new HttpResponseMessage(HttpStatusCode.Accepted) { Content = new StringContent("Azure works!") }
  100. }
  101. }
  102. };
  103. List<string> msgs = new List<string>();
  104. RPRegistrationDelegatingHandler rpHandler = new RPRegistrationDelegatingHandler(() => mockClient.Object, s => msgs.Add(s))
  105. {
  106. InnerHandler = new MockResponseDelegatingHandler(mapping)
  107. };
  108. HttpClient httpClient = new HttpClient(rpHandler);
  109. // Test
  110. HttpResponseMessage response = httpClient.SendAsync(request).Result;
  111. // Assert
  112. Assert.Equal(0, msgs.Count);
  113. Assert.Equal(response.StatusCode, HttpStatusCode.Accepted);
  114. Assert.Equal(response.Content.ReadAsStringAsync().Result, "Azure works!");
  115. }
  116. [Fact]
  117. [Trait(Category.AcceptanceType, Category.CheckIn)]
  118. public void DoesNotInvokeRegistrationForUnrelatedStatusCode()
  119. {
  120. // Setup
  121. Mock<ResourceManagementClient> mockClient = new Mock<ResourceManagementClient>();
  122. Mock<IProviderOperations> mockProvidersOperations = new Mock<IProviderOperations>();
  123. mockClient.Setup(f => f.Providers).Returns(mockProvidersOperations.Object);
  124. HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, compatibleUri);
  125. Dictionary<HttpRequestMessage, List<HttpResponseMessage>> mapping = new Dictionary<HttpRequestMessage, List<HttpResponseMessage>>
  126. {
  127. {
  128. request, new List<HttpResponseMessage>
  129. {
  130. new HttpResponseMessage(HttpStatusCode.Forbidden) { Content = new StringContent("auth error!") }
  131. }
  132. }
  133. };
  134. List<string> msgs = new List<string>();
  135. RPRegistrationDelegatingHandler rpHandler = new RPRegistrationDelegatingHandler(() => mockClient.Object, s => msgs.Add(s))
  136. {
  137. InnerHandler = new MockResponseDelegatingHandler(mapping)
  138. };
  139. HttpClient httpClient = new HttpClient(rpHandler);
  140. // Test
  141. HttpResponseMessage response = httpClient.SendAsync(request).Result;
  142. // Assert
  143. Assert.Equal(0, msgs.Count);
  144. Assert.Equal(response.StatusCode, HttpStatusCode.Forbidden);
  145. Assert.Equal(response.Content.ReadAsStringAsync().Result, "auth error!");
  146. }
  147. [Fact]
  148. [Trait(Category.AcceptanceType, Category.CheckIn)]
  149. public void DoesNotInvokeRegistrationForIncompatibleUri()
  150. {
  151. // Setup
  152. Mock<ResourceManagementClient> mockClient = new Mock<ResourceManagementClient>();
  153. Mock<IProviderOperations> mockProvidersOperations = new Mock<IProviderOperations>();
  154. mockClient.Setup(f => f.Providers).Returns(mockProvidersOperations.Object);
  155. HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, incompatibleUri);
  156. Dictionary<HttpRequestMessage, List<HttpResponseMessage>> mapping = new Dictionary<HttpRequestMessage, List<HttpResponseMessage>>
  157. {
  158. {
  159. request, new List<HttpResponseMessage>
  160. {
  161. new HttpResponseMessage(HttpStatusCode.Conflict) { Content = new StringContent("registered to use namespace") }
  162. }
  163. }
  164. };
  165. List<string> msgs = new List<string>();
  166. RPRegistrationDelegatingHandler rpHandler = new RPRegistrationDelegatingHandler(() => mockClient.Object, s => msgs.Add(s))
  167. {
  168. InnerHandler = new MockResponseDelegatingHandler(mapping)
  169. };
  170. HttpClient httpClient = new HttpClient(rpHandler);
  171. // Test
  172. HttpResponseMessage response = httpClient.SendAsync(request).Result;
  173. // Assert
  174. Assert.Equal(0, msgs.Count);
  175. Assert.Equal(response.StatusCode, HttpStatusCode.Conflict);
  176. Assert.Equal(response.Content.ReadAsStringAsync().Result, "registered to use namespace");
  177. }
  178. [Fact]
  179. [Trait(Category.AcceptanceType, Category.CheckIn)]
  180. public void DoesNotHangForLongRegistrationCalls()
  181. {
  182. // Setup
  183. Mock<ResourceManagementClient> mockClient = new Mock<ResourceManagementClient>();
  184. Mock<IProviderOperations> mockProvidersOperations = new Mock<IProviderOperations>();
  185. mockClient.Setup(f => f.Providers).Returns(mockProvidersOperations.Object);
  186. mockProvidersOperations.Setup(f => f.GetAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())).Returns(
  187. (string rp, CancellationToken token) =>
  188. {
  189. ProviderGetResult r = new ProviderGetResult
  190. {
  191. Provider = new Provider
  192. {
  193. RegistrationState = RegistrationState.Pending.ToString()
  194. }
  195. };
  196. return Task.FromResult(r);
  197. }
  198. );
  199. HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, compatibleUri);
  200. Dictionary<HttpRequestMessage, List<HttpResponseMessage>> mapping = new Dictionary<HttpRequestMessage, List<HttpResponseMessage>>
  201. {
  202. {
  203. request, new List<HttpResponseMessage>
  204. {
  205. new HttpResponseMessage(HttpStatusCode.Conflict) { Content = new StringContent("registered to use namespace") },
  206. new HttpResponseMessage(HttpStatusCode.Conflict) { Content = new StringContent("registered to use namespace") }
  207. }
  208. }
  209. };
  210. List<string> msgs = new List<string>();
  211. RPRegistrationDelegatingHandler rpHandler = new RPRegistrationDelegatingHandler(() => mockClient.Object, s => msgs.Add(s))
  212. {
  213. InnerHandler = new MockResponseDelegatingHandler(mapping)
  214. };
  215. HttpClient httpClient = new HttpClient(rpHandler);
  216. // Test
  217. HttpResponseMessage response = httpClient.SendAsync(request).Result;
  218. // Assert
  219. Assert.True(msgs.Any(s => s.Equals("Failed to register resource provider 'microsoft.compute'.Details: 'The operation has timed out.'")));
  220. Assert.Equal(response.StatusCode, HttpStatusCode.Conflict);
  221. Assert.Equal(response.Content.ReadAsStringAsync().Result, "registered to use namespace");
  222. mockProvidersOperations.Verify(f => f.RegisterAsync("microsoft.compute", It.IsAny<CancellationToken>()), Times.AtMost(4));
  223. }
  224. [Fact]
  225. [Trait(Category.AcceptanceType, Category.CheckIn)]
  226. public void DoesNotThrowForFailedRegistrationCall()
  227. {
  228. // Setup
  229. Mock<ResourceManagementClient> mockClient = new Mock<ResourceManagementClient>();
  230. Mock<IProviderOperations> mockProvidersOperations = new Mock<IProviderOperations>();
  231. mockClient.Setup(f => f.Providers).Returns(mockProvidersOperations.Object);
  232. mockProvidersOperations.Setup(f => f.GetAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()))
  233. .Throws(new CloudException("PR reg failed"));
  234. HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, compatibleUri);
  235. Dictionary<HttpRequestMessage, List<HttpResponseMessage>> mapping = new Dictionary<HttpRequestMessage, List<HttpResponseMessage>>
  236. {
  237. {
  238. request, new List<HttpResponseMessage>
  239. {
  240. new HttpResponseMessage(HttpStatusCode.Conflict) { Content = new StringContent("registered to use namespace") },
  241. new HttpResponseMessage(HttpStatusCode.Conflict) { Content = new StringContent("registered to use namespace") }
  242. }
  243. }
  244. };
  245. List<string> msgs = new List<string>();
  246. RPRegistrationDelegatingHandler rpHandler = new RPRegistrationDelegatingHandler(() => mockClient.Object, s => msgs.Add(s))
  247. {
  248. InnerHandler = new MockResponseDelegatingHandler(mapping)
  249. };
  250. HttpClient httpClient = new HttpClient(rpHandler);
  251. // Test
  252. HttpResponseMessage response = httpClient.SendAsync(request).Result;
  253. // Assert
  254. Assert.True(msgs.Any(s => s.Equals("Failed to register resource provider 'microsoft.compute'.Details: 'PR reg failed'")));
  255. Assert.Equal(response.StatusCode, HttpStatusCode.Conflict);
  256. Assert.Equal(response.Content.ReadAsStringAsync().Result, "registered to use namespace");
  257. mockProvidersOperations.Verify(f => f.RegisterAsync("microsoft.compute", It.IsAny<CancellationToken>()), Times.AtMost(4));
  258. }
  259. }
  260. public class MockResponseDelegatingHandler : DelegatingHandler
  261. {
  262. Dictionary<HttpRequestMessage, List<HttpResponseMessage>> mapping;
  263. public int RequestsCount { get; set; }
  264. public MockResponseDelegatingHandler(Dictionary<HttpRequestMessage, List<HttpResponseMessage>> mapping)
  265. {
  266. this.mapping = mapping;
  267. this.RequestsCount = 0;
  268. }
  269. protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
  270. {
  271. return await Task.Run<HttpResponseMessage>(() =>
  272. {
  273. var response = mapping[request].First();
  274. mapping[request].Remove(response);
  275. RequestsCount++;
  276. return response;
  277. });
  278. }
  279. }
  280. }