PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Common/Commands.ScenarioTests.Common/EnvironmentSetupHelper.cs

https://gitlab.com/jslee1/azure-powershell
C# | 373 lines | 303 code | 47 blank | 23 comment | 46 complexity | 3c67ff7bcc268f4a28e3aca6a572c890 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 Microsoft.Azure;
  15. using Microsoft.Azure.Commands.Common.Authentication;
  16. using Microsoft.Azure.Commands.Common.Authentication.Models;
  17. using Microsoft.Azure.Test;
  18. using Microsoft.Azure.Test.HttpRecorder;
  19. using Microsoft.WindowsAzure.Commands.Common.Test.Mocks;
  20. using Microsoft.WindowsAzure.Commands.Utilities.Common;
  21. using System;
  22. using System.Collections.Generic;
  23. using System.Collections.ObjectModel;
  24. using System.Diagnostics;
  25. using System.IO;
  26. using System.Management.Automation;
  27. using System.Security.Cryptography.X509Certificates;
  28. using Microsoft.Azure.ServiceManagemenet.Common;
  29. using System.Text;
  30. using Microsoft.WindowsAzure.ServiceManagemenet.Common.Models;
  31. namespace Microsoft.WindowsAzure.Commands.ScenarioTest
  32. {
  33. public class EnvironmentSetupHelper
  34. {
  35. private static string testEnvironmentName = "__test-environment";
  36. private static string testSubscriptionName = "__test-subscriptions";
  37. private AzureSubscription testSubscription;
  38. private AzureAccount testAccount;
  39. private const string PackageDirectoryFromCommon = @"..\..\..\..\Package\Debug";
  40. public const string PackageDirectory = @"..\..\..\..\..\Package\Debug";
  41. protected List<string> modules;
  42. public XunitTracingInterceptor TracingInterceptor { get; set; }
  43. protected ProfileClient ProfileClient { get; set; }
  44. public EnvironmentSetupHelper()
  45. {
  46. var datastore = new MemoryDataStore();
  47. AzureSession.DataStore = datastore;
  48. var profile = new AzureSMProfile(Path.Combine(AzureSession.ProfileDirectory, AzureSession.ProfileFile));
  49. AzureSMCmdlet.CurrentProfile = profile;
  50. AzureSession.DataStore = datastore;
  51. ProfileClient = new ProfileClient(profile);
  52. // Ignore SSL errors
  53. System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => true;
  54. // Set RunningMocked
  55. if (HttpMockServer.GetCurrentMode() == HttpRecorderMode.Playback)
  56. {
  57. TestMockSupport.RunningMocked = true;
  58. }
  59. else
  60. {
  61. TestMockSupport.RunningMocked = false;
  62. }
  63. }
  64. /// <summary>
  65. /// Loads DummyManagementClientHelper with clients and throws exception if any client is missing.
  66. /// </summary>
  67. /// <param name="initializedManagementClients"></param>
  68. public void SetupManagementClients(params object[] initializedManagementClients)
  69. {
  70. AzureSession.ClientFactory = new MockClientFactory(initializedManagementClients);
  71. }
  72. /// <summary>
  73. /// Loads DummyManagementClientHelper with clients and sets it up to create missing clients dynamically.
  74. /// </summary>
  75. /// <param name="initializedManagementClients"></param>
  76. public void SetupSomeOfManagementClients(params object[] initializedManagementClients)
  77. {
  78. AzureSession.ClientFactory = new MockClientFactory(initializedManagementClients, false);
  79. }
  80. public void SetupEnvironment(AzureModule mode)
  81. {
  82. SetupAzureEnvironmentFromEnvironmentVariables(mode);
  83. ProfileClient.Profile.Save();
  84. }
  85. private void SetupAzureEnvironmentFromEnvironmentVariables(AzureModule mode)
  86. {
  87. TestEnvironment rdfeEnvironment = new RDFETestEnvironmentFactory().GetTestEnvironment();
  88. TestEnvironment csmEnvironment = new CSMTestEnvironmentFactory().GetTestEnvironment();
  89. TestEnvironment currentEnvironment = (mode == AzureModule.AzureResourceManager ? csmEnvironment : rdfeEnvironment);
  90. if (currentEnvironment.UserName == null)
  91. {
  92. currentEnvironment.UserName = "fakeuser@microsoft.com";
  93. }
  94. SetAuthenticationFactory(mode, rdfeEnvironment, csmEnvironment);
  95. AzureEnvironment environment = new AzureEnvironment { Name = testEnvironmentName };
  96. Debug.Assert(currentEnvironment != null);
  97. environment.Endpoints[AzureEnvironment.Endpoint.ActiveDirectory] = currentEnvironment.Endpoints.AADAuthUri.AbsoluteUri;
  98. environment.Endpoints[AzureEnvironment.Endpoint.Gallery] = currentEnvironment.Endpoints.GalleryUri.AbsoluteUri;
  99. if (csmEnvironment != null)
  100. {
  101. environment.Endpoints[AzureEnvironment.Endpoint.ResourceManager] = csmEnvironment.BaseUri.AbsoluteUri;
  102. }
  103. if (rdfeEnvironment != null)
  104. {
  105. environment.Endpoints[AzureEnvironment.Endpoint.ServiceManagement] = rdfeEnvironment.BaseUri.AbsoluteUri;
  106. }
  107. if (!ProfileClient.Profile.Environments.ContainsKey(testEnvironmentName))
  108. {
  109. ProfileClient.AddOrSetEnvironment(environment);
  110. }
  111. if (currentEnvironment.SubscriptionId != null)
  112. {
  113. testSubscription = new AzureSubscription()
  114. {
  115. Id = new Guid(currentEnvironment.SubscriptionId),
  116. Name = testSubscriptionName,
  117. Environment = testEnvironmentName,
  118. Account = currentEnvironment.UserName,
  119. Properties = new Dictionary<AzureSubscription.Property, string>
  120. {
  121. {AzureSubscription.Property.Default, "True"},
  122. {
  123. AzureSubscription.Property.StorageAccount,
  124. Environment.GetEnvironmentVariable("AZURE_STORAGE_ACCOUNT")
  125. },
  126. }
  127. };
  128. testAccount = new AzureAccount()
  129. {
  130. Id = currentEnvironment.UserName,
  131. Type = AzureAccount.AccountType.User,
  132. Properties = new Dictionary<AzureAccount.Property, string>
  133. {
  134. {AzureAccount.Property.Subscriptions, currentEnvironment.SubscriptionId},
  135. }
  136. };
  137. ProfileClient.Profile.Subscriptions[testSubscription.Id] = testSubscription;
  138. ProfileClient.Profile.Accounts[testAccount.Id] = testAccount;
  139. ProfileClient.SetSubscriptionAsDefault(testSubscription.Name, testSubscription.Account);
  140. }
  141. }
  142. private void SetAuthenticationFactory(AzureModule mode, TestEnvironment rdfeEnvironment, TestEnvironment csmEnvironment)
  143. {
  144. string jwtToken = null;
  145. X509Certificate2 certificate = null;
  146. TestEnvironment currentEnvironment = (mode == AzureModule.AzureResourceManager ? csmEnvironment : rdfeEnvironment);
  147. if (mode == AzureModule.AzureServiceManagement)
  148. {
  149. if (rdfeEnvironment.Credentials is TokenCloudCredentials)
  150. {
  151. jwtToken = ((TokenCloudCredentials)rdfeEnvironment.Credentials).Token;
  152. }
  153. if (rdfeEnvironment.Credentials is CertificateCloudCredentials)
  154. {
  155. certificate = ((CertificateCloudCredentials)rdfeEnvironment.Credentials).ManagementCertificate;
  156. }
  157. }
  158. else
  159. {
  160. if (csmEnvironment.Credentials is TokenCloudCredentials)
  161. {
  162. jwtToken = ((TokenCloudCredentials)csmEnvironment.Credentials).Token;
  163. }
  164. if (csmEnvironment.Credentials is CertificateCloudCredentials)
  165. {
  166. certificate = ((CertificateCloudCredentials)csmEnvironment.Credentials).ManagementCertificate;
  167. }
  168. }
  169. if (jwtToken != null)
  170. {
  171. AzureSession.AuthenticationFactory = new MockTokenAuthenticationFactory(currentEnvironment.UserName,
  172. jwtToken);
  173. }
  174. else if (certificate != null)
  175. {
  176. AzureSession.AuthenticationFactory = new MockCertificateAuthenticationFactory(currentEnvironment.UserName,
  177. certificate);
  178. }
  179. }
  180. public void SetupModules(AzureModule mode, params string[] modules)
  181. {
  182. this.modules = new List<string>();
  183. if (mode == AzureModule.AzureProfile)
  184. {
  185. this.modules.Add(Path.Combine(PackageDirectory, @"ResourceManager\AzureResourceManager\AzureRM.Profile\AzureRM.Profile.psd1"));
  186. this.modules.Add(Path.Combine(PackageDirectory, @"Storage\Azure.Storage\Azure.Storage.psd1"));
  187. this.modules.Add(Path.Combine(PackageDirectory, @"ServiceManagement\Azure\Azure.psd1"));
  188. this.modules.Add(Path.Combine(PackageDirectory, @"ResourceManager\AzureResourceManager\AzureResourceManager.psd1"));
  189. }
  190. else if (mode == AzureModule.AzureServiceManagement)
  191. {
  192. this.modules.Add(Path.Combine(PackageDirectory, @"ResourceManager\AzureResourceManager\AzureRM.Profile\AzureRM.Profile.psd1"));
  193. this.modules.Add(Path.Combine(PackageDirectory, @"Storage\Azure.Storage\Azure.Storage.psd1"));
  194. this.modules.Add(Path.Combine(PackageDirectory, @"ServiceManagement\Azure\Azure.psd1"));
  195. }
  196. else if (mode == AzureModule.AzureResourceManager)
  197. {
  198. this.modules.Add(Path.Combine(PackageDirectory, @"ResourceManager\AzureResourceManager\AzureResourceManager.psd1"));
  199. }
  200. else
  201. {
  202. throw new ArgumentException("Unknown command type for testing");
  203. }
  204. this.modules.Add("Assert.ps1");
  205. this.modules.Add("Common.ps1");
  206. this.modules.AddRange(modules);
  207. }
  208. public void SetupModulesFromCommon(AzureModule mode, params string[] modules)
  209. {
  210. this.modules = new List<string>();
  211. if (mode == AzureModule.AzureProfile)
  212. {
  213. this.modules.Add(Path.Combine(PackageDirectoryFromCommon, @"ResourceManager\AzureResourceManager\AzureRM.Profile\AzureRM.Profile.psd1"));
  214. this.modules.Add(Path.Combine(PackageDirectoryFromCommon, @"Storage\Azure.Storage\Azure.Storage.psd1"));
  215. this.modules.Add(Path.Combine(PackageDirectoryFromCommon, @"ServiceManagement\Azure\Azure.psd1"));
  216. this.modules.Add(Path.Combine(PackageDirectoryFromCommon, @"ResourceManager\AzureResourceManager\AzureResourceManager.psd1"));
  217. }
  218. else if (mode == AzureModule.AzureServiceManagement)
  219. {
  220. this.modules.Add(Path.Combine(PackageDirectoryFromCommon, @"ResourceManager\AzureResourceManager\AzureRM.Profile\AzureRM.Profile.psd1"));
  221. this.modules.Add(Path.Combine(PackageDirectoryFromCommon, @"Storage\Azure.Storage\Azure.Storage.psd1"));
  222. this.modules.Add(Path.Combine(PackageDirectoryFromCommon, @"ServiceManagement\Azure\Azure.psd1"));
  223. }
  224. else if (mode == AzureModule.AzureResourceManager)
  225. {
  226. this.modules.Add(Path.Combine(PackageDirectoryFromCommon, @"ResourceManager\AzureResourceManager\AzureResourceManager.psd1"));
  227. }
  228. else
  229. {
  230. throw new ArgumentException("Unknown command type for testing");
  231. }
  232. this.modules.Add("Assert.ps1");
  233. this.modules.Add("Common.ps1");
  234. this.modules.AddRange(modules);
  235. }
  236. public void SetupModules(params string[] modules)
  237. {
  238. this.modules = new List<string>();
  239. this.modules.Add("Assert.ps1");
  240. this.modules.Add("Common.ps1");
  241. this.modules.AddRange(modules);
  242. }
  243. public virtual Collection<PSObject> RunPowerShellTest(params string[] scripts)
  244. {
  245. using (var powershell = System.Management.Automation.PowerShell.Create(RunspaceMode.NewRunspace))
  246. {
  247. return ExecuteShellTest(powershell, null, scripts);
  248. }
  249. }
  250. public virtual Collection<PSObject> RunPowerShellTest(IEnumerable<string> setupScripts, IEnumerable<string> scripts)
  251. {
  252. using (var powershell = System.Management.Automation.PowerShell.Create(RunspaceMode.NewRunspace))
  253. {
  254. return ExecuteShellTest(powershell, setupScripts, scripts);
  255. }
  256. }
  257. private Collection<PSObject> ExecuteShellTest(
  258. System.Management.Automation.PowerShell powershell,
  259. IEnumerable<string> setupScripts,
  260. IEnumerable<string> scripts)
  261. {
  262. SetupPowerShellModules(powershell, setupScripts);
  263. Collection<PSObject> output = null;
  264. foreach (var script in scripts)
  265. {
  266. if (TracingInterceptor != null)
  267. {
  268. TracingInterceptor.Information(script);
  269. }
  270. powershell.AddScript(script);
  271. }
  272. try
  273. {
  274. powershell.Runspace.Events.Subscribers.Clear();
  275. powershell.Streams.Error.Clear();
  276. output = powershell.Invoke();
  277. if (powershell.Streams.Error.Count > 0)
  278. {
  279. var sb = new StringBuilder();
  280. sb.AppendLine("Test failed due to a non-empty error stream, check the error stream in the test log for more details.");
  281. sb.AppendLine(string.Format("{0} total Errors", powershell.Streams.Error.Count));
  282. foreach (var error in powershell.Streams.Error)
  283. {
  284. sb.AppendLine(error.Exception.ToString());
  285. }
  286. throw new RuntimeException(sb.ToString());
  287. }
  288. return output;
  289. }
  290. catch (Exception psException)
  291. {
  292. powershell.LogPowerShellException(psException, TracingInterceptor);
  293. throw;
  294. }
  295. finally
  296. {
  297. powershell.LogPowerShellResults(output, TracingInterceptor);
  298. powershell.Streams.Error.Clear();
  299. }
  300. }
  301. private void SetupPowerShellModules(System.Management.Automation.PowerShell powershell, IEnumerable<string> setupScripts)
  302. {
  303. powershell.AddScript("$error.clear()");
  304. powershell.AddScript(string.Format("cd \"{0}\"", AppDomain.CurrentDomain.BaseDirectory));
  305. if (setupScripts != null)
  306. {
  307. foreach(var script in setupScripts)
  308. {
  309. powershell.AddScript(script);
  310. }
  311. }
  312. foreach (string moduleName in modules)
  313. {
  314. powershell.AddScript(string.Format("Import-Module \"{0}\"", moduleName.AsAbsoluteLocation()));
  315. }
  316. powershell.AddScript(
  317. string.Format("set-location \"{0}\"", AppDomain.CurrentDomain.BaseDirectory));
  318. powershell.AddScript(string.Format(@"$TestOutputRoot='{0}'", AppDomain.CurrentDomain.BaseDirectory));
  319. powershell.AddScript("$VerbosePreference='Continue'");
  320. powershell.AddScript("$DebugPreference='Continue'");
  321. powershell.AddScript("$ErrorActionPreference='Stop'");
  322. powershell.AddScript("Write-Debug \"AZURE_TEST_MODE = $($env:AZURE_TEST_MODE)\"");
  323. powershell.AddScript("Write-Debug \"TEST_HTTPMOCK_OUTPUT = $($env:TEST_HTTPMOCK_OUTPUT)\"");
  324. }
  325. }
  326. }